I am really stuck on this: (sorry, newbie problems) Following the method exposed in this post I need to render the tags in a page, but I am not able to get the tag values through the @property
The code is as follow, the models:
class TagsBlock(blocks.FieldBlock):
"""
Basic Stream Block that will use the Wagtail tags system.
Stores the tags as simple strings only.
"""
def __init__(self, required=False, help_text=None, **kwargs):
# note - required=False is important if you are adding this tag to an existing streamfield
self.field = forms.CharField(widget=AdminTagWidget, required=False)
super().__init__(**kwargs)
class ServicesPage(Page):
services = StreamField([
('services',blocks.StructBlock([
('entries',PortfolioBlock()),
('tags',TagsBlock(required=False)),
]))], null=True, blank=True)
@property
def get_tags(self):
"""
Helpful property to pull out the tags saved inside the struct value
Important: makes some hard assumptions about the names & structure
Does not get the id of the tag, only the strings as a list
"""
tags_all = [block.value.entries.get('tags', '').split(',') for block in self]
tags = list(chain.from_iterable(tags_all))
return tags
content_panels = Page.content_panels + [
StreamFieldPanel('services'),
]
Then in the template im just doing:
<div class="row-4">
{% for tag in page.services.get_tags %}
{{tag}}
{% endfor %}
</div>
However, I can't get any result. I have really tried everything, but I can't figure how to call the property to give me the list of values.
Thank you very much in advance for your time,
Francisco
In your template, the line
{% for tag in page.services.get_tags %}
would be trying to access a property named get_tags
on the 'services' field of the page. However, get_tags
isn't defined there - it's defined as a property of the page object - so this line should be
{% for tag in page.get_tags %}
Secondly, in the line
tags_all = [block.value.entries.get('tags', '').split(',') for block in self]
you're intending to loop over all the items in the StreamField, but the self
in for block in self
refers to the page object. This should be for block in self.services
.
Finally, in the same line, block.value
will give you the value of each block, which in this case will be a dictionary of two items, entries
and tags
. If you wanted to access entries
(the PortfolioBlock), you would write block.value['entries']
or block.value.get('entries')
rather than block.value.entries
- but really you don't want that, you want to access the tags
item instead - so block.value.entries.get('tags', '').split(',')
should be block.value.get('tags', '').split(',')
.