Counting items in Django templates - html

Is it possible to tally items being listed as part of the django template within the html?
For example, I have a django template with the following code snippet in it:
<div>
{% for thing in thing_list %}
{% if thing.status == "n" %}
<a>{{ thing.status.count }}</a>
{% endif %}
{% endfor %}
</div>
This django template displays all of the things in a list, and I can call each attribute of the thing and display it, so I know I have access to all of the fields.
I want to count then number of "things" and display that number as text. My current attempt above isn't working. Does anyone have any suggestions?

As Willem says, you should do this in the view. Rather than passing a list of all Things and then checking their status in the template with if, you should filter your Things when querying them from the database in the first place:
thing_list = Thing.objects.filter(status='n')
Then you can do just {{ thing_list.count }} in the template.

Related

How to pass variables in a paramter of an html component with django

I'm today working on a django porject composed of only one application (an encyclopedia), but I am facing some struggles.
I have a view named index that is displaying all the encyclopedias that the user can access to. On each file, I want to add a link to can redirect the user to the concerned encyclopedia.
To do that, in my index view, I am calling a function that lists all the encyclopedias that we can have access to. This list will be used for rendering an html page.
The problem that I am facing is on this html page named index.html. I am trying to pass the name of each encyclopedia in the href parameter for my link. Here is my html code:
{% extends "encyclopedia/layout.html" %}
{% block title %}
Encyclopedia
{% endblock %}
{% block body %}
<h1>All Pages</h1>
<ul>
{% for entry in entries %}
<li>{{ entry }}</li>
{% endfor %}
</ul>
{% endblock %}
P.S: my django project is based on a base code provided by : https://cs50.harvard.edu/web/2020/projects/1/wiki/
In your urls.py file, put this code in:
path("<str:entry>/", views.display_entry, name="display_entry")
The <str:> determines the variable type and the text after that is the name of the variable. You can do something like this in the view:
def display_entry(request, entry):
Note that the name in the urls.py and the view should be the same.
It was finally that I had to remove the slash. It is working with this code :
<li><a href ={{entry}}>{{ entry }}</a></li>
Thank you #AryanJassl for helping.

Trying to get a collection from a Front Matter value

Hi I'm new to Jekyll and have a basic blog set up. Now my idea is to loop through a collection per blog post to get some fancy HTML going on. Because as far as I'm aware you can't simply add HTML to the markdown.
// config.yml
collections:
- hollowknight
So I've set up a collection named hollowknight and I got a blog post about Hollow Knight.
In the Front Matter of the blog post I have collectionid: 'hollowknight'. And in the Layout I use for blog posts I tried the following:
// post.html
{% capture collection %}site.{{ page.collectionid }}{% endcapture %}
{% for section in collection %}
{{ section.title }}
{% endfor %}
So the idea was to set the collection variable to site.hollowknight as configured in the config and the Front Matter. I set up a single article inside the collection, but it isn't showing up.
Is there any way to realise this?
Edit: https://talk.jekyllrb.com/t/list-collection-with-name-from-front-matter/3619/6
Or is there a way to use paragraphs in the Front Matter, because then I could just use arrays and objects in the Front Matter of the posts to do my magic?
Edit: https://github.com/jekyll/jekyll/issues/246#issuecomment-1639375
Or am I just stretching to far from what Jekyll is supposed to be?
Edit
So I found out I was getting the collection the wrong way, https://talk.jekyllrb.com/t/list-collection-with-name-from-front-matter/3619/6.
{% for section in site.[page.collectionid] %}
{{ section.content | textilize }}
{% endfor %}
The only weird part is, everywhere I see | textilize being used but can't get it to work.
This is the final solutions:
{% for section in site.[page.collectionid] %}
{{ section.content | markdownify }}
{% endfor %}
It's markdownify instead of textilize.
Also I ended up using a Front Matter array with objects to loop through instead of a collection to keep it more organized.

Random access contents of Jekyll collection

