I'm trying to send some data from my python code to the HTML script.
This is my python code. I use lists to send the data.
def extractMetaData(request):
pdfDir = "C:/PythonPrograms/pdf/"
if pdfDir == "": pdfDir = os.getcwd() + "\\"
pdf_title = []
pdf_author = []
pdf_creationdate = []
pdf_creator = []
pdf_Keywords = []
pdf_producer = []
for pdf in os.listdir(pdfDir):
fileExtension = pdf.split(".")[-1]
if fileExtension == "pdf":
pdfFilename = pdfDir + pdf
pdf_toread = PdfFileReader(open(pdfFilename, "rb"))
pdf_title.append(pdf_toread.getDocumentInfo().title)
pdf_author.append(pdf_toread.getDocumentInfo().author)
pdf_creationdate.append(pdf_toread.getDocumentInfo()['/CreationDate'])
pdf_creator.append(pdf_toread.getDocumentInfo()['/Creator'])
pdf_Keywords.append(pdf_toread.getDocumentInfo()['/Keywords'])
pdf_producer.append(pdf_toread.getDocumentInfo().producer)
return render(request,'personal/extract.html',{'content':[str(pdf_title),str(pdf_author),str(pdf_creationdate), str(pdf_creator),str(pdf_Keywords), str(pdf_producer)]})
In HTML I use the following code.
{% block content %}
{% for c in content%}
<p>{{c}}</p>
{% endfor%}
{% endblock %}
But this prints all the items of the first list and then all items of second list and so on.. I want it to print the first item of the first list, first item of the second list and so on. Then start with second item of every list.. how can do this in jinja?
I would do it like this :
def extractMetaData(request):
pdfDir = "C:/PythonPrograms/pdf/"
if pdfDir == "":
pdfDir = os.getcwd() + "\\"
pdf_files = []
for pdf in os.listdir(pdfDir):
pdf_file = {} # Create a dictionnary to store values
fileExtension = pdf.split(".")[-1]
if fileExtension == "pdf":
pdfFilename = pdfDir + pdf
pdf_toread = PdfFileReader(open(pdfFilename, "rb"))
pdf_file['title'] = pdf_toread.getDocumentInfo().title
pdf_file['author'] = pdf_toread.getDocumentInfo().author
pdf_file['creationdate'] = pdf_toread.getDocumentInfo()['/CreationDate']
pdf_file['creator'] = pdf_toread.getDocumentInfo()['/Creator']
pdf_file['keywords'] = pdf_toread.getDocumentInfo()['/Keywords']
pdf_file['producer'] = pdf_toread.getDocumentInfo().producer
pdf_files.append(pdf_file)
return render(request,'personal/extract.html', {'pdf_files': pdf_files})
And then in the template :
{% block content %}
{% for pdf in pdf_files %}
{% for item_name, item in pdf_file.items %}
<p>{{ item_name }} : {{ item }}</p>
{% endfor %}
{% endfor%}
<hr>
{% endblock %}
I didn't test it so it might have some errors..
Related
I have to make a string of values separated by semicolons and pass this string to a script in HTML include to then parse and output the result.
My jekyll markdown page:
---
layout: page
title: Our team
permalink: /team
---
{% assign cfhandles=""%}
{% for person in site.data.team-handles %}
{{ cfhandles | append: person.handle }}
{{ cfhandles | append: ";" }}
{% endfor %}
{% include load-ratings.html cfhandles=cfhandles %}
My load-ratings.html:
<script>
let url = "https://codeforces.com/api/user.info?handles=";
let handles = "{{ include.cfhandles }}";
console.log(handles);
url = url + handles;
console.log(url);
async function load() {
let obj = await (await fetch(url)).json();
console.log(obj);
for (let cur_user of obj["result"]) {
let cur_handle = cur_user["handle"];
let user_rating = cur_user["rating"];
document.getElementById(cur_handle.toLowerCase()).innerHTML = "Рейтинг: " + user_rating;
}
}
load();
</script>
My team-handles.yml:
- handle: bob1
name: Bob
- handle: alice2
name: Alice
When I open the developer console, it shows me that in JS the handles variable is empty (but it shouldn't be like that). How do I pass the needed string to the file so it shows correctly?
I already tried using {%- -%} Liquid tags, but it didn't change the result.
Try this:
{% assign cfhandles=""%}
{% for person in site.data.team-handles %}
{% assign cfhandles = cfhandles | append: person.handle | append: ";" %}
{% endfor %}
{% include load-ratings.html cfhandles=cfhandles %}
The code basically assigns the new strings bob1; and alice2; to the existing variable.
I want to render a Jinja2 template, and after the rendering, read the values that were set by it:
import jinja2
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
""")
vars = {"name": "Ned"}
print(template.render(vars).strip())
print(vars)
This prints:
Hello Ned 42!
{'name': 'Ned'}
Is there something I can do after template.render that would give me the value of number? Also, I need to do it without knowing the name number beforehand. I want to discover whatever values have been set in the template.
Here's a way to do it without using functions that are documented, but say not to use them:
import jinja2
template = jinja2.Template("""
{% set number = 52 %}
{% set choice = "apple" %}
Hello {{name}} {{number}}!
{% if number > 50 %}
More than 40!
{% set also = 'foo' %}
{% endif %}
""")
ctx = template.new_context(vars = {"name": "Ned"})
template.render(ctx)
mod = template.module
template_vars = {n:getattr(mod, n) for n in dir(mod) if not n.startswith("_")}
print(template_vars)
This prints:
{'also': 'foo', 'choice': 'apple', 'number': 52}
I guess, this is a kinda hack but it seems you can do something with Context from jinja2.runtime like
$ cat show_vars.py
import jinja2
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
""")
vars = {"name": "Ned"}
print(template.render(vars).strip())
print(vars)
from jinja2 import Environment
from jinja2.runtime import Context
env = Environment()
ctx = Context(env, vars, '', template.blocks)
list(template.root_render_func(ctx))
print(ctx.vars)
print(ctx.get_all())
$ python show_vars.py
Hello Ned 42!
{'name': 'Ned'}
{'number': 42}
{'name': 'Ned', 'number': 42}
As #nedbat pointed out, one can also achieve the same with
import jinja2
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
{% if number > 50 %}
More than 40!
{% set also = 'foo' %}
{% endif %}
""")
ctx = template.new_context(vars = {"name": "Ned"})
list(template.root_render_func(ctx))
print("get_all:", ctx.get_all())
print("exported_vars:", ctx.exported_vars)
print("vars:", ctx.vars)
With the context provided:
import jinja2
import re
template = jinja2.Template("""
{% set number = 42 %}
Hello {{name}} {{number}}!
""")
vars = {"name": "Ned"}
rendered = template.render(vars).strip()
print(vars)
print(rendered)
changed_var_value = re.findall(r'Hello[\s\S]*\s{1}(.*)!', rendered)
print(f'var after the greeting: {changed_var_value}')
output:
{'name': 'Ned'}
Hello Ned 42!
var after the greeting: ['42']
I am trying to edit code using Shopify and their Liquid templates. It should be simple and I've searched their site and online. Their suggestions have not provided me a solution.
This is the original line of code:
{% if settings.display_quickview_vendor %}
<p class="product-vendor"><label>Vendor</label><span></span></p>
{% endif %}
This statement will always be true, referencing the json file. Using the class="product-vendor" and the .js file, it inserts the vendor name with the Vendor label from product setup.
My goal is that when my vendor name is set to "--" (using a drop down in product setup) the vendor line of code will not be executed.
I've tried this
{% if settings.display_quickview_vendor %}
{% if product-vendor != "--" %}
<p class="product-vendor"><label>Vendor</label><span></span></p>
{% endif %}
{% endif %}
I've also replace the second if statement with the following.
{% if product.vendor != "--" %}
{% if product.vendor contains '--' %}
{% if product-vendor contains '--' %}
My experience is with C# and VBA. I have a feeling that I'm not fully understanding what it is that I need to be asking or searching for.
This is the .js file where the quickview window is called.
initQuickView: function() {
e(".quickview-button a").click(function() {
var i = e(this).attr("id");
return Shopify.getProduct(i, function(i) {
var a = e("#quickview-template").html();
e(".quick-view").html(a);
var o = e(".quick-view");
if (o.find(".product-title a").text(i.title), o.find(".product-title a").attr("href", i.url), o.find(".product-vendor span").length > 0 && o.find(".product-vendor span").text(i.vendor), o.find(".product-type span").length > 0 && o.find(".product-type span").text(i.type), o.find(".product-inventory span").length > 0) {
var n = i.variants[0].inventory_quantity;
o.find(".product-inventory span").text(n > 0 ? null != i.variants[0].inventory_management ? n + " in stock" : "Many in stock" : "Out of stock")
}
This is from the schema.json file.
{
"type": "checkbox",
"id": "display_quickview_vendor",
"label": "Display Vendor?",
"default": true
},
This is from the data.json file.
"display_quickview_vendor": true,
I have a js object like this:
var data = [
{ src: "src1", name: "name 1" },
{ src: "src2", name: "name 2" },
{ src: "src3", name: "name 3" }
]
I am looping through it with Nunjucks:
{% for object in data %}
{{object.src}}
{% endfor %}
But I want to limit the number of iterations to 2.
How do I do that with Nunjucks?
I know there is a range option but I couldn't find how to use it in this case.
You could accomplish this a couple different ways:
A) Use loop.index0 special variable (Demo in Codepen)
Inside a for loop, you can use loop.index0 instead limit-var
{% for obj in data %}
{% if loop.index0 < 2 %}
{{obj.src}}: {{obj.name}}
{% endif %}
{% endfor %}
B) Add Custom Filter (Demo in Codepen)
But more readable is add custom filter limit and use it
var nunjucks = require('nunjucks');
var env = nunjucks.configure();
var data = [
{src: "src1", name: "name 1"},
{src: "src2", name: "name 2"},
{src: "src3", name: "name 3"}
];
env.addFilter('limit', function(arr, limit) {
return arr.slice(0, limit);
});
var res = nunjucks.renderString(`
{% for obj in data | limit(2) %}
{{obj.src}}: {{obj.name}}
{% endfor %}`,
{data}
);
console.log(res);
C) Use native slice() function (Demo in Codepen)
{% for obj in data.slice(0, 2) %}
{{obj.src}}: {{obj.name}}
{% endfor %}
I am parsing json in Django Views with following code:
def xyz(request):
url =" https://tools.vcommission.com/api/coupons.php?apikey=952d164efe86ca9ec33a1fdac8e6d0b6d4c02c92f44062bf8b646ad04ebf8cdc "
response = urllib.request.urlopen(url)
data1 = json.loads(response.read())
context = {"data1": data1}
template = 'coupons/store/myntra.html'
return render(request, template, context)
Now I am using this code in my template file
{% for item in data1 %}
{% if item.offer_id == "1022" %}
{{ item.coupon_title }} <br>
{% endif %}
{% endfor %}
All code is working fine but when I view my template html source code it is more than 10K lines.
It's taking more time to load.
Please suggest some ways.