How to add pages to navigation on Pelican? - python

I know this may not be a very smart question, but it really bother me for a while.
I am using Pelican for site generating, with theme SoMA/SoMA2. I am adding a folder under content and some pages inside. This should appear on the navigation according to the Tutorial, but didn't.
I tried with default theme (in quickstart) and it works. Does it mean SoMA/SoMA2 don't support personalized navigation? Any ways I can do with it?
Thanks.

Your intuition is correct: the SoMA/SoMA2 themes do not currently add pages to the navigation menu. You can see this by comparing the notmyidea base template with the SoMA base template. The relevant code is:
{% if DISPLAY_PAGES_ON_MENU -%}
{% for pg in PAGES %}
<li{% if pg == page %} class="active"{% endif %}>{{ pg.title }}</li>
{% endfor %}
{% endif %}
I can't guarantee that will be entirely sufficient, of course, since I haven't fully examined how SoMA implements its navigation, CSS, et cetera. But perhaps this might point you in the right direction.

Related

Strategy for handling recursive template display in Django

I'm rewriting a family tree app in Django that I previously wrote in Laravel. There's an 'outline view' page where I start with the 'original families' at the top of the tree, and show an outline of their children, their children's families/kids, those kids' families/kids, etc.
First I've generated a big nested list with all the info (in the controller for laravel, and in views.py in my Django rewrite). Then I give that list to a couple of views to display the lists for each original family. (Code included below)
Testing the logic a couple levels at a time it works, but when I let it call recursively and load my outline page, it gives me a recursion error: maximum recursion depth exceeded while calling a Python object.
Reading around, it sounds like python has a known limitation that it doesn't handle tail recursion, and I saw some posts saying that showing recursive views isn't good practice in Django.
Update: I've also started down the road of making a management command to generate an html page for this (that I can just show statically, and regenerate when I add new people), and that way I do avoid the recursion error. I'll do a bit more debugging with the original views to see what I can find out about where/when I reach the error (only for one particular branch or family, etc?) in case there's something I can fix in the way I generate the list.
Is there a better way to approach this problem in Django?
outline_whole.html:
{% for entry in results %}
{% get_class entry as object_type %}
{% include chunk_view %}
{% endfor %}
outline_family_chunk.html: (aka chunk_view, passed into the context)
{% get_class entry as object_type %}
<ul>
{% if object_type == 'Family' %}
{{ entry.display_name }}
{% elif object_type == 'Person' %}
<li>{% include "familytree/person_name_link.html" with person=entry %}</li>
{% elif object_type == 'list' %}
<ul>
{% for item in entry %}
{% include chunk_view with entry=item %}
{% endfor %}
</ul>
{% endif %}
</ul>
Example of the list it's working through- it gives a family with its children, then a list for the next family (where one of the original children was a parent):
[<Family: The Skywalker family (Anakin & Padme)>, <Person: Luke Skywalker>, <Person: Leia Skywalker>,[<Family: The Solo family >, <Person: Kylo Ren>]]
So without data it's hard to see where the problem is, but the obvious candidate is:
this_user -> Branch -> descendants[] --\
^ | <- has this_user
|______<___________<__________<______/
So when rendering a person, you render his branch, for which you call get_descendants and then from what I can tell, this could include the top-level user and we go round and round.
But like I said, it's a guess.

Django. How to show some content on only single page without duplicating?

For starters, i'm new in Django.
I have a searchbar and i want to show it on only single page. I use {%block searchbar %} {%endblock%} on all pages where I don't want to see the search bar. But suddenly I thought: I'm duplicating the code, and this violates the principle of "DRY". So, how can I display some content on a single page without duplicating this {%block searchbar %} {%endblock%} stuff?
In advance, thanks for your help!
Use include tag to include the search bar on the pages that you want. See here for more from the docs.
Place the code for the search bar in an HTML file called "searchbar.html
and then include it in any pages that you want.
{% extends "header.html" %}
{% block bar %}
{% include "searchbar.html" %} <!-- Simply include this on pages that you want -->
{% endblock %}
this way you will not violate the DRY principle.

django-wiki: how to list all articles under root article

