getpelican / pelican

Static site generator that supports Markdown and reST syntax. Powered by Python.
https://getpelican.com
GNU Affero General Public License v3.0
12.58k stars 1.81k forks source link

How to get access to both 'articles_page' and 'page' variable at the same time? #2280

Closed jfcherng closed 6 years ago

jfcherng commented 6 years ago

Environment

My Goal

I would like to have the following two things in my rendered index.html.

My Thought

I make a custom template (custom/index_with_content_top.html) and use :template: in the .rst file (pages/index.rst) to render it with the custom template.

Problems

Pelican reports CRITICAL: UndefinedError: 'articles_page' is undefined. After some survey, it looks like that in my pelicanconf.py, I have to add 'custom/index_with_content_top' into DIRECT_TEMPLATES and PAGINATED_DIRECT_TEMPLATES to get access to articles_page. But after adding, the page variable is no longer available in 'custom/index_with_content_top'. Pelican reports CRITICAL: UndefinedError: 'page' is undefined.

If my thought is impractical, is there another way to achieve my goal?

Source Codes

pages/index.rst:

:date: 2013-02-20
:title: My Index
:template: custom/index_with_content_top
:save_as: index.html

Page Content
============

Hello World!

custom/index_with_content_top.html:

{% extends "base.html" %}

{% block content %}
  <div class="row">
    <div class="col-md-12">
      <div class="main-section page-content">
        {{ page.content }}                                <--- here uses 'page'
      </div>
    </div>
    <div class="col-md-12">
      {% include 'component/latest_articles.html' %}      <--- here uses 'articles_page' inside
    </div>
  </div>
{% endblock content %}
avaris commented 6 years ago

articles_page is available for templates in PAGINATED_DIRECT_TEMPLATES. So, the way you want to use page here is not possible. Putting it in paginated as well as :template: will cause it to be rendered twice: once with page and once with articles_page but neither will have both at the same time.

A way to achieve it would be putting the content in a regular (or maybe hidden) page with a custom flag metadata and looping it over there:

page

:date: 2013-02-20
:title: My Index
:front: true
:status: hidden

Page Content
============

Hello World!

template

{% extends "base.html" %}

{% block content %}
  <div class="row">
    <div class="col-md-12">
      <div class="main-section page-content">
      {% for page in hidden_pages %}
        {% if page.front == "true" %}
        {{ page.content }}
        {% endif %}
      {% endfor %}
      </div>
    </div>
    <div class="col-md-12">
      {% include 'component/latest_articles.html' %}
    </div>
  </div>
{% endblock content %}
jfcherng commented 6 years ago

@avaris That's smart and it works like a charm! Thank you!