Still learning django and python...
I have a form with many fields. I want to lay them out in rows of two fields each, and am using a table to do so. I can't simply iterate over all the fields as I want finer control on certain things.
Essentially, I am putting out a row of two fields, and then if there are errors in any of those fields, generate a second row containing the errors.
In the template, I am repeating the following pattern over and over again:
<tr>
<td class="labels">Order Number:</td><td class="textentry">{{ order.ordernum }}</td>
<td class="labels">Order Status:</td><td class="textentry">{{ order.status }} </td>
</tr>
{% if order.ordernum.errors %}
{% for error in order.ordernum.errors %}
<tr class="errors"><td colspan=2> {{ error|escape }}</td>
{% endfor %}
{% if order.status.errors %}
{% for error in order.status.errors %}
<td colspan=2> {{ error|escape }}</td>
{% endfor %}
{% endif %}
</tr>
{% endif %}
where all that changes from repeated pattern to repeated pattern are the specific field names.
The repetition makes me wonder: is there a better way to do this in the template? Is there some way to call a function from within the template where I could just pass in the field names?
Thanks for your help!
W.
For anyone interested, I don't know if there's a better solution, but template macros a la djangosnippets.org/snippets/363 is how I solved this problem.
Related
I am just getting into some liquid template coding on a Shopify site. How do I use the for-loop index/variable when defining variable names in assign or capture tags? ie: I'm trying to condense the code to create multiple link menus from sequentially numbered settings, where [i] would be a number between 2 and 4 in the settings key.
What is the proper syntax to insert that number into
a) a tag like an if statement or assign.
b) interpolated text like in the h3 element below.
c) a nested/bracketed key statement (sorry if that's not what its called, i'm still learning), like in the second for statement.
{% for i in (2..4) %}
{% if settings.footer_quicklinks_enable[i] %}
<div class="grid-item medium--one-half large--three-twelfths">
<h3>{{ 'layout.footer.quick_links{{i}}' | t }}</h3>
<ul>
{% for link in linklists[settings.footer_quicklinks_linklist[i]].links %}
<li>{{ link.title }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% endfor %}
You need to use the square bracket notation instead of dot notation.
Create a string containing the variable name (with assign or capture), then use square bracket notation to access the setting with that name.
For example:
{% capture var %}footer_quicklinks_enable_{{i}}{% endcapture %}
{% if settings[var] %}
Also see this similar answer.
With reference to this question:Jekyll/Liquid Templating: How to group blog posts by year?
I have implemented the answer by Christian Specht which in my case returns a list of goal scorers from a csv file stored in my _data folder and it works perfectly.
However, how do I then return these in order of highest-lowest?
At the minute, the goalscorers are just returned in the order they appear in the csv file.
My code:
<h2>Top goal scorers</h2>
<table>
{% assign goalscorers = site.data.members | sort: 'sortby' %}
{% for goalscorer in goalscorers %}
{% if goalscorer.goals > "0" %}<tr><td>
{{ goalscorer.surname }} </td><td>{{ goalscorer.goals }}</td></tr>
{% endif %}
{% endfor %}
</table>
The resulting html:
<h2>Top goal scorers</h2>
<table>
<tr><td>Moore </td><td>2</td></tr>
<tr><td>Cromwell </td><td>1</td></tr>
<tr><td>Gould </td><td>3</td></tr>
<tr><td>Dowsett </td><td>6</td></tr>
<tr><td>Whalley </td><td>2</td></tr>
<tr><td>Tindall </td><td>1</td></tr>
<tr><td>Jones </td><td>1</td></tr>
</table>
OK I've done it, I needed to change the assign line to:
{% assign goalscorers = site.data.members | sort: 'goals' | reverse %}
I would like to populate the same section of a Jinja2 for loop with data from 2 separate SQL queries using Python / Webapp2 / Jinja2.
Specifically, I am storing team info in a variable called "team" and score info in a variable called "wins". I need to position some data from the wins variable directly after data from the team variable but cannot figure out how to do this within a for loop.
Here is a simplified version of what I am trying to achieve:
{% block content %}
{% for team in team %}
<div>{{ team[0] }} record: {{ wins[1] }}</div>
<div>{{ team[1] }} and {{ team[2] }}</div>
<div>{{ team[3] }}</div>
{% endfor %}
{% endblock %}
What is the best way to do this? I need to get that "wins" variable called but cannot determine how. Any help is appreciated.
I usually zip them up into a list of tuples in the view function. Make sure the teams and wins are sorted correctly beforehand.
team_info = zip(teams, wins)
And then you can access the tuples as you iterate over the list in the template
{% block content %}
{% for team, win in team_info %}
<div>{{ team[0] }} record: {{ wins[1] }}</div>
<div>{{ team[1] }} and {{ team[2] }}</div>
<div>{{ team[3] }}</div>
{% endfor %}
Is there a way I can have a single Jekyll website have more than one blog? I currently want to have two blogs in one site.
I am the author of the page http://www.garron.me/blog/multi-blog-site-jekyll.html
Considering that you need individual archives pages, and latest post per individual blog. Just use something like this:
Create a file archives-blog-1.html and fill it with:
{% for post in site.posts %}
{% if post.categories contains 'blog1' %}
<div class="post">
<h3 class="title">{{ post.title }}</h3>
<p class="meta">Date: {{ post.date }}</p>
</div>
{% endif %}
{% endfor %}
That will give you a list of all post in blog1, you can do the same for blog2. That page can be anyplace you want.
For the latest post, you can use the same code but enclosed between:
{% for post in site.posts limit:5 %}
....
{% endfor %}
That will give you the lastes 5 posts... I am using this
{% for post in site.posts limit:5 %}
<div class="post">
<ul>
<li>{{ post.title | truncate:200 }} <small>{{ post.date }}</small>
{% if post.summary %}
<p class="entry">{{ post.summary }}</p>
{% endif %}
</li>
</ul>
</div>
{% endfor %}
In my index page. http://www.garron.me/index.html ... under the sub-title (From the blogs)
I am not limiting to any category, so posts from all blogs appear there, you can limit with {% if post.categories contains 'blog1' %}
Hope it helps you.
There's a simpler solution than any of the answers so far.
Folder structure:
- blog1/
- _posts/
- blog2/
- _posts/
Then in the index.html for blog1, use site.categories.blog1 instead of site.posts.
See the documentation for "site.categories" and "page.categories" in https://jekyllrb.com/docs/variables/
I used two separate Jekyll installations to run two blogs on the same domain; if your blogs are going to live in separate root dirs (mine are at / and /photos/), then I'd recommend this approach. I also described how I merged both blogs' sitemap.xml files.
Your best bet would be to look into the data files feature. You can put .markdown files in a separate folder in your source and link to them as you post. This does mean that in order to make a post, you'll need to write a data file entry, but you can host as many "blogs" as you'd like, each with their own folder. Posts will automatically have the folder they're in as the url. I use this method for my own personal blog and portfolio.
Either that, or you may want to look into collections: http://jekyllrb.com/docs/collections/
Adding to #ggarron's answer, there's a short version of filtering by categories:
{% assign filtered_posts = site.posts | where_exp: "post", "post.categories contains 'blog1'" %}
The advantage of assigning to a variable is that one can replace all uses of site.posts with filtered_posts and keep consistency. For example, I have a snippet to get the first post of the list:
{% assign first_post = filtered_posts | first %}
This works as expected.
I use Twig and I want to make the following content translatable :
{% trans %}
You have actually <span class='messageNumber'>{{messageNumber}} message(s)</span> in your mailbox.
{% endtrans %}
But when this translatable content will be parsed by POEdit and sent to translators, they will see the <span> tags and attributes. What can I do to avoid this ?
I thought about doing this way :
{% messageNumberFormatted = "<span class='messageNumber'>"~messageNumber~"message(s)</span>" %}
{% trans %}
You have actually {{messageNumberFormatted}} in your mailbox.
{% endtrans %}
But isn't it a bit heavy or even bad practice for the translators ? In that case, they can't even see the word "message".
First, you should use transchoice with explicit interval pluralization, like this :
{% transchoice message_count %}
{0}You have {{no messages}} yet|{1}You have {{one message}}|]1,+Inf]You have {{%count% messages}}.
{% endtranschoice %}
Then maybe you could use replace to replace {{ with the opening tag, and }} with the closing tag. I don't know whether you can directly chain like this
{% transchoice message_count | replace('...') %}
Or if you must store in a variable by using set first.
You can use the trans twig filer with keys representing your sentences.
{{ you.have.actually|trans }} <span class='messageNumber'> {{ messageNumber message|trans }} </span> {{ in.your.mailbox|trans }}