Django: using Images in Hyperlinks - html

im pretty new to Django (as in no Knowledge so far) and a project requires me to include a Image inside of a hyperlink.
just including the inside of the hyperlinks created the error message
'blocktrans' doesn't allow other block tags (seen "static 'pretix_app/Instagram.png'") inside it
my code so far is
li ><img src="{% static 'pretix_app/YouTube.png' %}" alt="Youtube_icon" style="alignment: left;vertical-align:middle; width: 20px; padding-right: 5px" >
{% with 'target="blank" href="https://www.youtube.com"'|safe as a_attr %}
{% blocktrans trimmed %} <a {{ a_attr }}> Social Media-target {% endblocktrans %}
{% endwith %}</li>
This produces a working hyperlink, but does not include the image (which is required as a social media hyperlink)
The "safe as attr"-method was copied from a working template included in the source code.
Does anybody know if it is possible to include Images in Hyperlinks, and if yes, how?
Thanks in advance for any help

Hello Corinari and welcome to StackOverflow.
As the Django log says, the blocktrans (should be blocktranslate since Django 3.1 ref) may not contain other tags, which in this case is the {% static 'pretix_app/YouTube.png' %} part. We need to remove that part.
One possible way is to use the as statement. You could have the static tag outside your blocktrans block and pass through a variable, like this:
{% static 'pretix_app/YouTube.png' as yt_icon %}
{% blocktrans %}
<li>
<img src="{{ yt_icon }}" alt="Youtube_icon" style="alignment: left;vertical-align:middle; width: 20px; padding-right: 5px"/>
...
</li>
{% endblocktrans %}
This will fix your current error. There are, however several further notes I have. First is the probable typo pretix_app in the static path. The other, much more important, as Abdul says in his comment, you will reach another error with the second blocktrans block. As far as I know from what you have posted here you should not need the second blocktrans nested within the first one. You will be able to translate the whole thing as one.

Related

liquid variables stop working when layout is defined

Big thanks to anyone who looks at this! I think the question is straightforward. It is only long because I wanted to be very thorough/ well-documented. I have taken the following example code from the jekyll documentation and edited it only so that I can find it with a permalink:
---
food: Pizza
permalink: "/pizza"
---
<h1>{{ page.food }}</h1>
When I run jekyll serve, the variable is outputted as it should be, but it has no layout. When I try to add a layout that I wrote to the page, the variable no longer outputs, as seen here.
Ultimately, I want to write an archive page that loops through categories, exactly like this code in the documentation:
{% for category in site.categories %}
<h3>{{ category[0] }}</h3>
<ul>
{% for post in category[1] %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
{% endfor %}
But, because the liquid variables are not working, I cannot make the archive without either putting in in the _layouts directory or manually copy-pasting my layout to the archive page.
Sorry if I'm coming across as a jekyll newbie (I am) or if the answer is in the docs somewhere and I could not find it, but here are my questions:
Why is this behavior happening? Is it something about how jekyll works or is it my layout that is causing this?
What would be the best practice for writing the archive/ correcting this error?
The github repository for this entire project is here
It looks like you are using the wrong liquid tag for trying to get the content. When injecting the page content, use {{ content }} not {{ page.content }}. You can see an example in the docs.
Looking at your includes for post_body.html and body.html, you just need to fix the above and it should work.

Jekyll templates/snippits/shortcuts

I've been playing around with Jekyll for a couple of days, I've got a working site, but on many pages I want to use templates/snippits/shortcuts to make it easy to re-use commonly-typed content.
In MediaWiki, this is what I would have done;
This is a test {{ iconSmileFace }}
Where {{ iconSmileFace }} obviously translates to something like <img src = "resources/images/smile.png" />
I've seen that Jekyll has includes, so I could do {{% include iconSmileFace.html %}} but this syntax seems kinda verbose, and maybe not quite the Jekyll-way of doing things. Is there another better way?
I would create a snippet to hold all of my icons whether they are images or svgs or font icons:
{% case include.icon %}
{% when 'smiley-face' %}
Smiley face
{% when 'heart' %}
Heart
{% when 'close' %}
X
{% when 'next' %}
>
{% endcase %}
Then include it where you need it {% include icon.html icon="smiley-face" %}
A good idea would be to define a liquid tag.
Create the _plugins directory and a file called smile.rb with this content:
module Jekyll
class RenderSmileTag < Liquid::Tag
def render(context)
'<img src = "resources/images/smile.png" />'
end
end
end
Liquid::Template.register_tag('smile', Jekyll::RenderSmileTag)
Then every time you want to render the image just use: {% smile %} and it will generate <img src="resources/images/smile.png" />
If your intent is to output image tags with the shortcut, there's another way with a GitHub Pages supported plugin:
(Though I haven't tested this myself)
From the plugin jemoji's documentation, you can serve custom emojis by pointing to a custom source in your _config.yml:
emoji
src: "/resources/images"
Then reference the emoji in your markdown document:
It's a beautiful day! :smile:

Modifying the name of a variable within asset_path for use as an image

I am extremely new to Jekyll/Ruby/Liquid and I would like to create a for loop to display an image for every different tag that I have. However I can't seem to get it to work. I think the problem is nesting the name of each tag inside asset_path and then modifying the name. It keeps throwing the error that I have not properly terminated the variable.
For example, if one of my tags was 'cloud', I would like the 'cloud_logo.png' image to be displayed from my asset directory. I am using the jekyll-assets plugin and am running it all locally through terminal.
{% for tag in site.tags %}
<img src="{% asset_path {{ tag | first }}_logo.png %}"></img>
{% endfor %}
I would be very grateful if anyone could help me with this, thanks in advance!
Thanks so much for your answer JootS! It helped me a lot, you were missing something though, for some reason {{ asset_path }} wasn't getting recognised, but when I replaced it with /assets/ it was a temporary hotfix as my html file is in the root directory. So the solution was:
{% for tag in site.tags %}
<img src="/assets/{{ tag | first }}_logo.png" />
{% endfor %}
This is correct liquid:
{% for tag in site.tags %}
<img src="{{ asset_path }}{{ tag | first }}_logo.png" />
{% endfor %}
Note that you should set your 'asset_path' in your '_config.yml' file like this (for future reference):
asset_path: '/assets/'
Happy Jekylling!

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.

Menu navigation with Django

I have the view:
def about(request):
return render(request, 'about.html', {'page_about_exist':1,})
In html I have this code:
<li {% if page_about_exist %} class="active" {% endif %}> About</li>
So, If I go to the About-page, in menu it has class active, and I can see it visually.
Is there any other way without the dictionary? Because I have in url
url(r'^accounts/login/$', 'django.contrib.auth.views.login', name='login',),
and my way with dictionary doesnt look great there. Thanks.
You should do this kind of thing with template inheritance. For example, your base.html might include a navigation list with:
<li{% block products %}{% endblock %}><a href...>Products</a></li>
<li{% block about %}{% endblock %}><a href...>About</a></li>
Then in your about template (assuming it inherits from base) you have:
{% block about %} class="active"{% endblock %}
This will render as pure html, using the class you have defined for active pages. Because it uses simple template inheritance you can also get really fine control with this.
I use my own template tag called ifnav.
http://pypi.python.org/pypi/django-ifnav-templatetag
https://bitbucket.org/bikeshedder/django-ifnav-templatetag
The usage is very simple. Just add it to your INSTALLED_APPS and make sure the request context processor is activated.
Afterwards you can write this:
<li {% ifnav "^/about/" %} class="active" {% endifnav %}> About</li>
For current projects I use Django CMS which takes care of rendering the navigation.