build an includable template as string [django] - html

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.

Related

django tag { % block content % } isn't working

so i just started learning django, i understand the basic tag blocks but it didn't works well on my page. i have page called index.html and question.html
i write like this in index.html
<body>
<div>
<div>
sum content
</div>
<div>
{ % block content % }
{ % endblock % }
</div>
</div>
</body>
and like this in question.html :
{ % extends 'index.html' % }
{ % block content % }
<<my content>>
{ % endblock % }
but the content in question.html didn't show up in index.html. i've checked my setting and didn't have django-stub like in other case.
and if you want to know the structure, it goes like :
djangoProject1
>djangoProject1
>myweb
>static
>templates
-index.html
-question.html
this is my views.py
def index(request):
return render(request, 'index.html')
def question(request):
return render(request, 'question.html')
def formdata(request):
nama = request.POST.get("namaa")
umur = request.POST.get("umur")
komorbid = request.POST.get("penyakit_bawaan")
ruang = request.POST.get("ketersediaan_ruang")
demam = request.POST.get("demam")
lelah = request.POST.get("lelah")
batuk = request.POST.get("batuk")
nyeri = request.POST.get("nyeri")
tersumbat = request.POST.get("tersumbat")
pilek = request.POST.get("pilek")
sakit_kepala = request.POST.get("sakit_kepala")
tenggorokan = request.POST.get("tenggorokan")
diare = request.POST.get("diare")
hilang_cium = request.POST.get("hilang_penciuman")
ruam = request.POST.get("ruam")
sesak = request.POST.get("sesak")
sulit_gerak = request.POST.get("sulit_gerak")
nyeri_dada = request.POST.get("nyeri_dada")
hasil_rekomendasi = request.POST("hasil_rekomendasi")
data_resp = DataResponden(nama=nama, umur=umur, penyakit_bawaan=komorbid, ketersediaan_ruang=ruang, demam=demam,
lelah=lelah, batuk=batuk, nyeri=nyeri, tersumbat=tersumbat, pilek=pilek,
sakit_kepala=sakit_kepala, tenggorokan=tenggorokan, diare=diare,
hilang_penciuman=hilang_cium, ruam=ruam, sesak=sesak, sulit_gerak=sulit_gerak,
nyeri_dada=nyeri_dada, hasil_rekomendasi=hasil_rekomendasi)
data_resp.save()
return render(request, 'question.html')
Thank you in advance!
It looks like you might have some confusion regarding how templates work. index.html is a parent/base template, because it is being extended (through the {% extends 'index.html' %} tag). question.html is a child template, which means if you make no changes, it will inherit everything from index.html.
A child template can override parts of the parent template by using {% block %} tags. So when the webpage is getting rendered, the code from the block in the parent is not used at all (if there was any). When you directly render the parent template, there will be no such replacement since it does not extend anything.
So the rendered HTML for your files should be as follows
index.html
<body>
<div>
<div>
sum content
</div>
<div>
</div>
</div>
</body>
question.html
<body>
<div>
<div>
sum content
</div>
<div>
<<my content>>
</div>
</div>
</body>
So yeah, content in question.html is not supposed to show up in index.html. It works the other way around, with the entire structure of index.html being used for question.html, except for the things you override.
If you want index to have some content by default, you can have code inside the content block. It will be replaced by any child templates if necessary, but when you load just index.html it will still be visible.
If you are actually trying to insert something into index.html, take a look at the include tag. This allows for re-using common sections of the website across webpages. But you would not extend the base template inside any template you are planning to include.
Just remove the spaces in tag blocks everywhere like this:
Change this:
{ % block content % }
To this:
{% block content %}
Similarly with other tag blocks.

How to integrate jinja module inside PyGears

