Im new to django; I'm using include inside a template that call another template like this
{% include "cars_models.html" with user_id=request.user.id %}
is there a way to use Cars.objects.get(user_id=request.user.id) or something like inside the cars_models template direct to get all cars are related to user_id without using views
I'm trying to use cars_models templates inside another templates like widgets for base template. I'm not using any view for my base template
Please consider this custom template tag solution:
In the root directory create directory "templatetags". Create file car_tags.py inside the folder, add this code to that file:
from django import template
register = template.Library()
from app_name.models import Car
#register.simple_tag
def car_tag(id):
return Cars.objects.get(user_id=id)
Add library with your tag into the settings.py into TEMPLATES/OPTIONS:
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
'libraries': {
'car_tags': 'templatetags.car_tags',
}
},
In your template load your tag at the top of the template: {% load car_tags %}
Use your tag in your template this way: {% car_tag request.user.id %}
No, you can't use querysets in templates. You need to create one in your views and pass as context to your templates.
But if your models is something like this:
class Car(models.Model):
user = models.ForeignKey(User)
You can call all cars related to the logged user in your templates with:
{% for car in request.user.car_set.all %}
<p>{{car}}</p>
{%endfor%}
Where car_set is the RelatedManager of you model.
Related
I am currently trying to learn how to create my own custom theme from scratch and right now having trouble understanding the code of DAWN theme(wordpress free source theme).
/Sections/page.liquid
<div class="rte">
{%- if section.settings.page.content != blank -%}
{{ section.settings.page.content }}
{%- else -%}
<div class='page-placeholder-wrapper placeholder'>
{{ 'page' | placeholder_svg_tag: 'page-placeholder' }}
</div>
{%- endif -%}
</div>
{% schema %}
{
"name": "t:sections.page.name",
"tag": "section",
"class": "spaced-section",
"settings": [
{
"type": "page",
"id": "page",
"label": "t:sections.page.settings.page.label"
}
],
"presets": [
{
"name": "t:sections.page.presets.name"
}
]
}
{% endschema %}
I don't really understand what is "t:sections.page.name" why pick such a complex name? Does it retrieve any data from any files?
where is this page.liquid being used for? It looks like a bridge that connects the theme and all other sections.
My current goal is to figure out how to include all the custom section within a page template. Say if I have 10 sections writen and intended to include within a single template file. Then, I have to repeat the line {% section 'section-name' %} 10 times. And if there is more template file, the situation will just gotten worse. Is there a way to loop through all sections? Or any tutorials that I can refer to would be really helpful!
Thank you reading and answering!
Here is some explanation based on my knowledge,
For example, When you go to Online store -> Pages -> create a page via green button situated in the top right corner As per the screenshot - click steps where you noticed that the Theme template is Default page check the screenshot. That Default page is equal to your page.json template and inside the page.json [section/main-page.liquid] section is using.
Now here we have section/page.liquid which is basically for if we want page content inside a different page (page inside page)
Here is the screenshot of the page where we can notice that page.liquid is rendering click me
Learning Note : You can add this line <h2> Current template={{template}}.liquid </h2> into theme .liquid to check which template is rendering
For all sections inside the template, I guess you don't need a loop or {% section 'section-name' %} or anything as the Dawn theme is in Shopify 2.0 where all the templates are in JSON format and sections are everywhere so you can add as many as sections you want inside the template-name.JSON
Thank you
This is moreso a question about pyvis graphs, but also involves a django server running with a sqlite3 backend. One of my views needs to produce an interactive pyvis graph and display it in the clients browser. I can do this without the django app with the following code:
from pyvis.network import Network
network = Network()
network.show('map.html')
As you can see with this method, pyvis creates an html file and save it to disk first. nework.show() simply opens the file in the browser. Because I will be running this on a django webapp, I would rather create the graph's html without saving it to disk, then just return it as a string in the HttpResponse for the view. Is it possible to do this, or is there another way that is more appropriate?
One way to do that is to save the pyvis graph into a file within the templates directory of Django. Instead of using network.show(), use network.save_graph(path_to_templates_dir/some_pyvis_file.html) and then include that file inside the template where you want to show the results using the Django tags {% include ‘pvis_graph_file.html’ %}
views.py
from pyvis.network import Network
from django.conf import settings
network = Network()
...
network.save_graph(str(settings.BASE_DIR)+'app/templates/pvis_graph_file.html')
templates/showReport.html
{% extends 'base.html' %}
{% block body %}
Content of Report with pyVis Graphs
{% include 'pvis_graph_file.html' %}
{% endblock %}
I'm new to Drupal & Twig and all I need is in my custom theme a twig expression to output the current user's ID. I can't find anything in the template comments, only if a user is logged in true / false.
Is there a simple way to get the ID of the current user? I'm not sure how to implement custom methods in a theme.
thanks!
Hello bobomoreno,
I would suggest you use the module Bamboo Twig.
The Bamboo Twig module provides some Twig extensions with some useful functions and filters aimed to improve the development experience.
You could then enable the sub-module Bamboo Twig - Loaders:
drush en bamboo_twig_loader -y
Finally, you will be able to use the Twig function bamboo_load_currentuser:
<!-- Get Current User -->
{% set user = bamboo_load_currentuser() %}
<div>{{ user.name.value }}</div>
<div>{{ user.uid.value }}</div>
You can find the complete official documentation there.
In your theme find file yourthemename.theme and add following code:
function yourthemename_preprocess(&$vars, $hook)
{
$vars['uid'] = \Drupal::currentUser()->id();
}
now if you edit your twig template for html, page, region, block, field, form element... you can use 'uid' token in your twig. It works for all hooks
If you only need the ID in user.html.twig, it's {{ user.id }}
Here's how D8 now works, in two lines of executable code:
<?php
// This code returns the current user ID.
$account = \Drupal::currentUser();
return $account->id();
The display name is not a field you can configure in {{ content }}. You can get it directly from the user entity:
{{ user.displayname }}
Reference for the php method: AccountInterface::getDisplayName
The Twig Tweak module is very small and yet very powerful. You can get the current user id with drupal_token('current-user:uid') I am using it to pass the current user id to a view like this:
{{ drupal_view('view_name', 'embed_1', drupal_token('current-user:uid')) }}
We are using Twig as our templating engine but I'm stuck with a problem of the rendering order now. See - https://straightupcraft.com/articles/twig-processing-order
We are using amp for our new site and with amp and web components in general it is necessary to import the components (once) to use them. So the idea was to create a Twig Extension to accomplish exactly this. Everytime a component is used it is called via this twig function call. The function is checking the component, adding it to a stack and you can use it from now on. The stack then is transformed into a list of imports for the head of the page.
The problem here is Twigs top to bottom rendering. When I call said function in a partial or a template the rendering of "layout.twig" already took place and all function calls below/after are not affecting the stack.
Is there an option to change the rendering to inside out, so that the rendering is first using the lowest partial and "bubbles" up to templates and finally layout without them rendering before?
Another way to get the values in layout would nice as well.
Desired behavior:
Layout.twig
{{ getAllComponents() }}
{# should output component1 and component2 #}
{% block content %}
Page.twig
{% extends Layout.twig %}
{{ addComponent('component1') }}
{% include partials.twig %}
<component1>...</component1>
partials.twig
{{ addComponent('component2') }}
<component2>...</component2>
Actual behavior:
Layout.twig
{{ getAllComponents() }}
{# is empty #}
There is no option to change this behavior. However you can use a trick to archive this:
Render your content to a variable before you call getAllComponents()
layout.twig
{% set mainContent %}
{% block content %}{% endblock %}
{% endset %}
{{ getAllComponents() }}
{{ mainContent }}
There actually is a magical solution to this problem -- some genius wrote this Deferred Twig Extension which lets you run some code (output a variable, call a function, etc) in a block near the top of your layout, but wait until the rest of the twig templates have parsed before executing them. There's an example on that github page showing how you can achieve this.
As far as I know, no you cannot switch the rendering of a TWIG template.
However, I would recommend possibly looking at the {% embed %} or {{ render }} tags.
Embed allows specific TWIG files to be placed within others with variables, so you could pass each component into their relevant partials.twig file.
Render allows the use of embedding a separate controller action, so you create a ControllerAction that took in a component variable and renders its own TWIG file.
Documentation on Embed: https://twig.sensiolabs.org/doc/2.x/tags/embed.html
Documentation containing Render: https://twig.sensiolabs.org/doc/2.x/api.html
My application shows a list of projects, project detail pages and forms to edit these projects. These are the routes:
/ - list of projects
/project/42 - view project (project detail page)
/project/42/edit - edit project
Only its owner may edit a project.
I have implemented a Voter to prevent access to /project/42/edit for non-owners.
Now, I also want to hide the link "edit project" from the project detail page. What would be the way to do this? Ideally, in Twig, I would like to do something like
{% if may_access(path('project_edit', { 'id': project.id })) %}
edit project
{% endif %}
I can implement this function as a Twig extension, but maybe a similar functionality already exists.
The function is_granted() actually has a second parameter that allows me to do just what I need:
{% if is_granted("MAY_EDIT", project) %}
edit project
{% endif %}
I use this in combination with a check in the controller action:
public function editAction(Project $project)
{
if (!$this->get('security.context')->isGranted('MAY_EDIT', $project)) {
$this->flash('You are not allowed to edit this project');
return $this->show($project);
}
// ...
}
This is actually very similar to the approach that nifr used in his answer to Sonata User - Security on custom field. I was hoping to find a way to have the voter be called automatically and avoid the call to isGranted().
If you want to have a look at the complete code, it is in the tutorial project I have published in github.