Как можно визуализировать отдельный подблок StreamField? - PullRequest
1 голос
/ 13 марта 2019

У меня есть загадка, которую, я надеюсь, эксперт по внутренним телам трясогузки поможет мне решить. В конечном итоге я пытаюсь сделать сложную вложенную страницу на основе StreamField в виде обычного текста / HTML, которую можно использовать для индексации поиска и для отображения в виде фрагмента на странице результатов поиска.

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

Решение, которое я придумала, состоит в том, чтобы вручную обходить дерево блоков и отображать только определенные виды блоков в StreamField. Но хотя это было относительно просто для RichTextBlock, поскольку я могу просто извлечь строку 'value' из блока dict, это совсем не просто для любого из наших пользовательских блоков.

Я бы хотел отобразить HTML для отдельного блока, но я действительно не уверен, как это сделать, если такое вообще возможно. После глубокого изучения конвейера рендеринга для StreamField я лучше всего смогу вручную построить BoundBlock с соответствующими данными, а затем вызвать render() для этого. Но я не совсем уверен, как взять необработанный блок-дикт и превратить его в StreamValue для построения BoundBlock. Если это даже правильная идея ...

Я также работаю над обратным решением, в случае, если я просто лаю не на то дерево, здесь. Я подумал, что мог бы передать конкретную переменную контекста в StreamField.render_as_block(context) в функции, которая генерирует индекс поиска, который я могу запрограммировать для поиска отдельных блоков, а затем вообще не отображать себя, если они это видят. Я обновлю этот вопрос, если мне удастся заставить его работать.

1 Ответ

2 голосов
/ 20 марта 2019

Не знаю, правильно ли я понимаю, но вы можете перебирать блоки StreamField.Пример:

Определение блока:

class MyCustomImageBlock(StructBlock):
  image = ImageChooserBlock()
  caption = CharBlock()

  class Meta:
    template = '/blocks/image-with-caption.html'
    icon = 'image'

class MyCarouselBlock(ListBlock):

  class Meta:
    template = '/blocks/custom-list.html'
    icon = 'media'

ImageWithCaptionblock

Определение пользовательского StreamBlock:

class MyCustomStreamBlock(StreamBlock):

  some_image = MyCustomImageBlock()
  image_carousel = MyCarouselBlock(child_block=MyCustomImageBlock)

Определение страницы:

class MyPage(Page):

  content = StreamField(MyCustomStreamBlock())

Шаблон

Теперь вы можете просто визуализировать над блоками StreamField и использовать include_blockвизуализировать отдельные блоки.И вы также можете передавать переменные.

{% for block in page.content %}
  {% include_block block with current_page=page %} # in case you want to render only something when on a certain page
{% endfor %} 

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

{% for block in page.content %}
  <!--
  {% cycle 'right' 'left' as position %}
  {% cycle 'primary' 'secondary' 'white' as color %}
  -->
  {% include_block block with pos=position color=color %}
{% endfor %}
...