2017-10-13 24 views
0

有沒有比這更好的方法來製作固定內容的ListBlock的子類?如何用固定內容定義ListBlock的子類?

class MixedMediaCarouselBlock(blocks.ListBlock): 
    """ 
    A hghly streamlined CarouselBlock which displays only Images and/or Videos. 
    """ 

    def __init__(self, child_block=None, **kwargs): 
     child_block = blocks.StructBlock([ 
      ('image', ImageChooserBlock(required=False)), 
      ('video', EmbedBlock(
       label="Video URL", 
       help_text="Paste the video URL from YouTube or Vimeo." 
          " e.g. https://www.youtube.com/watch?v=l3Pz_xQZVDg" 
          " or https://vimeo.com/207076450.", 
       required=False 
       ) 
      ), 
     ]) 
     super(MixedMediaCarouselBlock, self).__init__(child_block, **kwargs) 

    class Meta: 
     template = 'core/blocks/mixed_media_carousel_block.html' 
     label = 'Mixed Media Carousel' 
     icon = 'media' 

感覺真的哈克這樣做,但我無法找到任何其他明顯的方法,因爲ListBlock要求child_block參數的構造函數,而其他類型的塊沒有。

的原因我想有一個ListBlock子是我的一個網頁使用它作爲單塊類型的StreamField

class News(Page) 
    assets = StreamField(
     MixedMediaCarouselBlock(), 
     help_text='Pick one or more images/videos to place in the sidebar of this article.' 
    ) 

也許我只是在做這錯了嗎?

編輯:是的,我肯定做錯了什麼。這根本不起作用,正如我剛剛發現的,當我嘗試使用此設置保存一個頁面時,在wagtail/wagtailcore/blocks/stream_block.py行401上獲得AttributeError: 'MixedMediaCarouselBlock' object has no attribute 'child_blocks'。(Wagtail 1.12.2)。不知道爲什麼。

EDIT2:我跟着@ gasman的建議,以及與此想出了:

class MixedMediaCarouselBlock(blocks.StreamBlock): 
    slides = blocks.ListBlock(
     blocks.StructBlock([ 
      ('image', ImageChooserBlock(required=False)), 
      ('video', EmbedBlock(
       label="Video URL", 
       help_text="Paste the video URL from YouTube or Vimeo." 
          " e.g. https://www.youtube.com/watch?v=l3Pz_xQZVDg or https://vimeo.com/207076450.", 
       required=False 
       ) 
      ), 
     ]) 
    ) 

但我仍然得到頁編輯表單塊類型菜單(我使用的鶺鴒改款):

Block Type Menu

更糟糕的是,表格讓我的slides到StreamField,這很容易導致用戶不小心讓多個單元素ListBlocks,而不是一個多元素ListBlock,這將增加BR多個實例擠兌渲染器。我能做些什麼呢?編輯3:這是我經過多次實驗後想出來的,但我根本不喜歡它。

class MixedMediaCarouselBlock(blocks.StructBlock): 
    """ 
    A hghly streamlined CarouselBlock which displays only Images and/or Videos. 
    """ 

    slides = blocks.ListBlock(
     blocks.StructBlock([ 
      ('image', ImageChooserBlock(required=False)), 
      ('video', EmbedBlock(
       label="Video URL", 
       help_text="Paste the video URL from YouTube or Vimeo." 
          " e.g. https://www.youtube.com/watch?v=l3Pz_xQZVDg or https://vimeo.com/207076450.", 
       required=False 
       ) 
      ), 
     ]) 
    ) 

    class Meta: 
     template = 'core/blocks/mixed_media_carousel_block.html' 
     label = 'Mixed Media Carousel' 
     icon = 'media' 

class News(Page): 
    ... 
    assets = StreamField(
     ('media', MixedMediaCarouselBlock()), 
     help_text='Pick one or more images/videos to place in the sidebar of this article.' 
    ) 

然後,處理的用戶提供一個單一MixedMediaCarouselBlock內意外增加多個MixedMediaCarouselBlock s,而不是多個視頻/圖像的問題,我砍死了一些不太CSS來隱藏,將讓他們做到這一點的UI:

body.model-news { 
    .stream-menu .toggle { 
    display: none; 
    } 

    .sequence-controls:not(.list-controls) button[id$=delete] { 
    display: none; 
    } 
} 

在我的[R & d,我整個鶺鴒1.12補丁說明,其中提到了另外min_nummax_num,並block_counts元ATTRS到StreamBlock,這聽起來真的有前途的跑了。但是它們不會影響UI;他們只是添加服務器端驗證,使無效選擇在POSTing後顯示爲表單錯誤。如果他們首先防止了無效變更,我可以真正使用它們。

回答

1

就我所見,您的塊定義是正確的。 ListBlock並沒有被設計爲子類,所以試圖這樣做不可避免地會變得有點冒失,並且不能保證在Wagtail發行版中保持穩定 - 但是你並不依賴於ListBlock的任何內部,只是改變了構造函數的方法簽名,所以它應該足夠安全。請記住,如果您劃分StructBlock,StreamBlock或ChoiceBlock以外的任何塊,則子類的引用將顯示在遷移文件中,因此,只要存在這些遷移,就有責任保持類定義:請參閱http://docs.wagtail.io/en/v1.12.2/topics/streamfield.html#streamfield-definitions-within-migrations

這裏的問題是,StreamBlock(和子類)是當前唯一允許作爲StreamField的頂層塊的塊類型:允許其他塊類型(#2048),但尚未實現。作爲解決方法,您可以將MixedMediaCarouselBlock定義爲僅具有一個子塊類型的StreamBlock;這並不像聽起來那麼笨,因爲在這種情況下,跳過選擇塊類型的菜單(#1696),這使得行爲或多或少與ListBlock相同。

+0

感謝您的解釋!雖然我不太明白你所描述的行爲。也許我設計了我更新的'MixedMediaCarouselBlock'錯誤?我已經將它添加到了原始問題中,並且仍然存在問題。 – CoreDumpError

+0

使用StreamBlock的想法是,您將使StructBlock成爲它的唯一的子節點,並省略ListBlock層。我必須重新熟悉獨生子StreamBlocks是如何工作的,然後 - 我想這可能是菜單顯示爲初始空白狀態,但不是隨後單擊「添加」按鈕時顯示。 – gasman

+0

那麼,這將工作......但「添加塊」的UI比「添加另一個'ListBlock'元素」的UI明顯不那麼漂亮。但是,這可能是最好的解決方案,因爲「ListBlock」不能用作頂級塊。 如果你願意,看看我的「EDIT3」。我找到了一種方法來完成這項工作,但這足以證明我可以使用您的解決方案。 – CoreDumpError

相關問題