Jinja2 in google appengine extended template repeates base templete - google-app-engine

Ok I have a base.html and I try to use that for my header menu and footer. In my other template I loop over items and display them on the page. My problem is the the other template is repeating my base.html like it's in the loop. I hope someone can show me the error in My ways.
Here is my base.html code:
<div class="menu">
<ul class="nav">
<li>Home</li>
<li>New Entry</li>
<li>Sign-up</li>
{% if user %}
<li>{{user.name}}</li>
<li>Log-Out</li>
{% else %}
<li>Log-In</li>
{% endif %}
</ul>
​
This is in the base.html also but didn't paste correctly.
<div id="content">
{% block content %}
{% endblock %}
</div>
And here is the sub template code:
{% extends "base.html" %}
{% block content %}
{% for p in posts %}
{{ p.render() | safe }}
<br><br>
{% endfor %}
<div>
{{text}}
</div>
{% endblock %}
Please help
Edit:
edit2: removed link and found my problem I was calling the wrong html file in render()
Be kind Newbie here

Looks ok. Are you sure you don't have a loop in the python code that renders the template?

Related

How can you loop through all of the children of a model?

In Django I am trying to loop through all of the children of my Todo model. But whenever I try to run it, it gives me an AttributeError that says "Manager isn't accessible via Todo instances". My code looks like this:
{% extends 'base.html' %}
{% block content %}
<h3>Tasks</h3>
{% for t in model.objects.all %} <!-- Error -->
<p>{{t.name}}</p>
{% endfor %}
{% endblock %}
{% block options %}
<li class="bg-light py-3 w-100 px-4 rounded text-nowrap fs-4">
<button class="text-decoration-none text-dark">Save</button>
</li>
{% endblock %}
I tried to just put the model in the context, and then I got an error in the HTML, so I figured out that it happened when I tried to reference 'model.objects.all'.
Inside of your view you need to specify what django should pass to the template. It does not serve the entire Database; therefore queries like in model.objects.all inside of your templates are not allowed.
Specify the queryset inside your views.py:
def todo_view(request):
context = {}
context['my_todos'] = my_todo_model.objects.all()
context['most_important_todo'] = my_todo_model.objects.get(pk=1)
# put your own logic inside the `.get` method above
return render(request, 'my_template.html' context)
And then access it inside of your template like so:
{% for t in my_todos %}
<p>{{ t.name }}</p>
{% endfor %}
{{ most_important_todo.name }}
Because we put a queryset inside of my_todos we can loop over it in the template. most_important_todo ist just a single object passed to the template, so we can access its properties (e.g. the name) directly.
Let me know how it goes

syntax in wagtail HTML template file

In below HTML template of Wagtail,
<h1>{{ page.title }}</h1>
<div>{{ page.intro }}</div>
{% for post in page.get_children %}
<h2>{{ post.title }}</h2>
<p>{{ post.first_published_at }}</p>
<p>{{ post.owner }}</p>
{% if post.specific.rncategory.all.count %}
{% for ctgy in post.specific.rncategory.all %}
{{ctgy.category.name}}
{% endfor %}
{% endif %}
{% for tg in post.specific.rntags.all %}
<button type="button">{{tg.tag.name}}</button>
{% endfor %}
{% endfor %}
Q1: Why we use page.get_children & post.specific.rncategory.all.count instead of page.get_children() and post.specific.rncategory.all().count() which are expected to be corrected ?
And It is the other way around (page.get_children is invalid) in the PDB debug interaction session.
(Pdb++) obj.get_children()[0]
<Page: Detail>
(Pdb++) obj.get_children()[0].specific.rncategory.all.count
*** AttributeError: 'function' object has no attribute 'count'
(Pdb++) obj.get_children()[0].specific.rncategory.all
<bound method BaseManager.all of <modelcluster.fields.create_deferring_foreign_related_manager.<locals>.DeferringRelatedManager object at 0x7f7076003790>>
(Pdb++) obj.get_children()[0].specific.rncategory.all()
<QuerySet []>
(Pdb++) obj.get_children()[1].specific.rncategory.all()
<QuerySet [<Link_PostDetail_Category: Link_PostDetail_Category object (2)>]>
(Pdb++) obj.get_children()[1].specific.rncategory.all().count()
1
(Pdb++) obj.get_children()[0].specific.rncategory.all().count()
0
(Pdb++)
This is the normal behaviour of the Django template language - by design, Django template code is not equivalent to Python.
Django template syntax never uses () for function calls. Instead, whenever a variable lookup results in a callable, it will automatically be called with no arguments. See "Behind the scenes" under https://docs.djangoproject.com/en/stable/ref/templates/language/#variables.

Wagtail Show latest blog posts on Homepage through a streamfield

