Display part of the content data - django

I have the following template code:
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ article.title }}</h3>
</div>
<div class="panel-body">
{{ article.content }} <!--will display the full text-->
</div>
I intend to show the first 200 characters of the content, like:
{{ article.content|length=200 }}
How to achieve such a constrain on the text.

There are two template filters here that are useful: slice and truncatechars.
slice limits an iterable (here a string) to a given number, for example:
{{ variable | slice:":200" }}
whereas truncatechars does approximately the same, except that in case the string is longer than the upper bound (here 200), it will slice to the upperbound minus three, and add an ellise:
{{ variable | truncatechars:"200" }}
For a smaller upperbound, to demonstrate the difference, for a string variable = "foobarqux" we would get:
{{ variable | slice:":6" }} # foobar
{{ variable | truncatechars:"6" }} # foo...
The two thus differ: the latter gives a textual hint that there is actually more content. Of course it depends on the specific situation which filter suits your needs.
A nice thing is that you can emulate truncatechars in terms of slice:
{{ variable | truncatechars:":6" }}
is equivalent to:
{% if variable|length > 6 %}{{ variable|slice:":3" }}...{% else %}{{ variable }}{% endif %}
But it is of course not the most elegant solution: in case you want truncatechars behavior, it is better to use the specific filter.

You can use truncatechars filter:
{{ article.content|truncatechars:200 }}

Related

Django include template as variable to use in default

I'd like to include a default template as a variable to pass it into a default case, like below:
<div class="row max-h-200 overflow-hidden">
{% include 'blog/userprofile_deleted.html' as deleted_profile %}
{{ user.profile.bio | safe | default:deleted_profile }}
</div>
Is this possible in django 3.2.9 ?
Currently I have to write out the default text as html in a single line:
<div class="row max-h-200 overflow-hidden">
{{ user.profile.bio | safe | default:'<h4> Very long html string! </h4> <span>Comment as <b>you</b> with your own profile!</span><span>Create your Account at the bottom of the page,or by visiting <code>/register</code> !</span>' }}
</div>

Replace function inside value not working

Maybe I'm doing it wrong (tried several ways to achieve my goal) or overlooking something here.
What I'd like to achieve is this:
When I use the Live-search function, I get categories containing the search keyword (like: Paint -> Paint buckets, Paint brushes, Paint colors etc.) which works like a charm. The one thing I need is to style the searched keyword in the presented categories like:
Paint bucket,
Paint brushes,
Color paint
This is the code I have at the moment:
{% if (products.length + categories.length + pages.length) == 0 %}
<div id="Pi56dYpB" class="undefined"> No results for:
<b>{{ query }}</b>...
</div>
{% endif %}
{% if categories.length > 0 %}
<div class="categories">
{% for category in categories %}
{% if loop.index < 7 %}
<a class="p-0" href="{{ category.url }}" style="all:inherit;">
<h3 id="bvwiyjEN" class="undefined">{{ category.name|replace({{ query }}: "<strong>"{{ query }}"<strong>"})|raw }}</h3>
</a>
{% endif %}
{% endfor %}
{% endif %}
Unfortunately this isn't working. I did check if the {{ query }} value is accessible with this simple line of code:
<h3 id="bvwiyjEN" class="undefined">{{ category.name }} - {{ query }}</h3>
No problems found here.
Did I use the wrong syntax in my code maybe? Any help would be appreciated!
replace({{ query }}) is the wrong syntax - replace(query) should work, as you don't want to echo the variable query here
As Nico Haase pointed out already, {{ ... }} is used to output variables, this translate to something like <?php echo $foo; ?> and can't/shouldn't be used inside statements
Furthermore, the filter replace expects an array of keys to replace with the values.
You would need to change your code to the following:
{% for category in categories %}
{{ category|replace({ (query): '<strong>'~query~'</strong>',})|raw }}
{% endfor %}
demo
Some notes:
The filter replace uses the PHP function strtr in the background. This mean the output will be case-sensitive. If you don't want this, I'd advice you to follow through here
Wrapping the key with parantheses is mandatory. This will force twig to evaluate/interpolate the value of the key - demo

