Reputation: 23
Hello I'm currently new to django/wagtail. I'm working on an about page that shows previous and current work/positions. I've made the positions streamfield blocks since the amount of experience isn't limited. Here is the code to my models.
#Create experience block
class ExperienceBlockStruct(StructBlock):
position_title = CharBlock(help_text="Enter a previous position title.")
description = CharBlock(help_text="Job description")
current_position = BooleanBlock(required=False, help_text="Check if
current position")
class Meta:
template = 'blocks/experience_block.html'
class ExperienceBlock(StreamBlock):
experience = ExperienceBlockStruct(icon="form")
And here is the page where I use the models
class About(Page):
profile_pic = "some image reduced code bc it currently works"
bio = RichTextField(blank=True)
resume = "some document reduced code bc it currently works"
experience = StreamField(ExperienceBlock())
content_panels = Page.content_panels + [
ImageChooserPanel('profile_pic'),
FieldPanel('bio'),
DocumentChooserPanel('resume'),
StreamFieldPanel('experience'),
]
Now the issue I'm having is how to render the blocks where the current_position = True
in a different area than those that are not.
I've tried
templates/about.html
{% for block in page.experience %}
{% if block.current_position %}
{% include_block block %}
{% endif %}
{% endfor %}
But that doesnt render anything. I've also tried to
<div class="experience">
{% if value.current_position %}
{{ value.position_title }}
{% else %}
{{ value.position_title }}
{% endif %}
</div>
but that creates a new div for every block. What I would like to achieve is something like in blocks/experience_block.html
<div>
Current position(s): {% blocks with current_postion == True %}
</div>
<div>
Past position(s): {% blocks with current_postion == False %}
</div>
How could I go about achieving something like this?
Upvotes: 1
Views: 642
Reputation: 25227
Your first template snippet was almost correct - you just need to check block.value.current_position
rather than block.current_position
:
{% for block in page.experience %}
{% if block.value.current_position %}
{% include_block block %}
{% endif %}
{% endfor %}
This is because looping over page.experience
gives you a series of BoundBlock
objects that tell you the block_type
(always 'experience'
in your case) alongside the block value. See BoundBlocks and values for a more detailed explanation.
You can do the same thing in your experience_block.html template (using {% for block in value %}
rather than {% for block in page.experience %}
) - although note that the Meta
template definition needs to go on ExperienceBlock
rather than ExperienceBlockStruct
, because that's the one that has access to the full list to loop over, rather than a single record.
To make things neater, I'd suggest defining a get_context
method on the block, so that you're doing the data manipulation within Python code rather than inside the template...
class ExperienceBlock(StreamBlock):
experience = ExperienceBlockStruct(icon="form")
def get_context(self, value, parent_context=None):
context = super(ExperienceBlock, self).get_context(value, parent_context=parent_context)
context['current_positions'] = [block for block in value if block.value.current_position]
context['past_positions'] = [block for block in value if not block.value.current_position]
return context
class Meta:
template = 'blocks/experience_block.html'
This will make the variables current_positions
and past_positions
available on the template.
Upvotes: 1