I created jinja module as example, which looks like this
{% from 'snippet.j2' import module with context %}
{% call module() %}
logic [$size(din.data)-1 : 0] res;
assign res = din.data * din.data;
{% if params['half'] %}
assign dout.data = res / 2;
{% else %}
assign dout.data = res;
{% endif %}
assign din.ready = dout.ready;
assign dout.valid = din.valid;
{% endcall %}
How should I use this module inside PyGears?
Okay, I think this should work.
If I understood correctly you are trying to create a Jinja template for a module that will multiply with 1/2 (in other words divide by two). First of all, make sure your Jinja file and module are named the same (this is a must so PyGears would know which Jinja template to use).
Having all this in mind let's say our module name is mulh
Python file would be something like this:
from pygears import gear, Intf, reg
from pygears.typing import Uint
from pygears.hdl import hdlgen
#gear
def mulh(din: Uint,*,half=False)->b'din*din':
    pass
mulh(Intf(Uint[8]))
hdlgen('/mulh', outdir='.')
This code will call your Jinja file and the HDL output would look like something like this:
module mulh
(
    input logic clk,
    input logic rst,
    dti.consumer din, // u8 (8)
    dti.producer dout // u16 (16)
);
    typedef logic [7:0] din_t; // u8
    typedef logic [15:0] dout_t; // u16
    din_t din_s;
    dout_t dout_s;
    assign din_s = din.data;
    assign dout.data = dout_s;
    logic [$size(din.data)-1 : 0] res;
    assign res          = din.data * din.data;
    assign dout.data    = res;
assign din.ready    = dout.ready;
    assign dout.valid   = din.valid;
endmodule
To make it easier to picture all of this I made this picture bellow

DJANGO template tags in plain text not displaying

I am making an app that displays questions. The question model has a text field and an image field. Each question has a template that is stored in my database in the text field. My problem is when I want to access images from the model, template tags are displayed as text and not rendering. My code:
# question model
class Question(models.Model):
question_text = models.TextField()
question_image = models.FileField(upload_to='static/images/questions', blank=true)
# question view
def question(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'questiontemplate.html', {'question': question})
# template
{% extends 'base.html %}
{% load static %}
{% autoscape off %}
{{ question.question_text }}
{% endautoscape %}
# in my database:
question.question_text = '<p> some html
{{ question.question_image.url }}
some html </p>'
question.question_image = 'image.png'
This works fine and renders the html perfectly except the template tag is not rendered and does not not give the image url
I want this to be the output:
Some html
static/images/questions/image.png
some html
But instead this is the output:
some html
{{ question.question_image.url }}
some html
Any suggestions to how the template tags could be render from the database text would be much appreciated.
Thanks for reading
Django doesn't know that the content in your model field is itself a model. The template can't know that. The only way to make this work is to treat that field itself as a template, and render it manually.
You could do that with a method on the model:
from django.template import Template, Context
class Question(models.Model):
...
def render_question(self):
template = Template(self.question_text)
context = Context({'question': self})
rendered = template.render(context)
return mark_safe(rendered)
Now you can call it in your template:
{{ question.render_question }}

How to render HTML with golang data in golang gin web frame?

I am trying to place a golang array (also slice, struct, etc.) to HTML so I can use array element in HTML Element content when returning HTML from golang gin web framework. Another problem is how to render these data with loop? Such as Flask jinja
works in this way.
{% block body %}
<ul>
{% for user in users %}
<li>{{ user.username }}</li>
{% endfor %}
</ul>
Usually you have a folder with template files so first you need to tell the gin where these templates are located:
router := gin.Default()
router.LoadHTMLGlob("templates/*")
Then in handler function you simply pass template name the data to HTML function like this:
func (s *Server) renderIndex(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", []string{"a", "b", "c"})
}
In index.tmpl you can the loop the data like this:
{{range .}}
{{.}}
{{end}}
The . is always the current context so in first line . is the input data and inside the range loop . is the current element.
Template example: https://play.golang.org/p/4_IPwD3Y84D
Documentation about templating: https://golang.org/pkg/text/template/
Great examples: https://astaxie.gitbooks.io/build-web-application-with-golang/en/07.4.html

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 ?