how to perform mathematical operations in django template - html

i want to print the value of current item in list(which is a integer) and its successor(not the list item) but the actual integer successor) at the same time..i am using
{% for i in hour %}{{ i }}-{{i+1}}{% endfor %}
but this gives me an error of "Could not parse the remainder: '+1' from 'i+1'"

Try: {{ i }}-{{ i|add:"1" }}
See https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#add

As far as I know there are three approaches:
Change to a different templating language that allows cleaner logic (Mako I believe though my knowledge is out of date)
Install a third party django package that allows you to do math in templates.
Create a template tag that accepts a value (i), does the calculation you want, and returns that value.
#3 is the one I would suggest.

Related

How do I access a collection field defined in _config.yml?

As outlined in Jekyll's Collections docs, I've added an additional field to my collections. Here's part of my _config.yml:
collections:
algebra1-2:
title: Algebra 1-2
output: true
How can I access the title field in pages and layouts?
I've tried {{ page.collection.title }} (and a dozen other permutations) with no luck. However, I have found that {{ page.collection }} will render algebra1-2.
Edit: I'm not checking whether or not the page belongs to the collection, and also am trying to avoid conditionals and looping over all pages, as this answer recommends.
I found that this is possible using the following syntax: {{ site.collections[1].<field> }}.
So, given the example above, {{ site.collections[1].title }} will evaluate to Algebra 1-2.

How to access `site.data.header["foo.bar.baz"]` if `foo.bar.baz` is a FrontMatter variable

I want something like:
---
my_var: "foo.bar.baz"
---
{{- site.data.header[page.my_var] -}}
Unfortunately, it doesn't work…
I know that I can use site.data.header.foo.bar.bazor site.data.header["foo"]["bar"]["baz"], but it's not that.
Also I know that I can split page.my_var to substrings and use them then as site.data.header["foo"]["bar"]["baz"]. But this increases Jekyll build time.
I guess I need some Ruby plugin, but don't know one and I don't know Ruby to write one.
If you know such plugin or can help me write one or know some native workaround, this would be sooo great!
Help :)
Also I know that I can split page.my_var to substrings and use them then as site.data["foo"]["bar"]["baz"]. But this increases Jekyll build time.
I'm not sure you can do this. And even if you can, I'm not sure that there is a real performance impact.
But you can do this :
_data/foo.yml
bar:
baz: 1
biz: 2
buz: 3
beer:
baz: 1
biz: 2
buz: 3
Then :
---
my_var: "foo.bar.baz"
---
{% assign keys = page.my_var | split: "." %}
{% assign object = site.data %}
{% for key in keys %}
{% assign object = object[key] %}
{% endfor %}
{{ object }}
What are hoping to do has been blocked by design.
site.data["foo.bar.baz"] implies that you need to have a data file named foo.bar.baz.yml or foo.bar.baz.json, ... etc.
But Jekyll sanitizes data files' names and therefore the resulting object would only have a key named "foobarbaz"
A plugin that purposely removes this sanitization can written but it wouldn't appear to be a benign or safe to end-users. So the chances of finding such a plugin in the wild is slim..

Using jinja inside jinja

Here's what I want to do:
{% for disaster in disasters %}
{{disaster.name}}
When I try to open the HTML page I get:
Error during template rendering
With exception value as:
Exception Value:
Reverse for '{{disaster.link}}' not found. '{{disaster.link}}' is not a valid view function or pattern name.
How can I do the same task with or without jinja logic?
Have you tried removing the curly braces around disaster.link? I've only worked with Jinja once, but that stood out to me.

How to adjust Jekyll post order?

