2017-10-13 8 views
0

고정 콘텐츠가 포함 된 ListBlock의 하위 클래스를 만드는 데 더 좋은 방법이 있습니까? ListBlock이 생성자 child_block 인수, 다른 블록 유형을하지 않는 동안 것을 필요로하기 때문에,고정 된 내용으로 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 서브 클래스 내 페이지 중 하나에 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 line 401에 AttributeError: 'MixedMediaCarouselBlock' object has no attribute 'child_blocks'이 생겼을 때 발견되었습니다. (Wagtail 1.12.2) 이것은 전혀 작동하지 않습니다. 이유는 모르겠지만.

EDIT2 : 나는 가스업자의 조언 @ 다음에,이 함께했다 :

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

여전히 더 나쁜 양식은 나를 BR 것이다 쉽게 하나가 아닌 다중 요소 ListBlock의 사용자가 실수로 여러 개의 단일 요소 ListBlocks을 만들기로 이어질 수있는 StreamField,에 slides의 여러 인스턴스를 추가 할 수 있습니다 렌더러를 잡아라. 이것에 대해 내가 뭘 할 수 있니?

EDIT3 : 이것은 많은 실험을 거쳐 내가 생각해 낸 것이지만, 전혀 좋아하지 않습니다.

:

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의 추가의 문제를 처리하기 위해, 나는 그들이 그렇게 할 것이다 UI를 숨길 일부 LESS CSS를 해킹 내 R & D 동안

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

    .sequence-controls:not(.list-controls) button[id$=delete] { 
    display: none; 
    } 
} 
, 정말 유망한 소리 StreamBlockmin_num, max_numblock_counts 메타 바인드합니다,의 추가를 언급 할미새 1.12 패치 노트를 가로 질러 달렸다. 그러나 그들은 UI에 영향을 미치지 않습니다. 그들은 잘못된 선택을 게시 후 폼 오류로 표시하는 서버 측 유효성 검사를 추가하기 만합니다. 무효 변경이 처음부터 이루어진 것을 막은 경우 실제로 사용할 수 있습니다.

답변

1

내가 알 수있는 한, 블록 정의가 정확합니다. ListBlock은 하위 클래스로 설계되지 않았으므로 그렇게하기 위해 노력하는 것은 필연적으로 약간의 해키 일뿐 Wagtail 릴리스에서 안정적이지는 않을 것입니다. 그러나 ListBlock의 내부 구조에 의존하지 않고 생성자를 변경하는 것입니다. 메서드 서명이므로 충분히 안전해야합니다. StructBlock, StreamBlock 또는 ChoiceBlock 이외의 블록을 서브 클래 싱하는 경우 하위 클래스에 대한 참조가 마이그레이션 파일에 표시되므로 해당 마이 그 레이션이 존재하는 한 클래스 정의를 유지하는 것은 사용자의 책임입니다. http://docs.wagtail.io/en/v1.12.2/topics/streamfield.html#streamfield-definitions-within-migrations을 참조하십시오.

현재 StreamBield (및 하위 클래스)는 StreamField의 최상위 블록으로 허용되는 유일한 블록 유형입니다. 다른 블록 유형 허용 (#2048)이 아직 구현되지 않았습니다. 이 문제를 해결하기 위해 MixedMediaCarouselBlock을 하나의 자식 블록 유형 만있는 StreamBlock으로 정의 할 수 있습니다. 이 상황에서는 블록 유형을 선택하기위한 메뉴가 건너 뜁니다 (#1696). ListBlock과 거의 비슷하게 동작합니다.

+0

설명해 주셔서 감사합니다. 비록 당신이 묘사 한 행동을 잘 이해하지 못하고 있습니다. 아마도 내가 업데이트 한'MixedMediaCarouselBlock'을 잘못 설계 한 것입니까? 나는 원래의 질문에 그것을 추가했고, 나는 아직도 가지고있는 문제를 가지고있다. – CoreDumpError

+0

StreamBlock을 사용하는 아이디어는 StructBlock을 하나의 자식으로 만들고 ListBlock 레이어를 제거하는 것입니다. 싱글 아이 스트림 StreamBlock이 어떻게 작동하는지 다시 숙지해야 할 것입니다. 메뉴가 초기 빈 상태로 표시 될 수도 있지만 이후에 '추가'버튼을 클릭 할 때가 아닐 수도 있습니다. – gasman

+0

글쎄, 그게 효과가있다 ...하지만 "add block"UI는 "다른 ListBlock 요소를 추가하기"UI보다 상당히 적다. 그러나 최상위 블록으로 사용할 수없는'ListBlock'의 경우에도 이것이 최상의 해결책 일 수 있습니다. 원한다면 "EDIT3"을 확인하십시오. 이 작업을 수행 할 수있는 방법을 찾았지만 해커가 충분히있어서 솔루션을 대신 사용할 수 있습니다. – CoreDumpError