Hi i am using PHP and Twig to create a blog for practice, i want to be able to access a post for it to display completely on a new url, for this i use a route to '/indiv' which using a controller renders a new page, what i want is to be able to access any post and display it using only one '.twig' file, however i don't seem to find a way to find out wich post was clicked, i know it has something to do with $_GET or $_POST however i don't know how to get the id of the post, some help would be greatly appreciated :)
{% extends "layout.twig" %}
{% block content %}
{% for blogPost in blogPosts %}
<div class="blog-post">
<a href={{'/indiv' | url}}> <h2> {{blogPost.title}} </h2> </a>
<form method="get">
<lable for="id"></lable>
<input class="btn btn-primary" type="submit" value="GotoPost">
<a href={{'/indiv' | url}}> </a>
</input>
</form>
<p> Jan 1, 2020 by Alex </p>
{% if blogPost.img_url %}
<div class="blog-post-image">
<img src={{blogPost.img_url}} alt="">
</div>
{% endif %}
</div>
{% endfor %}
{% endblock %}
one way:
you have to alter your route so it accepts a parameter
/indiv/{id}
and in your html you send the id of the clicked post
<a href='/indiv/{{blogPost.id}}>
another way:
as i can see in your code, you are sending data in a form so you can send the id of the post as well in the form using <input type="hidden" value="{{blogPost.id}}"
i never used Twig so the syntax might be wrong but this is the logic to be used.
Related
I'm very new to python and django framework. I'm facing a minor issue of not being able to assign a variable to my for loop.
In my html file there are buttons and a list (rendered using a loop).
for ex:
Buttons
<li><a class="layer-item" href="#" onclick="selectLayer('base')" title="Base layer">Base layer</a></li>
<li><a class="layer-item" href="#" onclick="selectLayer('soil')" title="Soil layers">Soil layers</a></li>
Inside script tags i'm updating the variable value as
<script>
var layerType = "";
function selectLayer(layer){
layerType = layer;
}
</script>
Also i have a loop like following in the same html file
{% for layer in base %}
<div class="col-4">
<span class="base-layer-title d-block">{{layer.title}}</span>
</div>
{% endfor %}
Here i want to replace base according the button clicked.
For ex:
<a class="layer-item" href="#" onclick="selectLayer('soil')" title="Soil layers">Soil layers</a>
Clicking on the above button should make the for loop as
{% for layer in soil %}
<div class="col-4">
<span class="base-layer-title d-block">{{layer.title}}</span>
</div>
{% endfor %}
From i read you can do something like this to assign a value to a variable.
{% with name="World" %} But not sure how to implement it in my issue.
Any help is appreciated
Also i have a loop like following in the same html file
{% for layer in base %}
{{layer.title}} {% endfor %}
Here i want to replace base according the button clicked.
In short, Django is a server-side framework and it cannot directly respond to any client-side activity. You cannot do it effectively without client-side libraries like React, JQuery, etc.
Workaround 1
You can make a new request to the server on click and re-render the entire page with new parameters.
urls.py
path('my_pattern/<slug:my_layer>', myview)
views.py
def myView(request, my_layer):
# your logics
base = get_layer_data(my_layer) # <-- logic to get list dynamically
return render(request, 'my_template.html', context={'base':base})
my_template.html
{% for layer in base %}
<div class="col-4">
<span class="base-layer-title d-block">{{layer.title}}</span>
</div>
{% endfor %}
...
<a class="layer-item" href="/my_pattern/soil" title="Soil layers">Soil layers</a>
<a class="layer-item" href="/my_pattern/some_other_layer" title="Some other layers">Soil layers</a>
...
The base will have dynamically generated data on every request.
Workaround 2
You can, however, render all the data on the page and control it using collapse in bootstrap https://getbootstrap.com/docs/4.5/components/collapse/
When the first page is loaded, I want the user to come across all the music, but if he selects a list from RadioButton, I only want the music in that list, but the javascript function doesn't work.
Let me add that I don't normally know JavaScript, but I need to use it.
<div style = "margin-top : 100px;"class = "container">
{% for table in tables %}
<input type="radio" name="list1" onclick="mL('{{table}}')"> {{table}}
{% endfor %}
<div align="center">
<audio class="my_audio" controls="controls" autoplay="autoplay" style="width:500px;"></audio>
<ul>
{% for table in tables %}
{% for music in musics %}
<li style="list-style-type:None">
<a id="{{table}}" href="javascript:void(0);" onclick="playSong('{{music}}')">{{music}}</a>
</li>
{% endfor %}
{% endfor %}
{% for music in musics %}
<li style="list-style-type:None">
<a id="default" href="javascript:void(0);" onclick="playSong('{{music}}')">{{music}}</a>
</li>
{% endfor %}
</ul>
</div>
</div>
<script> function mL(x)
{
{% for table in tables %}
if (x=={{table}})
document.getElementById("{{table}}").style.display="block";
document.getElementById("default").style.display="none";
{% endfor %}
else
document.getElementById("{{table}}").style.display="none";
document.getElementById("default").style.display="block";
return;
}
</script>
This isn't a Django issue, it's purely about the JavaScript (or should be).
Here are some problems with your code:
In HTML, the id attribute should be unique in the document. You seem to have many <a> tags with the same id. Use the class attribute, or even better use your own data attribute like data-table.
You can code generate JavaScript using Django template tags like you have, but I think it's a bad idea because it's very hard to reason about how the code will work. Don't use {% for %} inside the <script> block.
JavaScript doesn't use spaces for code blocks like Python does. You need to use braces { } instead.
Once those things are fixed, use the debugging console in your browser (F12 in Firefox and Chrome). It will let you see any syntax errors, and you can even run code in the console to see how things like document.getElementById work.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am iterating over my model and I wanted to replace that list with content from same model, only sorted, just by using a button. Let's presume I have this:
<div class="col-md-3">
<button>Replace content </button>
</div
<div class="col-md-9">
{% for c in cats%}
{{c.name}}
{% endfor %}
<p>Content to be replaced</p>
</div>
<div class="col-md-9">
{% for c in animal.cats_set.all %}
{{c.name}}
{% endfor %}
<p>Content to replace above content, sorted by if cat belongs to same animal</p>
</div>
How would I replace the content with the second content in this case ? Im thinking about a jQuery.
I'm going to throw out a warning first: deciding on whether you want the data changed by the Django template player or JQuery are two very different things.
Django will change the data on the server, while JQuery is used to change rendered data (usually after the page has already been displayed to the user).
Going the Django Route:
Django is only a template player, so you cannot change it after it has been rendered. It is not a functional language which can continually interact with a rendered page.
You can, however, use the template syntax to put logic in place to decide where data will go or use a structure such as the Django Blocks:
{% block blockName %}
...
{% endblock %}
When I'm writing a complex template I often find myself using this structure:
{% extends "path/ParentFile.html" %}
{% block content %}
{% include "path/ToDefaultChildFile.html" %}
{% endblock %}
If you're ok with the page rendering and then changing it with JQuery once the page is loaded then you'll want to look into the JQuery/JavaScript/frontend framework code to do so.
Use the jQuery .replaceWith() function. Like:
<div class="col-md-3">
<button>Replace content </button>
</div
<div class="col-md-9 old">
{% for c in cats%}
{{c.name}}
{% endfor %}
<p>Content to be replaced</p>
</div>
<div class="col-md-9 new">
{% for c in animal.cats_set.all %}
{{c.name}}
{% endfor %}
<p>Content to replace above content, sorted by if cat belongs to same animal</p>
</div>
Your jQuery function will be:
$(function() {
$(":button").click(function(e) {
$(".old").replaceWith($(".new"));
});
});
On our online fashion store http://www.showstyle.lu I am the webmaster trying to improve the user experience perspective. I finally managed to use a toggle tool for our filters (click on any category: e.g. Homme) as you can see if you click on Couleurs/Tailles etc all the filters appear (they used to be displayed permanently which didn't look aesthethic).
Now, the issue is upon selection of filters the page is then reloaded with a new url to filter the products. Each time the filters then toggle back up of course and it's redundant to have to reclick each one and see what filter's one chose.
Is there a way I can either make the center content container refresh like php where the rest of the site remains static? Or otherwise can I at least force the toggle to remain open if the url has "%filter%*****" in it ?
We are using a ecommerce platform called SEOshop so I don't have access to every script/index page on the website but I have access to a large part.
The filters work on generation from backend so in the html code the placeholders are simply:
{% for filter in collection.filters.custom %} <a class="filtertitle" href="javascript:;">
<p>{{ filter.title }}</p>
</a>
{% for value in filter.values %}
<div class="filterbox2">
<div class="sidebar-filter-item clearfix">
<input id="filter_{{ value.id }}" type="checkbox" name="filter[]" value="{{ value.id }}" {% if value.active %} checked="checked"{% endif %} />
<label for="filter_{{ value.id }}">{{ value.title }}{% if not value.active and value.has_count %} <span>({{ value.count }})</span>{% endif %}</label>
</div>
</div>
{% endfor %}
{% endfor %}
</form>
</div>
Another topic, is it possible to have the toggle open a popup instead? Something to look like this: https://dl.dropboxusercontent.com/u/5636466/showstyle/mockup_filters.png
Thanks for any help, I will continue my research and post my attempts/anything I find :)
If you want to reload only a specific part of the website then there is no way to do it only with php. What you are trying to do will require ajax requests to load the data without reloading the page and javascript to determine where it should be displayed (I would recommend looking into a framework like angular for that). I don't know anything about your site backend but I'm guessing this is not a trivial change and will require you to learn about such things.
I have an html file which I am rendering with jinja2 in python, which has some div sections like
<div id="imdb">
{{imdb_output}}
</div>
Now even when the value of imdb_output variable is returned None from its function in python file, as expected HTML still displays the div section although with no content, but with its css!
But what do I need to do so that even the empty div section does not appear if imdb_output has no values to display?? Do I need to add some JS?
Please help!
Here is a screenshot of the problem:-
http://imgur.com/qVfk2
use this
{% if imdb_output %}
<div id="imdb">
{{imdb_output}}
</div>
{% endif %}
You should read jinja2 documentation for template designers
Just check if imdb_output is empty:
{% if imdb_output %}
<div id="imdb">
{{imdb_output}}
</div>
{% endif %}