I have started a Jekyll based blog with a theme jekyll-now. I am new to Jekyll and how it operates (especially Liquid). I understand that new posts need to be as follows: 2014-10-04-Hello-World.md. But I really don't understand how I could order these.
My first thought is that they order by date so two posts on the same date would order randomly. But is this not the case? Is there a way of ordering posts chronologically. OR at least having a post archive page?
There is an example in the official Jekyll documentation how to create a basic post archive page:
Displaying an index of posts
Bonus: For a prettier archive page (grouped by year or year/month), see this answer.
You're right, I can't find anything in the docs where it says how the posts are ordered, but in fact Jekyll does order them chronologically, with the most recent post first (you can see this if you try the examples I linked above).
To sort them the other way (the oldest post first), you can use the reversed keyword, according to the Liquid documentation:
{% for post in site.posts reversed %}
However, I don't know how two posts on the same date are ordered, because I don't write that much posts, so I never had that problem :-)
You have to try that yourself.
Just faced the same problem and solved with this solution:
https://groups.google.com/forum/#!topic/jekyll-rb/8QCIzevauSU
Add a date field to the YAML Front Matter of a post, like so:
date: 2010-09-15 14:40:45
e.g. if you have 2 posts on 2014/12/31, you can add date: 2014-12-31 00:30:00 to latest_post.md, and date: 2014-12-31 00:10:00 to older_post.md.
You can add time zone (e.g. date: 2014-12-31 00:10:00 +08:00) if needed
I want to document my struggle into this post so it may help other users. You need to do two changes:
Open your posts and add weight. e.g., weight:100
Open your html file for the menu where you want the sorted posts. For Java/J2EE menu I have java.html file at the root path of my project.
Then, add the {% assign pages_list = pages_list | sort:"weight" %} line as shown in the below code. This will sort by weight.
{% for category in site.categories %}
{% if category[0] contains 'java' %}
<h3 id="{{ category[0] }}-ref">{{ category[0] | join: "/" }}</h3>
<ul>
{% assign pages_list = category[1] %}
{% assign pages_list = pages_list | sort:"weight" %}
{% include JB/pages_list %}
</ul>
{% endif %}
{% endfor %}
Jekyll just string-compares post paths when sorting, which is why the date format is year-month-day. Posts are internally also collections and you can see the sorting being invoked in reader.rb:
# Sorts posts, pages, and static files.
def sort_files!
site.collections.each_value { |c| c.docs.sort! }
site.pages.sort_by!(&:name)
site.static_files.sort_by!(&:relative_path)
end
So it's using generic ruby methods to sort and implements the comparator in document.rb:
# Compare this document against another document.
# Comparison is a comparison between the 2 paths of the documents.
#
# Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
# equal or greater than the other doc's path. See String#<=> for more details.
def <=>(other)
return nil unless other.respond_to?(:data)
cmp = data["date"] <=> other.data["date"]
cmp = path <=> other.path if cmp.nil? || cmp.zero?
cmp
end
Which means it first compares the dates and only checks the text if needed.
The date is special only if it somehow wasn't found (no metadata). For drafts it falls back to the file modification time, for the rest to the site time.
So if you want to force a different ordering of posts from the same day, craft the start of the title in the filename to alphabetically sort first. Eg. 2020-01-01-a.md will come after 2020-01-01-b.md if you're listing posts in descending order.

How can I render the ID of a minion that has a particular .sls or state in SaltStack?

I'm using SaltStack to manage some VMs. I'm looking for a way to render the ID/hostname of a minion(s) that have a specified .sls attached to them in the top.sls file or a particular state in a jinja template-enabled file. The reason I want to do this is so I can easily refer to a server(s) in a client's configuration without having to hardcode values anywhere at all. For example;
/srv/salt/top.sls:
base:
'desktoppc01':
- generic.dns
'bind9server01':
- generic.dns
- bind9
/srv/salt/generic/dns/init.sls:
/etc/resolv.conf:
file:
- managed
- source: salt://generic/dns/files/resolv.conf
- mode: 644
- template: jinja
And finally,
/srv/salt/generic/dns/files/resolv.conf:
domain {{ pillar['domain_name'] }}
search {{ pillar['domain_name'] }}
nameserver {{ list_minions_with_state['bind9'] }}
What I'm after specifically is an equivalent to {{ list_minions_with_state['bind9'] }} (which I just made up for demonstrations sake). I had assumed it would be something that would be pretty commonly needed, but after scouring the modules page I haven't found anything yet.
At the moment I have the client get information from a pillar, but this has to be manually configured which doesn't feel like time well spent.
I'm hoping I could expand this idea with a for loop so that servers are dynamically added as they're created.
edit:
With a file with the same data & hierarchy as a top.sls, rendering
base:
{% for server_id in salt['pillar.get']('servers') %}
'{{ server_id }}':
{% for states in salt['pillar.get']('servers:{{ server_id }}') %}
- {{ states }}
{% endfor %}
{% endfor %}
gives you
base:
'desktoppc01':
'bind9server01':
I tried a few variations on {{ server_id }} but was unsuccessful. Unless there's an easy way to use pillar variables in that function, I'm thinking of making a feature request and calling it a day.
The way I think around this problem is to use jinja and have a variable that contain the list of dns server... populated by a pillar variable
for instance you could have a pillar:bind:servers variable
see http://docs.saltstack.com/en/latest/topics/tutorials/states_pt3.html
and http://docs.saltstack.com/en/latest/topics/pillar/index.html#master-config-in-pillar
that can be used to both setup the nameserver of resolv.conf.. but also to add the - bind9 state to the servers.
so in the end you have just one place to edit: the list of minion that are bind server in pillar
The first thing that comes to mind would be using the test-state methodology by setting test=True for state.apply or state.highstate. If there were zero states to apply then your server would have your highstate or specific sls fully applied.
salt '*' state.highstate test=True
Using salt-run's survey.diff could be helpful (although the diff patch doesn't lend itself well to this scenario as much as examining config files):
salt-run survey.diff '*' state.apply my.state test=True
While not currently applicable to your question based on your examples another method that comes to mind would be to use salt grains within your states. When you have your states applied to the systems the state would append to the "states" grain. Grains track things like roles (eg. web, database, etc.) in your case grains could track states as more of a what was applied, instead of a what should be logic of roles. Then you can use them to target and/or query your servers.
Targeting by Grain (show only minion id's) :
salt -G 'states:bind9' test.ping
salt -G 'states:generic.dns' test.ping
salt -G 'states:my_jinja_state' test.ping
Querying Grains (for each minion show me the states grain):
salt '*' grains.get states
Diffing of Grains (compare each minions states grain):
salt-run survey.diff '*' grains.get states