I'm using django v1.11.7 with Jinja2 v2.10 as the template engine.
In my website, I wish to render forms using bootstrap. I found out that django-widget-tweaks can be used for this integration.
This package won't work with Jinja templates, since it needs to load a custom tag set into the Jinja environment. Loading tag sets can be complex, since I may need to write an extension.
Is there an easy way to get django-widget-tweaks to work with Jinja? Or is there another way for integrating boostrap with Jinja?
A little late but maybe this can help.
What I did is import the function I wanted to use and called them in my jinja templates:
app_root.jinja2.py
from jinja2 import Environment
from jinja2 import contextfunction
from widget_tweaks.templatetags.widget_tweaks import render_field
def environment(**options):
env = Environment(**options)
env.globals.update({
'render_field': render_field,
})
return env
In template
{% set class = class + "my-html-class" %}
{{ render_field(field, class) }}
EDIT: Anyone with a little bit of Jinja and template tag experience knows this won't work. For my current needs, I defined the two following function in my jinja config and will evaluate my needs at a later time.
def set_attr(bound_field, attr, value):
bound_field.field.widget.attrs[attr] = value
return bound_field
def add_class(bound_field, value):
try:
bound_field.field.widget.attrs['class'] += value
except KeyError:
bound_field.field.widget.attrs['class'] = value
return bound_field
EDIT 2
Other useful link: https://github.com/niwinz/django-jinja/issues/140
To make this solution work, I had to make these changes:
jinja2.py
from jinja2 import Environment
from widget_tweaks.templatetags.widget_tweaks import add_class
from widget_tweaks.templatetags.widget_tweaks import set_attr
def environment(**options):
env = Environment(**options)
env.filters['set_attr'] = set_attr
env.filters['add_class'] = add_class
return env
template.html
{{ form.field |set_attr('attr:val') }}
{{ form.field |add_class('my_class') }}
Related
I created a Variable (from Airflow UI):
Key: env_variables
Value: {'xx': 'yy`}
and trying to access using var.json.env_variables.xx inside bash operator. But the value of "xx" is dynamic, which
I am passing from REST API and accessing it using dag_run.conf['param'] (dag_run.conf['param'] should return xx). Eventually I want to run var.json.env_variables.xx. How can I achieve that inside bash operator in Airflow?
I am trying to run the following code but its showing Jinja Syntax Error.
task = BashOperator(
bash_command="export KUBECONFIG=$KUBECONFIG:{{var.json.env_variables.{{dag_run.conf['param']}} }}
What I want:
It should fetch the value of var.json.env_variables.xx. I have also tried using params but no luck, params.path is returning None.
task = BashOperator(
bash_command="export KUBECONFIG=$KUBECONFIG:{{params.path}},
params: {
"path":env_variables.get('{{dag_run.conf["param"]}}')
}
Any kind of help is highly appreciated.
You don't need the extra {{...}} in the Jinja expression around dag_run.conf and you'll also need the typical item access of a dictionary. Try using a template expression like this:
nested_vars = BashOperator(
task_id="nest_vars",
bash_command="export KUBECONFIG=$KUBECONFIG:{{ var.json.env_variables[dag_run.conf['param']] }}"
)
This is the log entry when passing in a triggering config of {"param": "xx"} to the operator instantiation above:
INFO - Running command: ['bash', '-c', 'export KUBECONFIG=$KUBECONFIG:yy']
I am trying to pass to 3 AWS launch template userdata a bash script. This script calls other scripts from Github depending on a specific variable. Since each launch template must call different scripts what is the best way to accomplish it. I am currently trying to configure a data source template_file but I canĀ“t find a way to do what I need.
This is a piece of the bash script where I put a variable that need to change its value depending on which launch template is being built every time:
#------------------------------------------------------------------------------------------
# Define here scripts (separated with 1 space) that will be executed on first run:
AMI_SCRIPTS="ami_base_lynis.sh ${ami_script}"
#------------------------------------------------------------------------------------------
download_and_run_scripts
This is the template file data source:
data "template_file" "AMIs"{
template = "${file("../AMIs/s1_aws_userdata.sh")}"
vars = {
ami = var.dci_appserver_ami
}
}
And this is the user data attribute:
user_data_base64 = base64encode(data.template_file.AMIs.rendered)
This is not working for me as it will replace the variable has the same value for all 3 launch templates. How can I assign each time a different value?
The syntax you used for user_data_base64 tells me that you're using Terraform v0.12 or later, so you should no longer use template_file as shown in the template_file documentation:
In Terraform 0.12 and later, the templatefile function offers a built-in mechanism for rendering a template from a file. Use that function instead, unless you are using Terraform 0.11 or earlier.
Because of that, I'm going to answer using the templatefile function instead.
Inside each of your launch template resource blocks, you can call templatefile with different values for the template variables in order to get a different result each time:
resource "aws_launch_template" "example1" {
# ...
user_data = base64encode(templatefile("${path.module}/../AMIs/s1_aws_userdata.sh", {
ami = var.dci_appserver_ami
ami_script = "script1.sh"
}))
}
resource "aws_launch_template" "example2" {
# ...
user_data = base64encode(templatefile("${path.module}/../AMIs/s1_aws_userdata.sh", {
ami = var.dci_appserver_ami
ami_script = "script2.sh"
}))
}
resource "aws_launch_template" "example3" {
# ...
user_data = base64encode(templatefile("${path.module}/../AMIs/s1_aws_userdata.sh", {
ami = var.dci_appserver_ami
ami_script = "script3.sh"
}))
}
You could in principle factor out constructing the templates into a local value if you want to do it more systematically, but since your question didn't include any indication that you are doing anything special with the launch templates here I've just written the simplest possible approach, where each launch template has its own template-rendering expression.
When creating a Go template, you can give it a name, like in this example, "my_home_template":
var tmplHome = template.Must(template.New("my_home_template").Funcs(funcMap).ParseFiles("templates/base.tmpl", "templates/content_home.tmpl"))
How can I get that template name and use it inside the actual template file?
Ultimately I just want to define a convenient css class, like so:
<body class="my_home_template">
Here's a working solution, taking mkopriva's advice:
When executing a template, pass some custom parameter with dummy data. Here, I just create a "PageHome" parameter to pass to the template, and value is a simple "1", but it could be any value:
tmplHome.ExecuteTemplate(w, "base", map[string]interface{}{"PageHome": "1", "Data": events, "UserFirstName": &u.FirstName, "UserProfilePic": &u.ProfilePic})
Then, inside the template itself, a simple if statement to check if the parameter exists, and do something accordingly:
{{ if .PageHome }}
<body class="PageHome">
{{ else }}
<body>
{{ end }}
All my other template executions don't pass a "PageHome" parameter at all, so the if statement never passes as true for them.
There's probably a more advanced solution using a functions via a template function map, and having a consistent "PageType":"something" parameter in all template executions, but in the end you still have to define a parameter per template execution and still have to build up if statements in your templates anyways.
I have some python code that runs in multiple environments. The code checks for the existence of environment variables, and takes a slightly different path depending on what environment variable is defined. The code is:
def _get_sink_to_function():
# Determine which path we send data to, based on env variables
# One of the following env variables must be present.
funcdict = {
'LOG_SINK': _post_gzip_to_log_sink,
'FIREHOSE_SINK': _post_gzip_to_firehose_sink
}
for v in funcdict.keys():
if os.environ.get(v):
return funcdict[v]
return None
main():
sink_to_func = _get_sink_to_function()
if not sink_to_func:
raise AssertionError('Missing mandatory env variable')
...
sink_to_func(gzip_data)
The environment variables are set using ansible.
Therefore, I would like to conditionally create the environement variable.
For example, in this (valid) ansible code:
LOG_SYNC: "{% if logger == 'one' %}path-to-the-log{% endif %}"
LOG_SYNC is always defined, sometimes with a value of "path-to-the-log", and sometimes as empty. I want LOG_SYNC not to be defined at all if logger is not equal to 'one'.
In other words, I want something like:
{% if logger == 'one' %}
LOG_SYNC: "path-to-the-log"
{% endif %}
But, that does not seem to be allowed.
The compiler, in whatever language you have written code, will need the variable to be defined first, if it is going to be used anytime later.
so you will need to define the variable, assign value NULL then it will not occupy any memory
I set the template path:
class Mustache
self.template_path = 'templates/pages'
end
This works fine.
But, I want to store the partials in a separate folder: templates/partials.
A mustache template looks like:
Hello {{ name }}
Your info: {{> info }
info.mustache is a partial.
The info partial has no class, so I can't set self.template_path.
So, how to set a template path for a partial, or have multiple template paths?
self.template_path = 'templates'
self.template_path = 'templates/'
self.template_path = 'templates/*'
self.template_path = 'templates/**'
self.template_path = [ 'templates/pages', 'templates/partials' ]
did not work.
You can't. If you look at this file you see that only the template path can be set. Partials end up using the same path during rendering.
https://github.com/defunkt/mustache/blob/master/lib/mustache/settings.rb
However, if you name your partial {{>partials/info}}, it will look for info.mustache inside your template path(templates/partials/info.mustache).
You can also override the partial method from mustache.rb like this:
class Fubar < Mustache
def partial(name)
partial_name = "partials/#{name}"
super(partial_name)
end
end
In the end a partial is no different than any other template. The pathing that you want is just for organizational purposes.
Another user brought up a good point that mustache is now maintained. There was a point in time where the original contributor had stopped supporting it. I'm glad someone else had picked up the project.