Have separate template for each tab without having separate URL - Django - django

I'm trying to develop a reporting system using Django. I have to display reports about various categories of data.I have put each category as a tab-tab1,tab2, etc. Is it possible to have different template for each tab without having to change the url.
I have tried template inheritance but that requires have separate url for each tab.
My concern is that if the number of tabs grow, then the number of urls will also increase.
Any suggestions please?
Thanks in Advance.

Why is it a problem for the number of URLs to increase?
Presumably you don't need separate URLconf entries for each tab, you can just capture the tab name in the URL and send it on to the view:
url(r'^reports/(?P<tab_name>\w+)/$', views.reports, name='reports')
...
def reports(request, tab_name):
... do something depending on tab_name ...

You can just use {% include %} tag and include different templates.
And I think it's better to have unique URL for each tab, it least with hashtag.

You can use a library like jquery tabs to create the tabs, then load each template individually either through include as suggested by #DrTyrsa or by a custom template tag (which would be my personal preference).
Here is an example (from the excellent bootstrap framework from twitter):
<ul class="tabs">
<li class="active">Home</li>
<li>Profile</li>
<li>Messages</li>
<li>Settings</li>
</ul>
<div class="pill-content">
<div class="active" id="home">...</div>
<div id="profile">...</div>
<div id="messages">...</div>
<div id="settings">...</div>
</div>
<script>
$(function () {
$('.tabs').tabs()
})
</script>

Related

Load django template dynamically

I've 2 section in my screen. Left section is for showing tabs and right is for displaying that tab template(as shown in screenshot). I'm not able to understand how to load different templates when I click these tabs
For example, when I click change password, I should be able to load change_password.html template
This is by far I've tried with code.
<div class="nav">
<ul>
<li class="active"></i><span class="hidden-xs hidden-sm">Home</span></li>
<li></i><span class="hidden-xs hidden-sm">Change Password</span></li>
<li>Bookings</span></li>
<li></i><span class="hidden-xs hidden-sm">Settings</span></li>
</ul>
</div>
I've tried to use with but no luck.
I've just started with django, so if anything is missed let me know. Thanks for your help!
Screenshot
I think what you're attempting is not possible. If you don't want a page reload upon clicking on a tab, you need to use Javascript to dynamically show/hide elements. If page reload is acceptable, you can create different views for each tab, each view rendering a different html file.
You can use the Django include tag to render another template with the current context. E.g. {% include "foo/bar.html" %} (see documentation here). But this will not solve your problem of displaying different content upon clicking on a tab.

Django - How do I change the sort order of search results while still on the page?

I have a list of results from a user's search and I want the user to be able to re-order them
as they wish. It is simple enough to pre-sort the queryset on the backend, in views.py which is what every Google
search brings up on the topic. But I need to have this done by the user. On the frontend. This is
usually done with a dropdown with options allowing alphabetical sort A-Z or sort by date added or so on.
I can't find an answer with Google search or a single tutorial that covers it, yet I see it used almost everywhere.
Does the solution involve ajax? How would I use ajax to do it? Is there a py module that does this in Django?
I am rendering the search results something like this
{% for stor in stories %}
<div>
<span class="story_block stock_bg">
<a href="{{stor.get_absolute_url}}">
<div class="story_con_block">
<p class="s_t">{{stor.title}}</p>
<p>by <strong>{{stor.author.username}}</strong></p>
<p>{{stor.summary}}</p>
</div>
</a>
</span>
</div>
{% endfor %}
It can be done with javascript if you are rendering the list with javascript. as javascript can manipulate the DOM , so you can sort it with javascript code and add click event to these sorting functions

Django along with bootstrap navbar - distiinguishing link to current page

I use bootstrap for my django project.
I have a navbar like this:
[home][gallery][user]
How can I change the CSS properties of a specific navbar button to correspond to a currently opened page?
For example, if I am on the home page, the home button would be highlighted.
Solution 1
I usually have the navbar template gets included in all templates, each template should define what the page is this.
For example
# nav.html
<div class="..">
<div class="..">My Nav</div>
<ul class="..">
Home
Settings
</ul>
</div>
Then in each template you specify which should be active. something like this
# home.html
{% include "yourtemplatedir/nav.html" with active='home' %}
# settings.html
{% include "yourtemplatedir/nav.html" with active='settings' %}
Solution 2
Using context processor will make it sometimes easy
def get_current_path(request):
return {
'current_path': request.get_full_path()
}
In your template you can use {{ current_path }} to determine which nav item should be active.
You can also enhance the context processor code in order to check the prefix of the url and set the active_page variable automatically. so you don't need to set it with each include (In case you include the nav.html in your base always). However it really hard to have exceptions in here.

Refresh Only template Grails

