html in django page to limit length of text - html

I am building a tool in django. It allows myself, and others, to make entries (imagine a journal) for various 'topics'. When the topic is clicked a page opens ('topic' page) that shows the entries. I am trying to limit the length of that text to 200 characters such that if someone wants to see the whole entry, they need to click on that entry to open it up to its specific page.
I have tried putting a maxlength="200" in a few different places. But nothing worked. The only thing I did that kind of worked was to create a 'textarea' with a maxlength="200" but that was visually odd and unappealing. I know there has to be some way to limit the length in the existing code, without creating a new area and putting the entry in there.
Below is the code for the 'topic.html' page. I am thinking that should be enough. If you need the views.py or models.py, let me know.
{% extends "AARs/base.html" %}
{% block header %}
<h2>{{ topic }}</h2>
{% endblock header %}
{% block content %}
<p>
Add new action
</p>
{% for action in actions %}
<div class="panel panel-default">
<div class="panel-heading">
<small>
{{ action.date_added|date:'M d, Y H:i' }}
</small>
<small> Read or Edit Action</small>
</div>
<div class="panel-body">
<small>
<input type="text" name="action" maxlength="10">
{{ action.text|linebreaks }}
</small>
</div>
</div>
{% empty %}
No actions have been added yet.
{% endfor %}
{% endblock content %}

You might be looking for the truncation filters in Django's template language:
truncatechars
truncatechars_html
truncatewords
truncatewords_html
As an example, quoting from the docs:
{{ value|truncatewords:2 }}
If value is "Joel is a slug", the output will be "Joel is …".

Related

How to check if an objects attribute is given?

I am trying to make a little website with django when I ran into a problem:
I have a site where I want to look at a post in detail, but not every post has an image attribute - so I am getting an error when I try to display images, since some arent existent.
So the solution would be to check if an image is given, but... How do I do that?
I tried something like this but it did not work:
</div>
<p>{{ object.content }}</p>
{% if object.image.url == True %} <!-- In no case an image is displayed -->
<p>
<img src="{{ object.image.url }}">
</p>
{% endif %}
</div>
You should check the truthiness object.image attribute, not its URL, so:
{% if object.image %}
<p><img src="{{ object.image.url }}"></p>
{% endif %}

what is ? in pagination hyper links

Hi im reading a book about django and in pagination template i see a ? but i do not know why is it there.I searched but got no answer.
Here is the template :
<div class="pagination">
<span class="step-links">
{% if page.has_previous %}
Previous
{% endif %}
<span class="current">
Page {{ page.number }} of {{ page.paginator.num_pages }}.
</span>
{% if page.has_next %}
Next
{% endif %}
</span>
</div>
what is the question mark in the address of page in ???
The ? basically represents a query parameter in the URL.
In many cases, the beginning of the query string is marked with a question mark and the various parameters that make up the query string are separated with an ampersand, but other syntaxes are also possible.
domain.com?parameter1=value1&parameter2=value2&parameter3=value3

How to set excerpt of a post in Jekyll?

Instead of using auto-generated excerpt, I'm trying to set a custom excerpt in post's YAML frontmatter.
---
layout: post
title: My Post
excerpt: My custom excerpt
---
But this custom excerpt doesn't get picked up in my post list page. My index.html template looks like this
<div class="home">
<div class="posts">
{% for post in paginator.posts %}
<div class="post py3">
<p class="post-meta">{{ post.date | date: site.date_format }}</p>
<h3 class="h1 post-title">{{ post.title }}</h3>
<p class="post-summary"> {{ post.excerpt }} </p>
</div>
{% endfor %}
</div>
{% include pagination.html %}
</div>
I'm using jekyll#3.7.2 and have jekyll-pagination plugin enabled. It should be pretty straight-forward, but I just cannot figure out what's going wrong. Am I missing anything?
Update
Actually I've made a very dumb mistake that I'm editing the wrong files. And setting excerpt actually does work.
post.excerpt is assigned by Jekyll, so, you cannot reassign it.
You can change the name of your variable to myexcerpt.
I get the same problem, and I figure out it was because of the length of the custom excerpt. If I reduce it to some amount of words, it worked. Otherwise, I will get a empty string.

Combining posts with different layouts on one page in jekyll/liquid

I'm trying to create a jekyll page with all of my posts listed sequentially. The problem is that some posts use different layouts, which are then specified in the post frontmatter. I've disabled individual page output for the posts (actually a custom category), so the layouts are partials.
For example, say I have some red posts and green posts:
_posts/01_post1.md:
---
layout: redpost
---
Post 1 (red)
_posts/02_post2.md:
---
layout: greenpost
---
Post 2 (green)
I want these to get processed using the correct layout. I also would prefer to use inheritance, which I think precludes the use of {%include%}.
_layouts/post.html:
<article class="post">
{{ content }}
</article>
_layouts/redpost.html:
---
layout: post
---
<div style="color:red">
{{ content }}
</div>
Then in my top-level page I want to loop over all the posts, render them using the appropriate template, and concatenate the result. Obviously no RENDER filter exists, although perhaps I was just unable to find it's name in the documentation.
_layouts/index.html:
<html>
...
{% for post in site.posts %}
{{ post | RENDER }}
{% endfor %}
</html>
The desired final HTML would then look like:
<html>
<article class="post">
<div style="color:red">
<p>Post 1 (red)</p>
</div>
</article>
<article class="post">
<div style="color:green">
<p>Post 2 (green)</p>
</div>
</article>
</html>
Is this possible without plugins?
The solution was trivial, which is why it isn't mentioned in the documentation. A document object gets rendered with the correct template just by being printed directly:
{% for post in site.posts %}
{{ post }}
{% endfor %}
What is wrong with the following? Seems like a solution to me.
_layouts/index.html:
<html>
...
{% for post in site.posts %}
{% include post.html %}
{% endfor %}
</html>
_includes/post.html:
<article class="post">
{% if post.layout == 'greenpost' %}
{% include greenpost.html %}
{% endif %}
</article>
_includes/greenpost.html:
<div style="color:green">
{{ post.content }}
</div>