I am a newbie in Django and am currently building a site. I have downloaded django-wiki ver 0.4a3 to have a wiki app for my site. Everything works fine, out-of-the-box. But instead of showing the root article as the main page, how can I show a list of all articles under the root article, so users can just click on any child article to open up that article? At the moment, users have to click a menu option to browse up one level or to browse at the current level to have a listing of all articles at that given level. I find this rather tedious. I rather have an "Windows Explorer tree-and-branch-like" navigation, e.g.,
root
|_child 1
| |_child 1.1
| |_child 1.2
|
|_child 2
| |_child 2.1
| |_child 2.1.1
|
|_child 3
Please note I am asking how to get a list all of articles under the root article, not how to create a template to implement the tree-and-branch articles navigator. Once I know how to get a listing of all articles, I think I can implement the necessary HTML and CSS to have that kind of navigator. I appreciate any pointers.
P.S. I have previously tried the official django-wiki google support group, but I think the support there is dead and buried. My two questions there are neither answered, let alone read (I only get 1 view -- which is actually my view count).
Chris.
[Solved.]
Make a copy of article.html originally located at wiki/templates/wiki/ and place this copy in your own project's templates/wiki/ directory. At the place where you want to place the tree directory, add something like the following lines:
<!-- article.html -->
...
<h4>List of articles</h4>
<ul>
<!-- Need to get the first article (root) -->
{% url 'wiki:get' path=urlpath.root.path as rootpath %}
<li>
<a href="{{ rootpath }}">
{{ urlpath.root.article.current_revision.title }}
</a>
</li>
<!-- Now get all the descendent articles of the root -->
{% for child in urlpath.root.get_descendants %}
<!-- Don't list articles marked for deletion -->
{% if not child.is_deleted %}
{% with ''|center:child.level as range %}
{% for _ in range %}<ul>{% endfor %}
{% url 'wiki:get' path=child.path as childpath %}
<li>
<a href="{{ childpath }}">
{{ child.article.current_revision.title }}
</a>
</li>
{% for _ in range %}</ul>{% endfor %}
{% endwith %}
{% endif %}
{% endfor %}
</ul>
You can fancy up the code above. I am new in Django (and to using django-wiki), so this might not be the cleanest or most efficient way, but the above works as expected for me.
Advantage:
The list of articles are always updated, so any deleted articles are removed and inserted new articles are shown.
The tree-like hierarchy visually shows all the available articles and their relationships with one another. This visual depiction is far, far better than the default's which is hard to even know how many articles exist or how far deep articles are nested.
Disadvantage:
According to the django-wiki's source code, get_descendents method is an expensive call, but for my small site, I have not noticed any penalty hits (so far).
Assuming your structure is no more than 10 deep:
[article_list depth:10]
Put this in your root article.

Pelican Archives Not Displaying

How do you enable an archives tab on a pelican powered blog?
I see from the docs that it is a direct template by default, but it isn't showing up on my blog. Is there some additional field to enable it? I couldn't find any mention of it in the docs or tutorials, so I'm assuming I've missed something obvious.
Not sure if you ever resolved this; I was having the same issue as you with pelican's bootstrap3 theme. For some reason, setting a value for YEAR_ARCHIVE_SAVE_AS was not working.
After looking at the theme's base.html file, I got it working by adding the following to pelicanconf.py:
ARCHIVES_SAVE_AS = 'archives.html'
Lines 156-158 from my base.html file:
{% if ARCHIVES_SAVE_AS %}
<li><i class="fa fa-th-list"></i><span class="icon-label">{{ _('Archives') }}</span></li>
{% endif %}

django philosophy: when to include templates and when to have code generate html?

When using Django templates, should I have some templates that act like "subroutines", so to speak, or should I generate HTML from within my code in these cases?
For example, I have a template with several lists of names, each of which I want to turn into a select. Should I have a template that renders the name_list variable into a select, and do something like this:
#in the view:
return {'name_list_1': name_list_1,
'name_list_2': name_list_2,
'name_list_3': name_list_3}
#in the template:
{% with name_list_1 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
{% with name_list_2 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
{% with name_list_3 as name_list %}
{% include "sub_name_list_select.html" %}
{% endwith %}
Or should I have a function in my code, name_list_to_select_html, which does the same job, and do this:
return {'name_list_1_html': name_list_to_select_html(name_list_1),
'name_list_2_html': name_list_to_select_html(name_list_2),
'name_list_3_html': name_list_to_select_html(name_list_3)}
#in the template:
{{ name_list_1_html|safe }}
{{ name_list_2_html|safe }}
{{ name_list_3_html|safe }}
Or are both of these wrong and I am getting the philosophy totally wrong?
Additional question: in terms of speed, is it slow to constantly include templates? Is that a bonus point for the in-code html generation?
Generally, HTML should only be generated in the templating system or directly related code. That keeps the view of the data completely separate from the business and functional logic. I feel that's a proper separation of concerns. Go with your first solution.
As for performance, Django should probably take around the same amount of time running either code. But it has built-in view and template fragment caching if you know those segments of code don't need to be regenerated on every request.

Categories

Resources