Start the Page Menu not from root_page, rather from second level - django

I have a page tree wich begins with 3 pages:
/private
/business
/education
in each of those pages there are several other pages inside.
Like as the wagtail demosite i built a templatetag to implement the top navigaton in my base template. the special thing is, that my menu is splitted in two sections: the first level (private, business, education) is shown up on the top of my website (section menu) and the child elements of those pages lies in my bootstrap navbar (top menu). how can i tell the top_menu model to ignore the first level, because its allready shown in my section menu?
menu_tags.py
from django import template
register = template.Library()
#register.assignment_tag(takes_context=True)
def get_site_root(context):
return context['request'].site.root_page
def has_menu_children(page):
return page.get_children().live().in_menu().exists()
#register.inclusion_tag('tags/section_menu.html', takes_context=True)
def section_menu(context, parent, calling_page=None):
menuitems_section = parent.get_children().filter(
live=True,
show_in_menus=True
)
return {
'calling_page': calling_page,
'menuitems': menuitems_section,
# required by the pageurl tag that we want to use within this template
'request': context['request'],
}
#register.inclusion_tag('tags/top_menu.html', takes_context=True)
def top_menu(context, parent, calling_page=None):
menuitems = parent.get_children().filter(
live=True,
show_in_menus=True
)
for menuitem in menuitems:
menuitem.show_dropdown = has_menu_children(menuitem)
return {
'calling_page': calling_page,
'menuitems': menuitems,
# required by the pageurl tag that we want to use within this template
'request': context['request'],
}
# Retrieves the children of the top menu items for the drop downs
#register.inclusion_tag('tags/top_menu_children.html', takes_context=True)
def top_menu_children(context, parent):
menuitems_children = parent.get_children()
menuitems_children = menuitems_children.live().in_menu()
return {
'parent': parent,
'menuitems_children': menuitems_children,
# required by the pageurl tag that we want to use within this template
'request': context['request'],
}
section_menu.html
{% load menu_tags wagtailcore_tags %}
{% for menuitem in menuitems %}
<li class="{% if calling_page.url == menuitem.url %} active{% endif %}">
{{ menuitem.title }}
</li>
{% endfor %}
top_menu.html
{% load menu_tags wagtailcore_tags %}
{% get_site_root as site_root %}
{% for menuitem in menuitems %}
<li class="{% if menuitem.show_dropdown %}dropdown{% endif %}{% if menuitem.active %} active{% endif %}">
{% if menuitem.show_dropdown %}
<a data-toggle="dropdown" class="dropdown-toggle" href="#">{{ menuitem.title }} <b class="caret"></b></a>
{% top_menu_children parent=menuitem %}
{% else %}
{{ menuitem.title }}
{% endif %}
</li>
{% endfor %}
header.html (where my section menu lies)
<header class="ms-header ms-header-dark">
<div class="departement-switcher">
<div class="container">
<ul>
{% block menu %}
{% get_site_root as site_root %}
{% section_menu parent=site_root calling_page=self %}
{% endblock %}
</ul>
</div>
</div>
</header>
navbar.html (where my default menu lies)
{% load menu_tags static %}
<nav class="navbar navbar-static-top yamm ms-navbar ms-navbar-dark">
<div class="container container-full">
<div class="navbar-header">
<a class="navbar-brand" href="/">
<img src="{% static 'img/logo.svg' %}" alt="Data Quest AG">
</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
{% block menu %}
{% get_first_level as site_root %}
{% top_menu parent=site_root calling_page=self %}
{% endblock %}
</ul>
</div>
<a href="javascript:void(0)" class="sb-toggle-left btn-navbar-menu">
<i class="zmdi zmdi-menu"></i>
</a>
</div>
</nav>

Related

Problem pagination for category posts in Django