I'm using a Jekyll collection to generate a reveal.js presentation. Each file in the collection represents one slide and are named sequentially, eg 01.md, 02.md, etc. This all works fine but I want to find a more flexible method to order slides.
If I can randomly access the files in the collection, rather than sequentially iterate through them, I could maintain the order of slides external to the collection - something like: [0,1,3,2,4].
Where the collection is defined as:
collections:
reality:
title: Reality Slide Deck
output: false
I can get the content of item 3 of the collection with:
{{site.reality[3].content}}
How do I access the front matter?
Thanks in advance.
Any front matter's variable is available under is own name.
{{site.reality[3].title}}
or
{{site.reality[3].variableName}}
You can loop through the content of your site using site.collection as is explained in the documentation at https://jekyllrb.com/docs/collections/#documents
To access only one collection you can use a conditional statement.
{% for info in site.collections %}
<ul>
<li>{{ info }}</li>
<li>The name of the collection: {{ info.label }}</li>
{% for stuff in info.docs %}
<li>{{ stuff.title }}</li>
{% endfor %}
</ul>
{% endfor %}
After saying all of this you can of course just loop through the one collection as below:
{% for real in site.reality %}
<li>{{ real.title }}</li>
{% endfor %}
The only other method that may work it to create an array using liquid syntax
{{ "a~b" | split:"~" }} #=> ['a','b']
Not sure if this answers your question, I hope it's useful for someone.

Listing related records in Bolt CMS

I have content types Topics and Pamphlets. Pamphlets are related to topics (e.g. a pamphlet called 'Mass in B minor' could be related to the topic 'music') using 'relations' field-type:
pamphlet:
...
relations:
topics:
multiple: false
...
What I want is to list all the Music pamphlets. More exactly, I want to be able to display each topic, with a list of pamphlets related to that topic.
There's a function record.related() but it works the other way, that is, I can use it when I display a pamphlet to show that the pamphlet is related to Music; but I can't use it when I display the Music topic to list all the pamphlets that are related to music.
(The documentation says that relations are always bi-directional, but I can't see how.)
Suggestions welcomed.
I was simply wrong when I said that the related records() function didn't do the job. Here we are (nicked from the out-of-the-box record.twig template):
{% set relatedrecords = record.related() %}
{% if relatedrecords is not empty %}
<p> Examples:</p>
<ul>
{% for related in relatedrecords %}
<li><a href="{{ related.link }}">
{{ related.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
In general, it seems, if A (a pamphlet) is related to B (a topic), exactly the same method can be used to show either the topic to which a given pamphlet belongs, or the pamphlets belonging to a given topic.
Apologies for getting this wrong, and congrats to the Bolt developers for a neat bit of work.
I now have an inefficient solution. Maybe someone can improve it.
To display all the pamphlets related to a given topic, I created a template topic.twig. Within that template, record.title contains the name of the topic (eg 'Music') and record.id contains the ID of the topic. We need to select pamphlets that are marked as related to a topic with that ID. The following code fetches all the pamphlets into pamphletlist then considers each one. Using the valuable dump() function, I found that the data structure for a pamphlet includes an array relation which includes an array topics. The code below works because in my data, one pamphlet can only be related to one topic. Code:
{# to get a list of all pamphlets related to this topic #}
{% setcontent pamphletlist = 'pamphlets' %}
{% for p in pamphletlist %}
{{ dump(p) }}
{% for t in p.relation.topics %}
{% if record.id == t %}
<p> {{ p.title }} </p>
{% endif %}
{% endfor %}
{% endfor %}
It would surely be more efficient to use a where clause, something like this:
{% setcontent pamphletlist = 'pamphlets' where { relation.topics: ... } %}
That would presumably get the election done at the database level, instead of peeking at each record in turn. But my experiments only produced twig syntax errors. Does anyone have a more efficient method?
Have you looked at the Related Content by Tags extension?
This gives you a list of related content by tags:
http://extensions.bolt.cm/view/45073af0-8585-4d5b-b978-fd6405858e0e

Jekyll: Is there anyway to output all posts and collection types in a single for loop ordered by date?

I have two collections defined for tutorials and articles within my Jekyll blog. I need to be able to display all the different collection types alongside posts and have them ordered by date. Is there anyway to do this?
Thank you.
That can be done with some liquid code. By looping first over all collections one can capture the collection labels and use these to access all documents in all collections in a second for-loop.
{% for collection in site.collections %}
{% capture label %}{{ collection | first }}{% endcapture %}
<h3>All documents listed in collection '{{ label}}'</h3>
{% for doc in site.collections.[label].docs %}
<li>
<span>{{ doc.date | date_to_string }}</span>
{{ doc.title }}
</li>
{% endfor %}
{% endfor %}
This lists dates and titles of all documents per collection in chronological order. However, if one want all documents sorted in one list things get nasty. I hope, something similar to the code above is what you are looking for.