Display singular and plural headers on appropriate context

I'd like to display the plural accordingly in template
{% if page.paginator.count <= 1 %}
<h3 style="display: inline">{{ page.paginator.count }} Comment</h3>
{% else %}
<h3 style="display: inline">{{ page.paginator.count }} Comments</h3>
{% endif %}
Since it's a everyday task,I wonder if it could be achieved in a straightforward way such as template-filer?
Django provides such a function for that. Its name is pluralize
Returns a plural suffix if the value is not 1. By default, this suffix is s.
<h3 style="display: inline"> Comment{{page.paginator.count|pluralize}}</h3>
For words that don’t pluralize by simple suffix, you can specify both a singular and plural suffix, separated by a comma.
countr{{ total|pluralize:"y,ies" }}.

html/template if range index clause

I've got this template that parses multiple items of a slice onto the page. It does that really well.
However, I now want to use the very same template to parse a single value of the slice, based on the range index. The slice is used in multiple files so I can't just .Execute it like Slice[1:2]
{{ $bpi := .Index}}
{{ range $i, $elmt := .Slice }}
{{ if $bpi.Equals $i }}
<div>{{ .SliceContent }}</div>
{{ end }}
{{ end }}
From what I've read is that the template isn't ment for computation, but if you've got a range index and if-statements in the html/template package it seems to me that I must be doing something wrong. I can write a FuncMap ofcourse, no problemo. But it doesn't seem right to me given these facts.
I am using something like this to conditionally include a default image or the first from a supplied slice of pictures. So I think this will provide you with the basis to do what you want. I check the slice has values, pulling the Nth item using the {{index .Slice n}} syntax as follows:
{{ $idx := 2}}
{{if .Pictures}}
<img src="{{if .Pictures}}{{index .Pictures $idx}}{{end}}" alt="supplied first picture">
{{else}}
<img src="http://fpoimg.com/200x200?text=Placeholder(FPOimg.com)" alt="default picture">
{{end}}
Therefore you can do the following:
{{ $bpi := .Index}}
{{ if .Slice }}
{{ index .Slice $bpi }}
{{ end }}

django slice numbers in template

Is there a way to get multiple digits of a given number within a django template?
For example:
{{ some_num|get_digit:2 }}
will give you the second right most digit. For 1224531 it would be 3
Is there a way to get the last 3 digits or the first 5 digits? Like python's slicing?
something like:
{{ some_num|get_digits:2,5}}
There is a the "slice" template tag
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#slice
It uses the same syntax as Python's list slicing.
Example:
{{ some_list|slice:":2" }}
in python this is equivalent to:
some_list[:2]
BTW your 2nd example would be "2:5" not "2,5"
NB. Python slicing works on any 'sequence'. Strings and lists are sequences. Numbers are not!
any extra filter that converts the number into a string before slicing will work. I used these variants:
{{ some_num|slugify|slice:"2:5" }}
and
{{ some_num|stringformat:"d"|slice:"5:10" }}
{{1234567|make_list|slice:'2:5'|join:''}}
Stefano's answer is on the right track. You need a pre-processing step to turn your number into a list, and a post-processing step to merge that list back into string.
You just need to write code as follow for slicing :-
{{valueformoney|slice:"0:4"}}
{% for cloth in valueformoney|slice:"0:4" %}
<div class="product h-100 w-100 border rounded ">
<div class="img__container">
<img src="{{cloth.cloth_image.url}}" alt="" />
</div>
<div class="product__bottom">
<div class="price">
<span class="text-danger"> <del>{% min_price cloth as result %} {{ result|rupee}}</del></span>
<span>{% discount_price cloth as result %}{{result|rupee}}</span>
<span class="float-right badge p-3 badge-info">Save {{cloth.cloth_discount}}% </span>
</div>
<h3 class="p-4">{{cloth.cloth_name}}</h3>
<div class="button">
See More
</div>
</div>
</div>
{% endfor %}