Типы и части созданные через дашборд

Topics: Customizing Orchard, Русский (Russian)
Oct 16, 2012 at 10:41 AM

Доброго дня!
Типы и части можно создать как в коде, так и из дашборда.

Каким образом я могу получить доступ к созданному из дашборда типу из кода своего модуля?

Допустим, у меня есть часть созданная в модуле, скажем это AddresPart. И допустим есть часть представляющая компанию клиента, созданная из дашборда - CustomerPart.
И я хочу сделать возможность в CustomerPart иметь коллекцию адресов AddresPart.

В этой статье, рассказано, как сделать такую привязку для двух типов созданных из кода, а как сделать это в описанном мной случае? 

Для начала не понятно, если один из типов создан в дашборде, как сделать модель для связывания, которая в статье показана в виде

public class ContentRewardProgramsRecord {
public virtual int Id { get; set; }
public virtual RewardsPartRecord RewardsPartRecord { get; set; }
public virtual RewardProgramRecord RewardProgramRecord { get; set; }



Oct 17, 2012 at 1:59 PM

Из элемента контента можно вытащить часть таким образом: ContentItem.As<Part>

Oct 17, 2012 at 9:19 PM

Подскажите полное имя упомянутого класса Part , пожалуйста.

Oct 18, 2012 at 12:43 PM

Part - это часть, класс наследованный от ContentPart<[Record]>. В примере по ссылке это AddresPart : ContentPart<AddressPartRecord>.

Если Запись (Record) без части (Part) то работать с ней можно с помощью IRepository<Record>. На худой конец использовать NHibernate.

Oct 18, 2012 at 4:30 PM

Боюсь, я не верно объяснил: проблема добраться до типа созданного из дашборда, в данном случае - CustomerPart, в котором я собираюсь создать коллекцию  AddressPartRecord.


Oct 19, 2012 at 9:54 AM

Так, если я правильно понимаю, вы хотите создать экземпляр (item) типа контента (ContentType) программно.

У вас скорее всего есть Customer ContentType, состоящий из CustomerPart. Но должен еще содержать список адресов, как описано здесь (http://skywalkersoftwaredevelopment.net/blog/writing-an-orchard-webshop-module-from-scratch-part-8).  AddressPart не связан с CustomerPart напрямую, у него есть просто ссылка на него. Так что, получить список адресов можно по CustomerId.

Второй вариант, если типы адресов известны и не будут изменятся, их можно прикрепить к Customer ContentType с соответствующими именами.

Третий вариант, использовать Container/Containable, Taxonomy или другой ContentPart, который будет содержать список AddresPart.

Oct 22, 2012 at 7:52 PM

Спасибо, буду разбираться :)

Nov 12, 2012 at 7:55 PM

Итак, я разобрался в должной мере, что бы задать ещё вопрос по теме использования частей созданных через дашборд:

Итак, я редактирую представление, говоря конкретней это к примеру 
~/Themes/TheThemeMachine/Views/Taxonomies.TermContentItems.List.cshtml

Стоит задача: добавить списку группировку по полю taxonomy и сортировку по стандартной контентной части Title

Методом "в лоб" я получил заголовок и вероятно так же получу taxonomy, но меня гнетёт подозрение, что существует более гуманный синтаксис для доступа к полям и частям. Как правильно обратиться?
Текущий вариант:

@using Orchard.ContentManagement
@{
IEnumerable<dynamic> contentItems = Model.ContentItems;
var sorted = contentItems.OrderBy(it => it.Header.Items[0].Title);
Model.ContentItems.Classes.Add("content-items");
Model.ContentItems.Classes.Add("term-content-items");
}
@foreach (var item in sorted)
{
@Display(item); 
}
@if (contentItems == null || contentItems.Count() < 1) {
<p>@T("There is no content associated to this term.")</p>
}

 


 

 

Nov 12, 2012 at 11:14 PM

А чем текущий вариант не нравится?

Clay со своими Behaviour дает возможность доступа к полям и свойствам частей через точку без явного приведения к определенному типу. Собственно, из за этого it.Header.Items[0].Title и работает.

Nov 13, 2012 at 4:52 PM

Не нравится тем, что не даёт однозначности и не похоже что бы был изначально таким задуман.

Ну т.е. если в Header по каким  то причинам окажется несколько элементов, и мой заголовок будет не первым то сортировка пойдёт по неверному алгоритму.

Ну Бог с ним с заголовком впрочем, а поле taxonomie? Его по последовательности задавать совсем не стоит - количество и порядок полей впоследствии могут измениться.

Логично было бы предположить в столь ядрёной системе синтаксис типа  item.Title.Value

Ну или хоть item.GetPartValue("TitlePart") или item.GetFieldValue("TermsPart")

Меня подмывает реализовать такой метод расширением, но не будет ли это велосипедом?

Nov 13, 2012 at 7:57 PM

GetPartValue обозначает, что значение части может быть только одно, но в массе случаев это не совсем так...

Fields тоже привязаны не к типу контента а к части (part). Другими словами Type<-Part<-Field.

Вообще не знаю насколько в этом есть смысл, давольно много модулей и идей, на первый взгляд интересных и логичных, не приняты управляющим комитетом.

Так что, лично для себя я использую Orchard исключительно для решения проблем, а если появляется код, который я использую снова и снова, делаю из него модуль и выкладываю в галлерею.

Nov 18, 2012 at 9:40 AM
Edited Nov 18, 2012 at 9:45 AM

Итак, что я нашёл в ответ на некоторые свои вопросы в этой теме. Пишу для таких же неудачников, которым мало имеющейся документации.

Сперва третий, не сформулированный вопрос "как получить доступ к полю из известного нам Part , в т.ч. если Part или поле созданы из dashboard".
Ответ такой:

Model.ContentItem.{Part or Type name}.{Field name}
т.е. если мы добавили в тип пользователя поля для ФИО то, фамилию, для которой мы сделали строковое поле LastName, мы будем демонстрировать в представлении так

@Model.ContentItem.User.LastName.Value

Второй вопрос "Как добавить списку группировку по полю taxonomy и сортировку по стандартной контентной части Title"

В условие задачи добавляем, что тип называется TradeItemType, а поле Taxonomy называется Category и для него установлен выбор только одного элемента, в противном случае конечно несколько по другому будет реализовано, но не принципиально. 

С неустановленным taxonomy не проверял, у меня такой вариант невозможен, но наверное не будет проблем.

@using Contrib.Taxonomies.Models
@using Contrib.Taxonomies.Fields
@using Orchard.ContentManagement
@using Orchard.DisplayManagement.Shapes
@{
Enumerable<dynamic> contentItems = Model.ContentItems; var grouped = contentItems. GroupBy(it=> (((IEnumerable<TermPart>)it.ContentItem.TradeItemType.Category.Terms.Value).FirstOrDefault()??new TermPart()).Name ); } @foreach (var grp in grouped) { <hr/>@grp.Key<hr/> foreach (var item in grp.OrderBy(it => it.ContentItem.TitlePart.Title)) { @Display(item); } }

На первый вопрос, о хранении списка адресов для клиента, у меня пока только теоретический ответ, как реализую, то вероятно тоже добавлю сюда.

Nov 21, 2012 at 8:38 AM

Спасибо. Понятно и доходчиво, я так не умею :)

Nov 21, 2012 at 4:25 PM

:)