Configuration

Custom model for tree pages

To build a tree, using the model from sqlalchemy_mptt.

Note

Otherwise, it will look like flat pages.
Plans to add a recursive model with only parent_id field.

Create model of tree pages. For more detail see example pyramid_pages_example.

from pyramid_pages.models import FlatPageMixin, MpttPageMixin, RedirectMixin

...

class WebPage(Base, MpttPageMixin, RedirectMixin):
    __tablename__ = 'mptt_pages'

    id = Column('id', Integer, primary_key=True)


class NewsPage(Base, FlatPageMixin):
    __tablename__ = 'flat_news'

    id = Column('id', Integer, primary_key=True)
    date = Column(Date, default=func.now())

If you use pyramid_sacrud, you can inherited from BaseSacrudMpttPage or BaseSacrudFlatPage or just use SacrudOptions.

It’s look likes this:

Integration pyramid_pages with pyramid_sacrud

Configure pyramid_pages

Then add settings of pyramid_pages.

from youproject.models import WebPage, NewsPage

...

settings['pyramid_pages.models'] = {
   '': WebPage,
   'pages': WebPage,  # available with prefix '/pages/'
   'news': NewsPage
}

# pyramid_pages - put it after all routes
# and after pyramid_pages configuration.
config.include("pyramid_pages")

If you use version of pyramid >= 1.6a1, there is a possibility put config.include("pyramid_pages") before pyramid_pages Configuration.

from youproject.models import WebPage, NewsPage

...

config.include("pyramid_pages")
settings['pyramid_pages.models'] = {
   '': WebPage,
   'pages': WebPage,  # available with prefix '/pages/'
   'news': NewsPage
}

Custom resource

Base resource for pages can be found in the module pyramid_pages.routes.

Just inherit your resource from PageResource.

Custom resource for gallery.
1
2
3
class GalleryResource(BasePageResource):
    model = Gallery
    template = 'gallery/index.jinja2'
Model for GalleryResource.
1
2
3
4
5
6
7
8
class Gallery(BasePage, MpttPageMixin):
    __tablename__ = 'mptt_gallery'

    id = Column(Integer, ForeignKey('base_pages.id'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'gallery_page',
    }
Model photo for Gallery.
1
2
3
4
5
6
7
class Photo(Base):
    __tablename__ = 'photos'

    id = Column('id', Integer, primary_key=True)
    path = Column('path', Text)
    gallery_id = Column(Integer, ForeignKey('mptt_gallery.id'))
    gallery = relationship('Gallery', backref='photos')

And add it to config.

settings['pyramid_pages.models'] = {
   '': WebPage,
   'pages': WebPage,  # available with prefix '/pages/'
   'news': NewsPage,
   'gallery': GalleryResource
}

Generate menu

Make menu object and pass it in template context.

from pyramid_pages.common import Menu


class Gallery(Base, MpttPageMixin):
    __tablename__ = 'mptt_gallery'

    menu_template = 'myproject/templates/my_custom_menu.mako'

    id = Column('id', Integer, primary_key=True)

page_menu = Menu(DBSession, WebPage).mptt
news_menu = Menu(DBSession, NewsPage).flat
gallery_menu = Menu(DBSession, Gallery).mptt

Just include menu template.

{% with menu=news_menu() %}
  {% include menu.template with context %}
{% endwith %}

{% with menu=page_menu(from_lvl=1, to_lvl=6, trees=(1, 2, 3)) %}
  {% include menu.template with context %}
{% endwith %}

Or write your own.

Flat menu template.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<div class="main-menu-list">
    {% for node in menu %}
        <div class="main-menu-list__item
                {% if node == context.node or node == page %}
                  main-menu-list__item_state_current
                {% endif %}">
            <a href="{{ request.resource_url(context.resource_of_node(node)) }}"
              class="main-menu-list__item-link">
              {{ node.name }}
            </a>
        </div>
    {% endfor %}
</div>
MPTT menu template.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<div class="main-menu-list">
  {% for resource in menu if resource.node.in_menu and resource.node.visible recursive %}
    <div class="main-menu-list__item
            {% for item in lineage(context) if item and item.node==resource.node %}
                main-menu-list__item_in_current_branch
            {% endfor %}
            {% if resource.node == context.node or resource.node == page %}
              main-menu-list__item_state_current
            {% endif %}
            {% if resource.children_qty %}
              main-menu-list__item_state_has-child
            {% endif %}">
      <a href="{{ request.resource_url(resource) }}"
        class="main-menu-list__item-link">
        {{ resource.node.name }}
      </a>
      <div class="main-menu-list">{{ loop(resource.children) }}</div>
    </div>
  {% endfor %}
</div>

If you want show mptt menu with to_lvl==max-2 or similar, just use to_lvl=-2.

{% with menu=page_menu(from_lvl=1, to_lvl=-2, trees=(1, 2, 3)) %}
  {% include menu.template with context %}
{% endwith %}