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

#templates #view #plone #dexterity

#шаблоны #Вид #plone #ловкость

Вопрос:

Я думаю, это должно быть просто. У меня есть элемент содержимого folderish TTW dexterity (выпадающее окно), который содержит элементы folderish TTW dexterity (предложения). Каждое предложение содержит обзоры ловкости TTW, в которых есть поля, которые я хочу обобщить.

Я могу легко создать представление, которое генерирует таблицу, как указано ниже, для любого предложения, с помощью простых изменений в представлении списка папок:

 [review1 link]   [criterion_1 value] [criterion-2 value]... 
[review2 link]  [criterion_1 value] [criterion-2 value]... 
.
.
  

Я также могу создать представление рабочей таблицы для раскрывающегося списка, изменив представление списка папок:

 [proposal1 link] [column I would like to insert the above table in for this proposal]
[proposal2 link] [column I would like to insert the above table in for this proposal]
.
.
  

Моя проблема в том, что я не могу понять, как вставить первую таблицу в ячейки во втором столбце второй таблицы. Я попробовал две вещи:

  1. В шаблоне представления для списка dropbox я попытался дублировать макрос repeat макроса listingmacro, присвоив ему и всем его переменным новые имена, чтобы он повторялся для каждого предложения. Это позволяет легко получить доступ ко всем схемам дублинского ядра для каждого обзора, но я не могу получить доступ к полям ловкости. Все, что я пробовал (то, что работает при создании первой таблицы), выдает предупреждения LocationError и AttributeError. Каким-то образом, когда я спускаюсь на один уровень, я теряю часть информации, необходимой для просмотра шаблона, чтобы найти все. Есть предложения?
  2. Я также попытался получить доступ к макросу списка для предложения с помощью вызовов типа <metal use-macro="item/first_table_template_name/listing"/> . Является ли это хотя бы частично правильным подходом? Он не выдает ошибок, но также ничего не вставляет на мою страницу.

Спасибо.

Комментарии:

1. Взгляните на список полного представления Plone: github.com/plone/Products . CMFPlone/ blob / … и github.com/plone/Products . CMFPlone/ blob / …

2. Спасибо… кажется, это ставит меня на правильный путь и позволяет мне использовать вариант 2, который намного чище для отладки. Я опубликую окончательное решение с подробностями, как только выясню странности.

Ответ №1:

Это решение свободно основано на примерах, предоставленных kuel: https://github.com/plone/Products .CMFPlone/blob/854be6e30d1905a7bb0f20c66fbc1ba1f628eb1b/Products/CMFPlone/skins/plone_content/folder_full_view. пт и https://github.com/plone/Products .CMFPlone/blob/b94584e2b1231c44aa34dc2beb1ed9b0c9b9e5da/Products/CMFPlone/skins/plone_content/folder_full_view_item.pt . — Спасибо вам.

Способ, которым я нашел самый простой для создания и отладки, был:

  1. Создайте минималистичный шаблон из стандартного шаблона plone folder_listing.pt это всего лишь таблица обобщенных данных обзора для одного предложения. Шаблон предназначен только для таблицы, без информации о заголовке или каких-либо других слотов. Это урезанная версия, но над первым утверждением ничего нет. Ключевое утверждение, разрешающее доступ к полям, имело вид:

    python: item.GetObject().restrictedTraverse(‘criterion_1’)

Шаблон таблицы:

     <table class="review_summary listing">
        <tbody><tr class="column_labels"><th>Review</th><th>Scholarly Merit</th><th>Benefits to Student</th><th>Clarity</th><th>Sum</th></tr>
    <metal:listingmacro define-macro="listing">
    <tal:foldercontents define="contentFilter contentFilter|request/contentFilter|nothing;
                          contentFilter python:contentFilter and dict(contentFilter) or {};

            I kept all the standard definitions from the original template.
            I have just removed them for brevity.

                        plone_view context/@@plone;">

    The following tal:sum is where I did some math on my data.  If you are
    not manipulating the data this would not be needed.  Note that I am only
    looking at the first character of the choice field.

         <tal:sum define="c1_list python:[int(temp.getObject().restrictedTraverse('criterion_1')[0]) 
                              for temp in batch if temp.portal_type=='ug_small_grants_review'];
                          c1_length python: test(len(c1_list)<1,-1,len(c1_list));
                          c2_list python:[int(temp.getObject().restrictedTraverse('criterion_2')[0]) 
                              for temp in batch if temp.portal_type=='ug_small_grants_review'];
                          c2_length python: test(len(c2_list)<1,-1,len(c2_list));
                          c1_avg python: round(float(sum(c1_list))/c1_length,2);
                          c2_avg python: round(float(sum(c2_list))/c2_length,2);
                          avg_sum python: c1_avg c2_avg;
                           ">
    <tal:listing condition="batch">

        <dl metal:define-slot="entries">
            <tal:entry tal:repeat="item batch" metal:define-macro="entries">
            <tal:block tal:define="item_url item/getURL|item/absolute_url;
                                   item_id item/getId|item/id;

                 Again, this is the standard define from the folder_listing.pt
                 but I've left out most of it to save space here.

                                   item_samedate python: (item_end - item_start amp;< 1) if item_type == 'Event' else False;">
                <metal:block define-slot="entry"

                       The following condition is key if you can have things
                       other than reviews within a proposal.  Make sure the
                       item_type is proper for your review/item.

                        tal:condition="python: item_type=='ug_small_grants_review'">
                <tr class="review_entry"><td class="entry_info">
                <dt metal:define-macro="listitem"
                    tal:attributes="class python:test(item_type == 'Event', 'vevent', '')">
              I kept all the standard stuff from folder_listing.pt here.

                </dt>

                <dd tal:condition="item_description">

                </dd>
                </td>

           The following tal:comp block is used to calculate values 
           across the rows because we do not know the index of the 
           item the way the batch is iterated.

               <tal:comp define = "crit_1 python: item.getObject().restrictedTraverse('criterion_1')[0];
                                   crit_2 python: item.getObject().restrictedTraverse('criterion_2')[0];
                                   ">

               <td tal:content="structure crit_1"># here</td>
               <td tal:content="structure crit_2"># here</td>
               <td tal:content="structure python: int(crit_1) int(crit_2)"># here</td>
                 </tal:comp> 
               </tr>
             </metal:block>
            </tal:block>
            </tal:entry>
        </dl>
        <tr>
            <th>Average</th>
            <td tal:content="structure c1_avg"># here</td>
            <td tal:content="structure c2_avg"># here</td>
            <td tal:content="structure avg_sum"># here</td>
        </tr>
    </tal:listing>
    </tal:sum>

    <metal:empty metal:define-slot="no_items_in_listing">
        <p class="discreet"
           tal:condition="not: folderContents"
           i18n:translate="description_no_items_in_folder">
            There are currently no items in this folder.
        </p>
    </metal:empty>

    </tal:foldercontents>
    </metal:listingmacro>
</tbody></table>
  
  1. Создайте другой шаблон листинга, который вызывает этот шаблон для заполнения соответствующей ячейки таблицы. Опять же, я использовал модификацию folder_listing.pt . В основном в блоке повтора я помещаю следующее утверждение во второй столбец таблицы:

    Это относится сразу после тега </dd>, заканчивающего обычный список элементов.

    </td> <td class=»review_summary»>
    <div tal:replace=»structure python:item.GetObject().ug_small_grant_review_summary_table()» />
    </td>

Обратите внимание, что «ug_small_grant_review_summary_table» — это имя, которое я дал шаблону, показанному более подробно выше.