I have a list.gsp which loads a template .
Actually the template contains which loads the data from the domain class.
Every 10 seconds I want to refresh the template only, so that it gets latest data from the db. How can i do this?
There are several ways to solve this but all of them require Ajax. I'll give one example:
Suppose the following HTML:
<div class="content">
... other content here
<div id="template">
<g:render template="someTemplate" ... />
</div>
... other content here
</div>
Then this javascript:
setInterval(refreshTemplateEveryTenSeconds, 10000);
function refreshTemplateEveryTenSeconds() {
$('#template').load("/some/server/resource");
}
See the jquery load docs for more info on this.
Obviously, if you're not using jQuery then modify to do the ajax call as your technology would suggest. But this gives you a general idea of how you might approach the problem.

Django: Is there a better way to bold the current page link

I have a base.html template that contains a list of links.
Example:
<div id="sidebar1">
<ul>
<li>Index</li>
<li>Stuff</li>
<li>About Me</li>
<li>Contact Me</li>
</div>
Then I have in my views.py a definition for each of index.html, stuff.html, about.html and contact.html. Each of those templates simply derive from a base.html template and set their own respective titles and contents.
My question is about the above /stuff I have a class="current".
I'd like to make the current page that I'm on have that class attribute.
I could set a different variable in each view like current_page="about" and then do a compare in the template with {% ifequal %} in each class element of each link , but that seems like duplicating work (because of the extra view variable).
Is there a better way? Maybe if there is a way to get the view function name that the template was filled from automatically I would not need to set the extra variable? Also it does seem like a lot of ifequals.
Here's an elegant way to do this, which I copied from somewhere and I only wish I could remember where, so I could give them the credit. 8-)
I assign an id to each of my pages (or all the pages within a section) like this:
In index.html: <body id='section-intro'>...
In faq.html: <body id='section-faq'>...
In download.html: <body id='section-download'>...
And then an id for the corresponding links:
<li id='nav-intro'>Introduction</li>
<li id='nav-faq'>FAQ</li>
<li id='nav-download'>Download</li>
And the in the CSS I set a rule like this:
#section-intro #nav-intro,
#section-faq #nav-faq,
#section-download #nav-download {
font-weight: bold;
/* And whatever other styles the current link should have. */
}
So this works in a mostly declarative way to control the style of the link that the current page belongs in. You can see it in action here: http://entrian.com/source-search/
It's a very clean and simple system once you've set it up, because:
You don't need to mess about with template markup in your links
You don't end up using big ugly switch statements or if / else / else statements
Adding pages to a section Just Works [TM]
Changing the way things look only ever means changing the CSS, not the markup.
I'm not using Django, but this system works anywhere. In your case, where you "set their own respective titles and contents" you also need to set the body id, and there's no other Django markup required.
This idea extends easily to other situations as well, eg. "I want a download link in the sidebar on every page except the download pages themselves." You can do that in CSS like this:
#section-download #sidebar #download-link {
display: none;
}
rather than having to put conditional template markup in the sidebar HTML.
Haven't used Django, but I've dealt with the same issue in Kohana (PHP) and Rails.
What I do in Kohana:
<li><a href="/admin/dashboard" <?= (get_class($this) == 'Dashboard_Controller') ? "class=\"active\"" : NULL ?>>Dashboard</a></li>
<li><a href="/admin/campaigns" <?= (get_class($this) == 'Campaigns_Controller') ? "class=\"active\"" : NULL ?>>Campaigns</a></li>
<li><a href="/admin/lists" <?= (get_class($this) == 'Lists_Controller') ? "class=\"active\"" : NULL ?>>Lists</a></li>
What I do in Rails:
<li><a href="/main" <%= 'class="active"' if (controller.controller_name == 'main') %>>Overview</a></li>
<li><a href="/notifications" <%= 'class="active"' if (controller.controller_name == 'notifications') %>>Notifications</a></li>
<li><a href="/reports" <%= 'class="active"' if (controller.controller_name == 'reports') %>>Reports</a></li>
I see only a couple of ways of doing it, while avoiding repeated ifequals:
Javascript. Something along the lines of (jQuery):
var parts = window.location.pathname.split('/');
var page = parts[parts.length-1];
$('#sidebar1 a[href*=' + page + ']').addClass('current');
Change your views to contain a list of pages with their associated titles and URLs and create a {% for %} loop in your template, which will go through that list, and add a single {% ifequal %}.
Option 2 being the favorite from where I stand. If the logic for all of your pages is the same, and only the templates differ, you might consider using the FlatPages model for each of your pages. If the logic is different, and you need different models, you might consider using a menuing app of some sort. A shameless plug: I have a menuing app of my own
If you add the request context processor, it's pretty straightforward:
settings.py:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.request',
'django.contrib.auth.context_processors.auth' # admin app wants this too
)
Now you have access to the HttpRequest, which contains the request path. Highlighting the current page is a simple matter of checking if the path matches the link's destination, i.e., you're already there:
<li><a class="{% if request.path == '/' %}current{% endif %}" href="/">Index</a></li>
<li><a class="{% if request.path == '/stuff/' %}current{% endif %}" href="/stuff/">Stuff</a></li>
<li><a class="{% if request.path == '/about/' %}current{% endif %}" href="/about/">About Me</a></li>
<li><a class="{% if request.path == '/contact/' %}current{% endif %}" href="/contact/">Contact Me</a></li>