I have 3 mains sections in my site, homepage, blog index, and blog specific. I am using the streamfield function in wagtail to order various sections in the homepage. One of those sections is for the latest three blog posts.
I have done this for the blog index page, but can't grab the latest blog posts in the streamfield.
My model looks like this
class CaseStudiesIndex(Page):
def casestudies(pages):
casestudies = CaseStudyPage.objects.all().order_by('-first_published_at')
return casestudies
intro = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('intro', classname="full")
]
class LatestPosts(blocks.StructBlock):
static = blocks.StaticBlock(admin_text='Latest posts: no configuration needed.',)
def casestudies(pages):
casestudies = CaseStudyPage.objects.all().order_by('-first_published_at')[:3]
return casestudies
class Meta:
icon = 'doc-full'
label = 'Latest Posts'
template = 'blocks/_latestPosts.html'
class HomePage(Page):
blocksbody = StreamField([
('lead_banner', LeadBanner()),
('latest_posts', LatestPosts()),
('team', Team())
],null=True,blank=True)
content_panels = Page.content_panels + [
StreamFieldPanel('blocksbody'),
]
In my block folder I am calling the file fine and it renders the wrapper fine but I can't grab any of the data, I have tried a bunch of ways but nothing returns.
{% load wagtailcore_tags wagtailimages_tags %}
{% load static %}
<section>
<div class="wrapper__inner">
<ul>
{% for case in self.casestudies %}
{{case.title}}
{% endfor %}
{% for case in self.case_studies %}
{{case.title}}
{% endfor %}
{% for case in self.latest_posts %}
{{case.title}}
{% endfor %}
{% for case in page.casestudies %}
{{case.title}}
{% endfor %}
{% for case in page.case_studies %}
{{case.title}}
{% endfor %}
{% for case in page.latest_posts %}
{{case.title}}
{% endfor %}
</ul>
</div>
</section>
For the Blog Index page that does work I do the following.
{% extends "inner_base.html" %}
{% load wagtailcore_tags %}
{% block body_class %}template-case-studies{% endblock %}
{% block content %}
<section>
<div class="wrapper__inner">
<h1>{{self.title}}</h1>
<ul>
{% include "blocks/CaseStudiesLatestBlock.html" %}
</ul>
</div>
</section>
{% endblock %}
And the CaseStudiesLatestBlock.html which works fine looks like
{% load wagtailcore_tags wagtailimages_tags %}
{% load static %}
{% for case in self.casestudies %}
<li>
<strong>{{ case.title }}</strong>
</li>
{% endfor %}
Defining your own methods on a StructBlock won't work - the self (or value) variable you receive on the template is just a plain dict, not the StructBlock object itself. (This might seem counter-intuitive, but it's consistent with how blocks work in general: just as a CharBlock gives you a string value to work with and not a CharBlock instance, StructBlock gives you a dict rather than a StructBlock instance.)
Instead, you can define a get_context method (as documented here) to provide additional variables to the template:
class LatestPosts(blocks.StructBlock):
static = blocks.StaticBlock(admin_text='Latest posts: no configuration needed.',)
def get_context(self, value, parent_context=None):
context = super(LatestPosts, self).get_context(value, parent_context=parent_context)
context['casestudies'] = CaseStudyPage.objects.all().order_by('-first_published_at')[:3]
return context
You can then access the casestudies variable in the template, e.g. {% for case in casestudies %}.

Hyde copy code from content straight in to deploy

I'm using hyde (http://hyde.github.io) and everything is working great. Then I needed a page that is not static. I wrote it in php. Is there a way to have hyde just copy the content straight in to the deploy page from the content page?
{% extends "topbar.j2" %}
{% block container %}
{% block ignore %} *Hyde don't try to process just copy as is*
<h2> Search </h2>
<?php
... php code ...
echo "Stuff"
?>
{% endblock ignore %}
{% endblock container %}
So with some playing and deeper reading of the documentation.
The raw tag is for jinja syntax only (as shown)
{% raw %}
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endraw %}
Thought about turning off the markdown filter for the search page, but didn't want to create jinja page rules
Learned that one line of php does not seem to break the page.
<?php phpinfo(); ?>
Our solution
Move all php code back to its own file searcher.php
<?php
if(url is searcher.php redirect to search.php);
//code and stuff ... ;
echo "results";
?>
Keep the search.php page simple
{% extends "topbar.j2" %}
{% block container %}
<h2> Search </h2>
{% raw %}
<?php include_once("searcher.php"); ?>
{% endraw %}
{% endblock container %}

Access variable from included template in Jinja2?

I'm developing in app engine.
I have a parent template with this:
{% set active_page = 'linked_accounts' -%}
{% block side_column %}
{% include 'blocks/settings_sidebar.html' %}
{% endblock %}
settings_sidebar contains
<h4>Settings</h4>
<hr>
{{active_page}}
<ul class="side_navigation">
<li><a class="{% if 'my_account' == active_page %}active{% endif %}" href="/my_account">My Account</a></li>
<li><a class="{% if 'linked_accounts' == active_page %}active{% endif %}" href="/linked_accounts">Linked Accounts</a></li>
</ul>
My problem is that active_page is empty. The docs state that by default includes include their parent scope, and yet that doesn't seem to be the case here.
Figured it out. I had to add scoped to the block declaration or the include didn't have variable access.

Resources