I used the following code for pagination and got the error I left here. please help.
Note that for categories whose number of posts is less than 2 (_paginator), there is no problem, but the same posts are more than two and pagination is done.
urls.py:
from django.urls import path
from . views import home, detail_article, category_list
app_name = "blog"
urlpatterns = [
path('', home, name="home"),
path('page/<int:page>', home, name="home"),
path('post/<slug:slug>', detail_article, name="detail_article"),
path('category/<slug:slug>', category_list, name="category_list"),
path('category/<slug:slug>/page/<int:page>', category_list, name="category_list")
]
views.py:
def category_list(request, slug, page=1):
category = get_object_or_404(Category, slug=slug, status=True)
article_list = category.articles.published()
_paginator = Paginator(article_list, 2)
articles = _paginator.get_page(page)
context = {
'category':category,
'articles':articles
}
return render(request, 'blog/category.html', context)
template.html:
<!-- Paginator -->
{% if articles.has_other_pages %}
<div class="col-12 pagging">
<ul>
{% if articles.has_previous %}
<li>
<a href="{% url 'blog:category_list' category.slug articles.previous_page_number %}">
<i class="fa fa-arrow-right" aria-hidden="true"></i></a>
</li>
{% else %}
<li><i class="fa fa-arrow-right a-active" aria-hidden="true"></i></li>
{% endif %}
<!-- {% for i in articles.paginator.page_range %} {% if articles.number == i %}
<li><span class="a-active">{{ i }}</span></li>
{% else %}
<li>{{ i }}</li>
{% endif %} {% endfor %} -->
{% if articles.has_next %}
<li>
<a href="{% url 'blog:category_list' category.slug articles.next_page_number %}">
<i class="fa fa-arrow-left" aria-hidden="true"></i>
</a>
</li>
{% else %}
<li><i class="fa fa-arrow-left a-active" aria-hidden="true"></i></li>
{% endif %}
</ul>
</div>
{% endif %}
<!-- end paginator -->
and error! :(
error
The HTML in comment is still rendered by the template engine. So you should remove the {% url 'blog:category' %} parts. If you want to put comment in a Django template, you do that between {# … #}, or you can use a {% comment %} … {% endcomment %} template block [Django-doc].
For example:
{% if articles.has_previous %}
<li>
<a href="{% url 'blog:category_list' category.slug articles.previous_page_number %}">
<i class="fa fa-arrow-right" aria-hidden="true"></i></a>
</li>
{% else %}
<li><i class="fa fa-arrow-right a-active" aria-hidden="true"></i></li>
{% endif %}
{% comment %}
<!-- {% for i in articles.paginator.page_range %} {% if articles.number == i %}
<li><span class="a-active">{{ i }}</span></li>
{% else %}
<li>{{ i }}</li>
{% endif %} {% endfor %} -->
{% endcomment %}
{% if articles.has_next %}
<li>
<a href="{% url 'blog:category_list' category.slug articles.next_page_number %}">
<i class="fa fa-arrow-left" aria-hidden="true"></i>
</a>
</li>
{% else %}
<li><i class="fa fa-arrow-left a-active" aria-hidden="true"></i></li>
{% endif %}
fixed problem! :)
{% for i in articles.paginator.page_range %}
{% if articles.number == i %}
<li><span class="a-active">{{ i }}</span></li>
{% else %}
<li>{{ i }}</li>
{% endif %} {% endfor %}

How to fetch and display data from Django Model without invoking the URL

I have a Class-Based ListView as shown below:
class JobByStateView(ListView):
model = State
template_name = 'jobs/jobs_by_state.html'
context_object_name = 'state_list'
ordering = ['name']
paginate_by = 15
I have added the path to urls.py file as shown below:
path('jobs/', JobByStateView.as_view(), name='job-by-state'),
And this how my template looks:
<div class="row">
<div class="col-md-4">
<ul class="list-unstyled mb-0">
{% for state in state_list %}
{% if forloop.counter|divisibleby:"5" == False %}
<li>
{{state.name}}
</li>
{% else %}
<li>
{{state.name}}
</li>
</ul>
</div>
<div class="col-md-4">
<ul class="list-unstyled mb-0">
{% endif %}
{% endfor %}
</ul>
</div>
</div>
When I try to access this templates via the url (http://localhost:8000/jobs) it works as expected and displays the data on the screen. But when I try embed this template within another template as shown below, nothing gets displayed on the web page.
{% include 'jobs/jobs_by_state.html' %}
I would like to display this template as a widget within another template.
Really appreciate, if anyone could please help me in fixing this issue.
Thank you so much in advance for your time and help!
=========================================================================
The other page template is:
{% extends 'base.html' %}
{% block page_content %}
{% include 'carousel.html' %}
{% for job in job_list %}
<div class="listing-wrapper">
<div class="listing-container border-top border-bottom">
<a href="{{ job.get_absolute_url }}">
<h2 class="heading mt-3 mb-1 mx-2 d-inline-block">{{ job.title}}</h2>
</a>
</div>
</div>
{% endfor %}
{% if is_paginated %}
<ul class="pagination justify-content-center my-4">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link bg-dark text-white" href="?page{{page_obj.previous_page_number}}">← Previous Page</a>
</li>
{% endif %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link bg-dark text-white" href="?page{{page_obj.next_page_number}}">Next Page →</a>
</li>
{% endif %}
</ul>
{% endif %}
{% include 'jobs/jobs_by_state.html' with state_list=state_list %}
{% endblock page_content %}
{% block page_sidebar %}
{% include 'simple_search_widget.html' %}
<!-- Social Sharing Buttons -->
<div class="sharethis-inline-share-buttons mt-4"></div>
<!-- Newsletter Widget -->
{% include 'newsletter_widget.html' %}
{% endblock page_sidebar %}
The view for the parent template is as shown below:
class JobList(ListView):
model = Job
template_name = "jobs/job_listings.html"
context_object_name = "job_list"
ordering = ['-published_date']
paginate_by = 10
The following solution from #Charnel and #ChidG worked.
#Shahzan, ok, well you are referring to that variable in your template like this: {% include 'jobs/jobs_by_state.html' with state_list=state_list %}. So if the variable isn't in the context, it can't be passed to the included template, and so the included template won't display anything.

My generic DetailView not showing list of items

I am following a django tutorial series, the music website contains the ListView which contains Albums(this is showing) but the DetailView Containing the list of songs in each Album is not showing.
I have tried changing the iteration name in the for loop but it still not working, the list shows when i am not using the generic method i.e using index and detail function instead of the IndexView and DetailView classes.
MY music.views Code
class IndexView(generic.ListView):
template_name='music/index.html'
def get_queryset(self):
return Albums.objects.all()
class DetailView(generic.DetailView):
model = Albums
template_name = 'music/detail.html'
My detail.html code which is supposed to show the list of songs but not working
{% extends 'music/base.html' %}
{% block title %} Album Details {% endblock %}
{% block body %}
<img src ="{{ all_album.alb_logo }}">
<h1>{{ all_album.alb_title }}</h1>
<ul>
{% for song in all_album.song_set.all %}
<li>{{ song.song_title }} </li>
{% endfor %}
</ul>
<br>
{% endblock %}
My index.html which shows the list of albums, this is working
{% extends 'music/base.html' %}
{% block body %}
<h2>List of Current albums available</h2>
<div class='container-fluid'>
<div class='row'>
{% for album in object_list %}
<div class='col-lg-4'>
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="{{ album.alb_logo }}" >
<div class="card-body">
<h5 class="card-title">{{ album.alb_title }}</h5>
<p class="card-text">{{ album.alb_artist }}</p>
<a href="{% url 'music:detail' album.id %}" class="btn
btn-primary btn-sm">View details</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
My urls.py code#
urlpatterns = [
path('',views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
]
The detail.html page is expected to show the list of songs in a selected album that is already in the database when clicked, but it is not showing.
You were using the wrong context variable name(all_album) inside the template, it should be object.
#detail.html
{% extends 'music/base.html' %}
{% block title %} Album Details {% endblock %}
{% block body %}
<img src="{{ object.alb_logo }}">
<h1>{{ object.alb_title }}</h1>
<ul>
{% for song in object.song_set.all %}
<li>{{ song.song_title }} </li>
{% endfor %}
</ul>
<br>
{% endblock %}
Reference: DetailView get_context_data() method--Django Doc

How to create two pagination in Django for the same page?

I have searching on the internet but I did not find a good answer, I would like to know if is possible to create multiple pagination with ListView, like I changed my context to return two list of different objects and then I will put each in a row and each row will have a paginatior for that list.
How should I proceed to achieve this ?
ListView
class IndexView(TemplateView):
template_name = "index.html"
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['oportunities_idea'] = Oportunity.objects.filter(goal_oportunity_idea=True)
context['oportunities_project'] = Oportunity.objects.filter(goal_oportunity_project=True)
return context
index.html
<div class="row mt15"><!--project-->
<div id="home" class="tab-pane row fade in active">
<legend>Projects</legend>
{% for project in oportunities_project %}
<h2>{{project.title}}<h2>
{% if forloop.counter|divisibleby:1 %}
</li>
<li>
{% endif %}
{% endfor %}
</div>
</div>
<div class="row mt15">
<div id="home" class="tab-pane row fade in active">
<legend>Ideas</legend>
{% for idea in oportunities_idea %}
<h2>{{idea.title}}<h2>
{% if forloop.counter|divisibleby:1 %}
</li>
<li>
{% endif %}
{% endfor %}
</div>
</div>

How to set up a custom template in djangocms

I've successfully installed djangocms on a Ubuntu machine, and now I would like to integrate a custom template bought from Envato.
After I have installed it, djangocms came with its own simple template files which are located in mysite/templates:
base.html
{% load cms_tags staticfiles sekizai_tags menu_tags %}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}This is my new project home page{% endblock title %}</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap-theme.min.css">
{% render_block "css" %}
</head>
<body>
{% cms_toolbar %}
<div class="container">
<div class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
{% show_menu 0 1 100 100 "menu.html" %}
</ul>
</div>
</div>
{% block content %}{% endblock content %}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.min.js"></script>
{% render_block "js" %}
</body>
</html>
feature.html
{% extends "base.html" %}
{% load cms_tags %}
{% block title %}{% page_attribute "page_title" %}{% endblock title %}
{% block content %}
<div class="jumbotron">
{% placeholder "feature" %}
</div>
<div>
{% placeholder "content" %}
</div>
{% endblock content %}
menu.html
{% load i18n menu_tags cache %}
{% for child in children %}
<li class="{% if child.ancestor %}ancestor{% endif %}
{% if child.selected %} active{% endif %}
{% if child.children %} dropdown{% endif %}">
{% if child.children %}
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
{{ child.get_menu_title }} <span class="caret"></span>
</a>
<ul class="dropdown-menu">
{% show_menu from_level to_level extra_inactive extra_active template "" "" child %}
</ul>
{% else %}
<span>{{ child.get_menu_title }}</span>
{% endif %}
</li>
{% if class and forloop.last and not forloop.parentloop %}{% endif %}
{% endfor %}
page.html
{% extends "base.html" %}
{% load cms_tags %}
{% block title %}{% page_attribute "page_title" %}{% endblock title %}
{% block content %}
{% placeholder "content" %}
{% endblock content %}
I have read their documentation but I haven't found anything related to some custom template integration. Could anyone please lead me in the right direction ?
EDIT1:
I have added in CMS_TEMPLATES:
CMS_TEMPLATES = (
## Customize this
('page.html', 'Page'),
('feature.html', 'Page with Feature'),
('index.html', 'oriel.io') # this is what I added
)
but nothing happened.
Add your templates to CMS_TEMPLATES in your settings file.
I recently met the same problem! So let me try to explain
1) You should extend PageAdmin in admin.py
In admin side, when you want to choose template for page ('advanced settings') it will call AdvancedSettingsForm by default. but we must to extend too to give your templates.
class ExtendedPageAdmin(PageAdmin):
def get_form_class(self, request, obj=None, **kwargs):
if 'advanced' in request.path_info:
return ExtendedAdvancedSettingsForm
elif 'permission' in request.path_info:
return PagePermissionForm
elif 'dates' in request.path_info:
return PublicationDatesForm
return self.form
and DO NOT forget unregister and register
admin.site.unregister(Page)
admin.site.register(Page, ExtendedPageAdmin)
2) OK) You have choosen ('advanced settings') and there must be choice among your custom templates.
class ExtendedAdvancedSettingsForm(AdvancedSettingsForm):
def __init__(self, *args, **kwargs):
super(ExtendedAdvancedSettingsForm, self).__init__(*args, **kwargs)
template_choices = [(x, _(y)) for x, y in get_cms_setting('TEMPLATES')]
self.fields['template'] = forms.ChoiceField(choices=template_choices)
3) Ok, wee see custom templates for page, but there will be error if you want to save it. It's because of Page model. It looks like this:
#python_2_unicode_compatible
class Page(six.with_metaclass(PageMetaClass, MP_Node)):
"""
A simple hierarchical page model
"""
...
template_choices = [(x, _(y)) for x, y in get_cms_setting('TEMPLATES')]
...
template = models.CharField(_("template"), max_length=100,
choices=template_choices, default=TEMPLATE_DEFAULT
help_text=_('The template used to render the content.'))
4) So you should change template_choice during init the Page object. Let's use signals
def after_page_init(sender, instance, **kwargs):
instance._meta.get_field_by_name('template')[0]._choices = []
def patch_cms_page():
from cms.models import Page
from django.db.models.signals import post_init
post_init.connect(after_page_init, sender=Page)
and finally call patch_cms_page() in urls.py )