class ButtonBlock(blocks.StructBlock):
      button_page = blocks.PageChooserBlock(required=False)
      button_url = blocks.URLBlock(required=False)

여기 StructBlock에 2개의 Field Block이 있다. 이걸로 a태그로 만들어 관련 페이지로 이동하게 하는 기능을 만들고 싶어한다고 가정해보자. 내부 Link로 이동하고 싶으면 button_page를 외부 링크로 이동하고 싶으면 button_url을 사용한다. (이동하는 url은 한개이기 때문에 Field Block 한개만 사용한다. )

 

 

이럴경우 보통 Template에서

{% if card.button_page %}
  <a href="{{ card.button_page.url }}" class="btn btn-primary">
  	Learn More (internal)
	</a>
{% elif card.button_url %}
  <a href="{{ card.button_url }}" class="btn btn-primary">
  	Learn More (external)
  </a>
{% endif %}

위와 같이 사용한다. 물론 잘못된 것이 아니다. 하지만 2개의 Field Block말고 수많은 Field Block중 한가지만 사용하고 싶을 때에는 아마도 elif가 끊임 없이 늘어나서 Template이 지저분해질 것이다. (신경 안쓰인다면 뒤로가기 버튼을 누르면 된다.)

 

그래서 If Logic을 미리 BackEnd에서 처리하는 방법을 알아보려고 한다.

 

 

class LinkStructValue(blocks.StructValue):
    """Additional logic for our urls."""
    
    def url(self):
        button_page = self.get('button_page')
        button_url = self.get('button_url')
        if button_page:
            return button_page.url
        elif button_url:
            return button_url
        
        return None

방법은 간단하다. StructValue를 상속받은 LinkStructValue를 만들어주었다. (StructBlock이 아니다.) 

그리고 여기서 관련 Logic을 작성해주면 된다.

 

이후 간단하게 ButtonBlock에

class ButtonBlock(blocks.StructBlock):
    """An external or internal URL."""
    
    button_page = blocks.PageChooserBlock(required=False, help_text="If selected, this url will be used first")
    button_url = blocks.URLBlock(required=False, help_text="If added, this url will be used secondarily to the button page")
       
    class Meta:
        template = "streams/button_block.html"
        icon = "placeholder"
        label = "Single Button"
        value_class = LinkStructValue

value_class를 등록해주면 된다. 

자, 이제 이렇게 되면 BackEnd 단계에서 Logic을 처리하고 FrontEnd의 템플릿은 깔끔해질 것이다. 

 

심지어

class LinkStructValue(blocks.StructValue):
    """Additional logic for our urls."""
    
    def url(self):
        button_page = self.get('button_page')
        button_url = self.get('button_url')
        if button_page:
            return button_page.url
        elif button_url:
            return button_url
        
        return None
    
    def latest_posts(self):
        return BlogDetailPage.objects.live().public()[:3]

위와 같이 다른 객체를 가져와서 return해주는 것도 가능하다. 

'Back-End > Wagtail, Django' 카테고리의 다른 글

Wagtail Menu System  (0) 2021.11.23
Wagtail, Django Paginator  (0) 2021.11.21
Wagtail Sitemap  (0) 2021.11.17
Wagtail 참고 사이트  (0) 2021.11.17
Wagtail git ignore setting  (0) 2021.11.16

+ Recent posts