Not sure how I can end the else statement here - html

I am trying to add some logic to a link so that I can have a toggle between states
In the HTML I am using some nunjucks to set the content for the link in the page template. This works:
prototypeLinks = [{href: 'thispage?from=indexpage', text: 'Reset the list of options'} if data['from'] == 'contentpage'] %}
But when I try to add an else if to create the toggle, it doesn't work:
prototypeLinks = [{href: 'thispage?from=indexpage', text: 'Reset the list of options'} if data['from'] == 'contentpage'] else { href: 'thispage?from=indexpage', text: 'Reduce the options' } endif %}
When I run it I get:
[Line 5, Column 131] expected block end in set statement
It feels like there is a way to add the expected block end.

Related

Jekyll Collection Filter

I'm trying to grab a specific item from a collection called 'content' based on an id using where_exp, but for the life of me I can't get it to work. Here's the code:
filter:
{% assign var = site.content | where_exp:"content", "content.id == 'testId'" | first %}
frontmatter for post in collection:
---
layout: content
title: "This is the title"
image: "assets/photos/image.jpg"
id: "testId"
---
html:
<img class="full-width-poto" src="{{ var.image }}">
I can't figure out what I'm doing wrong.
Note, I've been referring to this post: Getting a specific item from a collection in Jekyll and https://riptutorial.com/jekyll/example/28446/accessing-a-specific-collection-item
Ok, I figured out my problem, just in case someone comes across this. For some reason I can't use the key 'id' for this...it must be hardcoded for something else.
I swapped in 'myid' and it works fine now...

build an includable template as string [django]