Jekyll and modular/atomic design

I am currently looking at developing a "static" website, few pages only. However, by design, I can tell there is going to be repetitive layouts/patterns. I am thinking doing a data-oriented approach, with my HTMLs being as reusable as possible. Here is an example:
index.html:
<div>
{% include organisms/topBanner.html
tp-title=site.data.home.topbanner.title
tp-select-blurb=site.data.home.topbanner.select.blurb
button-text=site.data.generic.buttons.getstarted
button-link=site.data.generic.links.gosomewhere
%}
</div>
then my organisms/topBanner.html:
<div class="tb">
<h1>
{{ include.tp-title }}
</h1>
<div>
<h2>{{ include.tp-select-blurb }}</h2>
<div>
{% include atoms/button.html
%}
</div>
</div>
</div>
finally my atoms/button.html:
<a class="button" href="{{ include.button-link }}">{{ include.button-text }}</a>
I have multiple JSON file under _data that basically hold the texts. An example for the button would be a _data/generic/buttons.json:
{
"getstarted": "GET STARTED",
"completesurvey": "COMPLETE THE SURVEY"
}
or links.json:
{
"gosomewhere": "/go-somwhere",
"surveypage": "/survey"
}
So this means you need to pass all your data from the top level include of the organism so every bits in it would have its data. That way the example of that button is that the HTML is defined only once and the data is bound to it. And for a second button to be in the topBanner you could do something like this:
index.html:
<div>
{% include organisms/topBanner.html
tp-title=site.data.home.topbanner.title
tp-select-blurb=site.data.home.topbanner.select.blurb
b-getstarted-text=site.data.generic.buttons.getstarted
b-getstarted-link=site.data.generic.links.gosomewhere
b-survey-text=site.data.generic.buttons.completesurvey
b-survey-link=site.data.generic.links.surveypage
%}
</div>
and in the topBanner.html, you rebind the data to the dedicated button:
<div class="tb">
<h1>
{{ include.tp-title }}
</h1>
<div>
<h2>{{ include.tp-select-blurb }}</h2>
<div id="getstarted">
{% include atoms/button.html
button-text=include.b-getstarted-text
button-link=include.b-getstarted-link
%}
</div>
<div id="survey">
{% include atoms/button.html
button-text=include.b-survey-text
button-link=include.b-survey-link
%}
</div>
</div>
</div>
This approach means everything is data driven, there is no repetition/'copy/paste' of HTML, it all works through includes and you can apply atomic design pattern (http://patternlab.io/).
Wanna change the text of the button from 'GET STARTED' to 'LET'S START'? Go to the data/generic/buttons.json and change it there. The whole website now has the text changed.
The drawback is the fact that all the data has to trickle down from top level. Readability might be bad.
First use of Jekyll for me, and waned to have your opinion on this. What is good practice for static website dev like this? Is it easier to have a buttonGetStarted.html that includes a more generic button.html, and pass the data to button.html from buttonGetStarted.html? Like:
buttonGetStarted.html:
{% include atoms/button.html
button.text=site.data.generic.buttons.getstarted
button.text=site.data.generic.links.gosomewhere
%}
and then include buttonGetStarted every time I need it on the page? But then if I need a new button for the survey, I need to create another html buttonSurvey.html and so on... Sure on the code you see an {% include buttonSurvey.html %} which is easy to read and understandable straight away what this button is about. So this:
{% include button.html button.text=site.data.generic.buttons.getstarted %}
with only one file button for all the buttons, or
{% include buttonGetStarted.html %}
with creation of a new HTML file everytime I need a new button?
Thanks
F.
Disclaimer : As this question is primarily opinion-based (see SO help on this), I've voted to close it.
However, I can give my two cents. Quote are from Atomic Design Methodology.
Atom
[...] elements that can’t be broken down any further without ceasing to be functional
atom/buttons.html
<a class="button" href="{{ include.datas.button-link }}">
{{ include.dats.button-text }}
</a>
Molecule
[...] molecules are relatively simple groups of UI elements functioning together as a unit.
Here the question is : "do we need datas from organism / page for our molecule to work ?"
Yes : Datas will be passed by the parent organism. molecule/buttonGetStarded.html looks like (Note : this molecule is Homonuclear, but is functionnal.)
{% include button.html datas=include.buttonDatas %}
No : Datas will be set from inside the molecule (imaginary data structure)
{% include button.html datas=site.data.buttonDatas.getStarted %}
So in your case, I think that organism/topBanner.html can be composed like this (simplified for readability) :
{{ include.tp-title }}
<h2>{{ include.tp-select-blurb }}</h2>
<div id="getstarted"> {% include molecules/buttonGetStarted.html %}</div>
<div id="survey"> {% include molecules/buttonSurvey.html %}</div>
As I guess that your data files can be used for Internationalization (I18n) purpose. The molecule language doesn't need to be passed all the way down. It can be guessed by the molecule itself.
{% if page.language == nil %}
// if no language variable in page's front matter
// we default to site language set in _config.yml
{% assign language = site.language %}
{% else %}
// language variable present in front matter
{% assign language = page.language %}
{% endif %}
// get datas depending on guessed language
{% assign datas = site.data[language] %}
// this can even be more atomic with
{% assign datas = site.data[language]['buttonSurvey'] %}
// include the atom with correct language datas
{% include atom/button.html datas=datas %}
Note that this logic can even be factorized.