I want to build a list of clickable links for my nav, and because these are links to my site, I want to use the url-tag. I get a list of dictonaries which knows all names for the links and create a template string with them with this function:
def get_includable_template(links):
output = '<ul>'
for link in links:
output = output + '<li><a href="{% url' + get_as_link(link) + '%}>" + link['shown'] + '</a></li>'
output = output + '</ul>
links looks like this:
links = [
{'app': 'app1', 'view': 'index', 'shown': 'click here to move to the index'},
{'app': 'app2', 'view': 'someview', 'shown': 'Click!'}
]
get_as_link(link) looks like this:
def get_as_link(link):
return "'" + link['app'] + ':' + link['view'] + "'"
The first method will return a template, which looks like this (but it's all in the same code line):
<ul>
<li>click here to move to the index</li>'
<li>Click!</li>
</ul>
I want this to be interpreted as template and included to another template.
But how to include this?
Let's say, my other template looks like this:
{% extends 'base.html' %}
{% block title %}App 1 | Home{% endblock %}
{% block nav %}INCLUDE THE TEMPLATE HERE{% endblock %}
{% block content %}...{% endblock %}
What I have already tried:
make the template string a variable - doesn't work, because it doesn't interpret template language in variables (I couldn't find a template tag similar to safe which not only interprets HTML code but also template code.
Building HTMl code in my methods (Isn't best-practice at all, because I needed to use absolute paths)
Is there a good solution about this?
You are making this more complicated than it needs to be.
Firstly, it seems that the only reason you need this to be interpreted as a template is so that it parses the url tag. But there is already a way of creating links in Python code, and that is the reverse() function. You should use that instead.
Secondly, the way to dynamically generate content for use inside a template is to use a custom template tag.

How do I scrape page content with a generator?

I have a blog where each post has a bunch of images and videos. I would like to be able to tag each of them with some keywords, and then populate a set of pages based on the tags. For example going to /photos/car/ would list all images tagged with car.
I include images and videos using a simple plugin right now, that essentially only has a render function. I figure I could add the tags there.
But how can I make Jekyll 'scrape' my pages and populate pages with images?
Short answer is : this is tricky.
But why ?
A custom imgWithTags-tag liquid tag like {% img cookie-monster.png tag2,tag3 %} can do two things :
render the html tag
store tag -> image associations in a site.taggedImage variable
As this tag can be used on any post, page or collection document, the site.taggedImage variable will only be complete after the render process.
Once the render process is finished, we can grab the :site, :post_render hook to process our datas and create Tags pages.
But here, we can no longer rely on things like {% for p in tagPages %}...{% endfor %} to automatically generate links to our pages : rendering is finished.
The trick can be to maintain a link data file by hand, in order to be able to generate links with loops like this {% for p in site.data.tagPages %}...{% endfor %}
Let's give it a try
NOTE : this works only with Jekyll version 3.1.x (not 3.0.x)
_plugins/imgWithTags-tag.rb
module Jekyll
class ImgWithTags < Liquid::Tag
# Custom liquid tag for images with tags
# syntax : {% img path/to/img.jpg coma, separated, tags %}
# tags are optionnal
#
# This plugin does two things :
# it renders html tag <a href='url'><img src='url' /></a>
# it stores tags -> images associations in site.config['images-tags']
Syntax = /^(?<image_src>[^\s]+\.[a-zA-Z0-9]{3,4})\s*(?<tags>[\s\S]+)?$/
def initialize(tag_name, markup, tokens)
super
if markup =~ Syntax then
#url = $1
#tags = $2.split(",").collect!{|tag| tag.strip } if !$2.nil?
else
raise "Image Tag can't read this tag. Try {% img path/to/img.jpg [coma, separated, tags] %}."
end
end
def render(context)
storeImgTags(context) if defined?(#tags) # store datas if we have tags
site = context.registers[:site]
imgTag = "<a href='#{ site.baseurl }/assets/#{#url}'><img src='#{ site.baseurl }/assets/#{#url}' /></a>"
end
def storeImgTags(context)
# store tagged images datas in site config under the key site.config['images-tags']
imagesTags = context.registers[:site].config['images-tags'] || {}
#tags.each{|tag|
slug = Utils.slugify(tag) # My tag -> my-tag
# create a tag.slug entry if it doesn't exist
imagesTags[slug] = imagesTags[slug] || {'name' => tag, 'images' => [] }
# add image url in the tag.images array if the url doesn't already exist
# this avoid duplicates
imagesTags[slug]['images'] |= [#url.to_s]
}
context.registers[:site].config['images-tags'] = imagesTags
end
end
end
Liquid::Template.register_tag('img', Jekyll::ImgWithTags)
At this point : all tagged images links are rendered and all tags->images associations are stored.
_plugins/hook-site-post-render-imagesTagsPagesGenerator.rb
Jekyll::Hooks.register :site, :post_render do |site, payload|
puts "++++++ site post_render hook : generating Images Tags pages"
imagesTags = site.config['images-tags'] # datas stored by img tag
linksDatas = site.data['imagesTagsLinks'] # tags pages link in data file
pagesFolder = 'tag'
imagesTags.each do |slug, datas|
tagName = datas['name']
tagImages = datas['images']
pageDir = File.join(pagesFolder, slug)
tagPage = Jekyll::ImageTagPage.new(site, site.source, pageDir, tagName, tagImages)
# as page rendering has already fired we do it again for our new pages
tagPage.output = Jekyll::Renderer.new(site, tagPage, payload).run
tagPage.trigger_hooks(:post_render)
site.pages << tagPage
# verbose check to see if we reference every tag url in out data file
if !linksDatas.key?(tagName) # check if tag is in imagesTagsLinks data file
puts "Warning ---------> #{tagName} not in data file"
puts "Add : #{tagName}: #{tagPage.url}"
puts "in data/imagesTagsLinks.yml"
puts
else
if tagPage.url != linksDatas[tagName] then # check if url is correct in imagesTagsLinks data file
puts "Warning ---------> incorrect url for '#{tagName}'"
puts "Replace : #{tagName}: #{linksDatas[tagName]}"
puts "by : #{tagName}: #{tagPage.url}"
puts "in data/imagesTagsLinks.yml"
puts
end
end
end
puts "++++++ END site post_render hook"
end
module Jekyll
class ImageTagPage < Page
def initialize(site, base, dir, tag, images)
#site = site
#base = base
#dir = dir
#name = 'index.html'
self.process(#name)
self.read_yaml(File.join(base, '_layouts'), 'tag_index.html')
self.data['tag'] = tag
self.data['images'] = images
self.data['title'] = "Images for tag : #{tag}"
end
end
end
And the Tag layout page
_layouts/tag_index.html
---
layout: default
---
<h2>{{ page.title }}</h2>
{% for i in page.images %}
<img src="{{ site.baseurl }}/assets/{{ i }}" alt="Image tagged {{ page.tag }}">
{% endfor %}
Here, everything is in place to generate tags page.
We can now do a jekyll build and see the verbose output just tell us what to add in _data/imagesTagsLinks.yml
_data/imagesTagsLinks.yml
tag1: /tag/tag1/
tag2: /tag/tag2/
...
We can now link to our tag page from everywhere with a simple
{% for t in site.data.imagesTagsLinks %}
<li>{{ t[0] }}</li>
{% endfor %}
I've told you : it's tricky. But It does the job.
Note: the img tag can be improved, and why not a figure tag ?

Django: escaping translations with safe

I've got a problem. When I use HTML Tags in a translation (.po files) they end up being displayed as: <p>. When I use the |safe filter it results in <p>. But I don't get it to work that the actual html tags are passed.
Anyone got a clue about this?
.po file:
#: website/views.py:35
msgid "web_content_detailed"
msgstr "<h1>asdjkasjdlas</h1>"
view.py:
context = {}
context['somevar'] = _('web_content_detailed')
return render(request, 'somehtml.html', context)
somehtml.html:
{{ somevar }} => <h1>asdjkasjdlas</h1>
{{ somevar|safe }} => <h1>asdjkasjdlas</h1>`

In Jekyll, how to set default tab size in highlighted code?

The tab size of highlighted code can be set by {% highlight c tabsize=4 %}. But this should be set every code blocks. Is there a method to set the default tab size?
# _plugins/pygments_options.rb
class Jekyll::Tags::HighlightBlock
old_sanitized_opts = instance_method(:sanitized_opts)
define_method(:sanitized_opts) do |*args|
old_sanitized_opts.bind(self).(*args).
merge(Jekyll.configuration.fetch("pygments_options", {}))
end
end
and
# _config.yml
# …
pygments_options:
tabsize: 4
{% highlight c tabsize=4 %} is the only way to pass arguments to highlight tag.