Templates

Default site

core/home.html

Websauna default homepage.

This page is only visible when developing Websauna core or running unit tests against it. Websauna applications always supply their own homepage.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
{# Websauna default homepage.

This page is only visible when developing Websauna core or running unit tests against it. Websauna applications always supply their own homepage.
 #}
{% extends "site/base.html" %}

{% block content %}

    <!-- Header -->
    <header>
        <div class="jumbotron text-center">
            <h1 id="front-page-title">{{site_name}}</h1>
            <p class="lead text-center">
                <span class="lead-inner">{{site_tag_line}}</span>
            </p>
        </div>
    </header>

    <section id="sign-up">
        <div class="row">
            <div class="col-lg-12">
                <p class="text-center lead">
                    <div class="alert alert-danger">
                      If you are seeing this text it means you are developing Websauna itself, you are running Websauna unit tests or you have messed up app:main entry point for your application and it loads default Websauna home.
                    </div>
                </p>
            </div>
        </div>
    </section>

    <section id="features">
        <div class="container marketing">

            <div class="row text-center">

                <div class="col-md-4 col-sm-6">

                    <!-- Left -->
                    <div class="entry">
                        <span class="fa-stack fa-4x">
                            <i class="fa fa-circle fa-stack-2x text-primary"></i>
                            <i class="fa fa-heart fa-stack-1x fa-inverse"></i>
                        </span>
                        <h4>You chose Python</h4>
                        <p>Cutting edge programming language</p>
                    </div>

                    <div class="entry">
                        <span class="fa-stack fa-4x">
                            <i class="fa fa-circle fa-stack-2x text-primary"></i>
                            <i class="fa fa-facebook fa-stack-1x fa-inverse"></i>
                        </span>
                        <h4>Easy sign ups</h4>
                        <p>Your uses can sign up using Facebook, Github or other social media accounts.</p>
                    </div>
                </div>

                <!-- Middle -->
                <div class="col-md-4 col-sm-6">

                    <div class="entry">
                        <span class="fa-stack fa-4x">
                            <i class="fa fa-circle fa-stack-2x text-primary"></i>
                            <i class="fa fa-database fa-stack-1x fa-inverse"></i>
                        </span>
                        <h4>Runs on PostgreSQL</h4>
                        <p>Most advanced open source database available today</p>
                    </div>

                    <div class="entry">
                        <span class="fa-stack fa-4x">
                            <i class="fa fa-circle fa-stack-2x text-primary"></i>
                            <i class="fa fa-lock fa-stack-1x fa-inverse"></i>
                        </span>
                        <h4>Secure</h4>
                        <p>Ships with very secure defaults.</p>
                    </div>
                </div>

                <!-- Right -->
                <div class="col-md-4">

                    <div class="entry">
                        <span class="fa-stack fa-4x">
                            <i class="fa fa-circle fa-stack-2x text-primary"></i>
                            <i class="fa fa-globe fa-stack-1x fa-inverse"></i>
                        </span>
                        <h4>Internationalization</h4>
                        <p>Spean many languages through GNU gettext</p>
                    </div>

                    <div class="entry">
                        <span class="fa-stack fa-4x">
                            <i class="fa fa-circle fa-stack-2x text-primary"></i>
                            <i class="fa fa-eye fa-stack-1x fa-inverse"></i>
                        </span>
                        <h4>It's beautiful</h4>
                        <p>Easy theming with industry standard Bootstrap layout and FontAwesome icons</p>
                    </div>
                </div>
            </div>
        </div>
    </section>



{% endblock %}

core/notfound.html

404 page

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{# 404 page #}

{# We cannot extend extend base.html as we do not want to touch any session'y stuff in special views. We do this to avoid session conflicts when browsers fetch requests and may have race condition e.g. with missing favicon.ico #}
{% extends "site/base_compact.html" %}

{# TODO: Not sure if we should extend base_compact.html here so that we would have more protection against having state variables on 404 page #}

{% block body %}

    <main>
        <section id="it-is-broken">
            <div class="container">
                <div class="row">
                    <div class="col-md-12">
                      <div id="not-found">
                          <h1>Not found</h1>

                          <p>
                              Nothing in this URL. Are you sure the address is correct?
                          </p>

                          <p>
                            <a href="{{ request.application_url }}">View site front page.</a>
                          </p>
                      </div>
                    </div>
                  </div>
              </div>
          </section>
    </main>

{% endblock %}

core/timestruct.html

Render a datetime.

Render absolute timestamp and relative friendly timestamp for it.

User by websauna.system.core.templatecontext.friendly_time().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{# Render a datetime.

Render absolute timestamp and relative friendly timestamp for it.

User by :py:func:`websauna.system.core.templatecontext.friendly_time`.
#}
<div class="friendly-time">
    {{ time|friendly_time() }}
</div>

<div class="unfriendly-time">
    {{ time|datetime(format=format, target_timezone=timezone, locale="en_US", show_timezone=show_timezone) }}
</div>

core/interstitial_form.html

Interstital promps like yes/no screens snippet.

It is usually used in a situations like delete confirmations (yes/no) or password confirmations (ask password for security reasons before the action can continue).

See websauna.system.form.interstitial for more information.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{# Interstital promps like yes/no screens snippet.

It is usually used in a situations like delete confirmations (yes/no) or password confirmations (ask password for security reasons before the action can continue).

See :py:mod:`websauna.system.form.interstitial` for more information.
#}

<form method="POST">
  <input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}">
  {% for choice in choices  %}
    <button type="submit" id="{{ choice.id }}" name="{{ choice.id }}" class="{{ choice.css_class or 'btn btn-default' }}">
      {% if choice.icon_class %}
        <i class="{{ choice.icon_class }}"></i>
      {% endif %}
      {{ choice.label }}
    </button>
  {% endfor %}
</form>

core/forbidden.html

HTTP 403 - when the view raises pyramid.httpexceptions.HttpForbidden

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{# HTTP 403 - when the view raises pyramid.httpexceptions.HttpForbidden #}

{% extends "site/base.html" %}

{% block content %}
    <div id="forbidden">
        <h1>Forbidden</h1>

        <p>
            Whoopsie. You do not have permission to access this page. 
        </p>
    
        {% if not request.user %}
            <p>
                <a href="{{'login'|route_url}}">Login first?</a>
            </p>
        {% endif %} 
    </div>
{% endblock %}

core/internalservererror.html

HTTP 500 error

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{# HTTP 500 error #}
{% extends "site/base_compact.html" %}

{# We will in the whole body as we do not want to have anything in templates raising further exceptions #}
{% block body %}
    <main>
        <section id="it-is-broken">
            <div class="container">
                <div class="row">
                    <div class="col-md-12">

                        <div>
                            <h1 class="text-center">It didn't work.</h1>

                            {#

                                Hotlinking should be cool by WikiMedia:

                                http://commons.wikimedia.org/wiki/Commons:Reusing_content_outside_Wikimedia#Hotlinking_or_InstantCommons

                             #}
                            <p class="text-center">
                                <img class="img-thumbnail img-responsive" src="http://upload.wikimedia.org/wikipedia/commons/a/a4/Volcano_q.jpg" alt="">
                            </p>

                            <p class="text-center">
                                The click you just made did not exactly go as planned: something became smoldering ashes.
                                Our administrators are running to the server room to see what this smoke is all about. But don't worry.
                                Everybody in our team is alerted. We'll get this fixed shortly.
                            </p>

                            <p class="text-center">
                                <small>
                                    <a href="https://commons.wikimedia.org/wiki/Lava#/media/File:Volcano_q.jpg">Image by WikiMedia Commons</a>
                                </small>
                            </p>
                        </div>

                    </div>
                </div>
            </div>
        </section>
    </main>
{% endblock %}

core/badcsrftoken.html

Do Bad CSRF page. Do not have full framing as this page may appear inside <iframe>

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{# Do Bad CSRF page. Do not have full framing as this page may appear inside <iframe> #}
{% extends "site/base_compact.html" %}

{% block body %}
    <main>
        <section id="it-is-broken">
            <div class="container">
                <div class="row">
                    <div class="col-md-12">

                        <div>
                            <h1 id="heading-bad-csrf-token" class="text-center">Form submission error</h1>

                            <p>
                              Cross site request forgery check failed.
                            </p>

                            <p>
                              <strong>Try refreshing the page.</strong>
                            </p>


                            <p>
                              Things that might cause this error include
                            </p>

                          <ul>
                              <li>Browser cookies have been turned off</li>
                              <li>Browser addon that blocks cookies</li>
                              <li>Network connectivity issues</li>
                            </ul>

                            <p>
                              Form submission is denied. This server can not verify that your cross-site request forgery token belongs to your login session. Either you supplied the wrong cross-site request forgery token or your session no longer exists. This may be due to session timeout or because browser is not supplying the credentials required, as can happen when the browser has cookies turned off.
                            </p>

                        </div>

                    </div>
                </div>
            </div>
        </section>
    </main>
{% endblock %}

core/sitemap.xml

Google sitemap

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{# Google sitemap #}
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% for url in urlset %}
  <url>
    {% set lastmod=url.lastmod(request) %}
    {% set location=url.location(request) %}
    {% set changefreq=url.changefreq(request) %}
    {% set priority=url.priority(request) %}
    <loc>{{ location }}</loc>
    {% if lastmod %}<lastmod>{{ lastmod }}</lastmod>{% endif %}
    {% if changefreq %}<changefreq>{{ changefreq }}</changefreq>{% endif %}
    {% if priority %}<priority>{{ priority }}</priority>{% endif %}
   </url>
{% endfor %}
</urlset>

site/meta.html

Misc <meta> tags in <head>.

1
2
3
{# Misc ``<meta>`` tags in ``<head>``. #}
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width" />

site/base.html

Site default framing and blocks from <html> to </html>

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
{# Site  default framing and blocks from <html> to </html> #}
<!DOCTYPE html>
<html lang="en">

<head>

    {% block description %}
        {% include "site/description.html" %}
    {% endblock description %}

    {% block meta %}
        {% include "site/meta.html" %}
    {% endblock meta %}

    {% block css %}
        {% include "site/css.html" %}
    {% endblock %}

    {% block head_script %}
        {% if js_in_head %}
          {% include "site/javascript.html" %}
        {% endif %}
    {% endblock %}

    {% block extra_head %}
        {# Pages can register their page specific CSS/JS here #}
    {% endblock %}

</head>

{# body_classes allows to insert extra CSS classes on <body> tag #}
<body
    {% block body_classes %}
    {% endblock body_classes %}
    >

    {# body block contains the whole page without a navigation frame and the analytics script #}
    {% block body %}

        {# Navigation #}
        {% block header %}
            {% include "site/header.html" %}
        {% endblock header %}

        {# main is the content without margins and flash messages #}
        {% block main %}
            <main>

                <div class="messages">
                    {% block messages %}
                        {% include "site/messages.html" %}
                    {% endblock messages %}
                </div>

                {# content is the content with margins #}
                <div class="container">
                    {% block content %}
                    {% endblock content %}
                </div>
            </main>
        {% endblock main %}

        {% block footer %}
            {% include "site/footer.html" %}
        {% endblock footer %}

        {% block body_end %}
        {% endblock body_end %}

        {# script is shared site JavaScript #}
        {% block body_end_script %}
            {% if not js_in_head %}
              {% include "site/javascript.html" %}
            {% endif %}
        {% endblock body_end_script %}

        {# extra_body_end is page specific JavaScript #}
        {% block extra_body_end %}
        {% endblock extra_body_end %}

    {% endblock body %}

    {# analytics is tracking JavaScript #}
    {% block analytics %}
        {% include "site/analytics.html" %}
    {% endblock analytics %}

</body>
</html>

site/css.html

CSS files on every page of the site.

Load

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{# CSS files on every page of the site.

Load

* :term:`Bootstrap` 3.x

* Websauna core CSS styles (e.g. navbar logout button style fixes)

* :term:`Font Awesome` from :term:`CDN`
#}

{# CDN'ed version #}
{#
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
 #}
<link rel="stylesheet" href="{{ 'websauna.system:static/bootstrap.min.css'|static_url }}">
<link rel="stylesheet" href="{{ 'websauna.system:static/theme.css'|static_url }}">
<link href="//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">

{% if request.on_demand_resource_renderer %}
  {% for css_url in request.on_demand_resource_renderer.get_resources("css") %}
    <link rel="stylesheet" href="{{ css_url }}"></link>
  {% endfor %}
{% endif %}

site/javascript.html

Load JavaScript files.

The include location of this template may alter between <head> and the end of <body>.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{# Load JavaScript files.

The include location of this template may alter between ``<head>`` and the end of ``<body>``.
#}

<script src="{{ 'websauna.system:static/jquery-3.1.1.min.js'|static_url }}"></script>
<script src="{{ 'websauna.system:static/bootstrap.min.js'|static_url }}"></script>

{# Pull JS for widgets #}
{% if request.on_demand_resource_renderer %}
  {% for js_url in request.on_demand_resource_renderer.get_resources("js") %}
    <script src="{{ js_url }}"></script>
  {% endfor %}
{% endif %}

site/logo.html

Site logo inside navigation bar.

1
2
3
4
{# Site logo inside navigation bar. #}
<a class="navbar-brand" href="{{'home'|route_url}}">
    Websauna
</a>

site/description.html

Site title and description in <head>.

1
2
3
4
5
6
7
8
{# Site title and description in <head>. #}
{% if site_title %}
    <title>{{site_title}}</title>
{% endif %}

{% if site_description %}
    <meta name="description" content="{{site_description}}">
{% endif %}

site/messages.html

Flash messages as Bootstrap alerts.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{# Flash messages as Bootstrap alerts. #}

{% set queues = ['error', 'warning', 'info', 'success', ''] %}

{# Bootstrap 3.x alert classes mapped to error levels #}
{% set visuals = {'error': 'danger'} %}

{% for queue in queues %}
     {% with messages = request.session.pop_flash(queue) %}
        {% for msg in messages %}
            {% if msg.kind %}
                <div {% if msg.msg_id %}id="{{ msg.msg_id }}"{% endif %} class="alert alert-{{ visuals.get(msg.kind, msg.kind) }}">
                    {% if msg.rich %}
                      {{ msg.rich|safe }}
                    {% else %}
                      {{ msg.plain }}
                    {% endif %}
                </div>
            {% else %}
                <div {% if msg.msg_id %}id="{{ msg.msg_id }}"{% endif %} class="alert alert-danger">
                    {% if msg.rich %}
                      {{ msg.rich|safe }}
                    {% else %}
                      {{ msg.plain }}
                    {% endif %}
                </div>
            {% endif %}
        {% endfor %}
    {% endwith %}
{% endfor %}

site/base_compact.html

Alternative <html>…</html> framing without header and footer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
{# Alternative <html>...</html> framing without header and footer. #}
<!DOCTYPE html>
<html lang="en">

{# Base template which does not use any request context information and is safe to use on error pages #}

<head>

  {% block meta %}
    {# Include or override default <meta> tags #}
    {% include "site/meta.html" %}
  {% endblock meta %}

  {% block css %}
    {# Include or override default CSS head #}
    {% include "site/css.html" %}
  {% endblock %}

  {% block custom_head %}
    {# A block where the template extending this base tempplate can drop in more ``<head>`` elements. #}
  {% endblock %}

</head>

<body>
    {% block body %}
      {#  This block covers everything between ``<body>...</body>`` #}

      <main>

          {# content is the content with margins #}
          <div class="container">
              {% block content %}
              {% endblock content %}
          </div>
      </main>

      {# analytics is tracking JavaScript #}
      {% block analytics %}
          {% include "site/analytics.html" %}
      {% endblock analytics %}

    {% endblock body %}

</body>
</html>

site/analytics.html

Google Analytics and other JavaScript snippets at the bottom of <body>.

1
{# Google Analytics and other JavaScript snippets at the bottom of ``<body>``. #}

site/header.html

Site header

1
2
3
4
5
6
{# Site header #}
<div id="header-outer">
    <header>
        {% include "site/nav.html" %}
    </header>
</div>

email/base.html

HTML email framing

Based on a template by Lee Munroe

Takes in template context variable email_css that is a template name for CSS code to be included within <style>...</style> block.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
{# HTML email framing

Based on a template by Lee Munroe

* https://github.com/leemunroe/responsive-html-email-template

Takes in template context variable ``email_css`` that is a template name for CSS code to be included within ``<style>...</style>`` block.
#}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTMlsL 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>{{subject}}</title>


{% if email_css %}
  <style>
    {% include email_css %}
  </style>
{% else %}
  <style>
    {% include "email/email.css" %}
  </style>
{% endif %}
{% block extra_head %}
{% endblock %}
</head>

<body bgcolor="#dadada">



<!-- body -->
<table class="body-wrap">
    <tr>
        <td></td>
        <td class="container" bgcolor="#f0f0f0">

            <!-- content -->
            <div class="content">
            <table>
                {% block header %}
                  {% include "email/header.html" %}
                {% endblock %}
                <tr>
                    <td>
                        {% block content %}
                        ...
                        {% endblock content %}
                    </td>
                </tr>
            </table>
            </div>
            <!-- /content -->
        </td>
        <td></td>
    </tr>
</table>
<!-- /body -->

{% block footer %}
{% include "email/footer.html" %}
{% endblock %}


</body>
</html>

email/base_subject.txt

Plain text email subject

1
2
{# Plain text email subject #}
[{{ site_name }}] {% block subject %}{% endblock %}

email/header.html

HTML email header.

Note

If you wish to use the company logo here, so that it actually shows up in the opened email, don’t serve it from your own server. Instead upload the logo to Google Drive and hot link it there. GMail and other email applications are little bit picky where they allow images come from.

For raw <img src> link translate the Google Drive sharing link. From:

https://drive.google.com/file/d/0B6nei6GpGxGsb1hnWHlBRFJhxxx/view?usp=sharing

To:

https://drive.google.com/uc?id=0B6nei6GpGxGsb1hnWHlBRFJhxxx
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{# HTML email header.

.. note ::

  If you wish to use the company logo here, so that it actually shows up in the opened email, don't serve it from your own server. Instead upload the logo to Google Drive and hot link it there. GMail and other email applications are little bit picky where they allow images come from.

For raw ``<img src>`` link translate the Google Drive sharing link. From::

  https://drive.google.com/file/d/0B6nei6GpGxGsb1hnWHlBRFJhxxx/view?usp=sharing

To::

  https://drive.google.com/uc?id=0B6nei6GpGxGsb1hnWHlBRFJhxxx

#}
<tr>
    <td class="right-align">
        <h2><a href="{{ 'home'|route_url }}">{{ site_name }}</a></h2>
    </td>
</tr>

email/base.txt

Plain text email framing

1
2
3
{# Plain text email framing #}
{% block content %}{% endblock content %}
{% block footer %} {% include "email/footer.txt" %}{% endblock footer %}

Admin

admin/menu/navbar.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<nav class="navbar navbar-default {% if entry.css_class %}{{ entry.css_class }}{% endif %}">

    <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#header-{{ entry.id }}">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar icon-bar-red"></span>
            <span class="icon-bar icon-bar-gold"></span>
            <span class="icon-bar icon-bar-green"></span>
        </button>

        {% if entry.label %}
            <a class="navbar-brand" href="{{ entry.get_link(request) }}">
                {{ entry.label }}
            </a>
        {% endif %}
    </div>

    <div class="collapse navbar-collapse" id="header-{{ entry.id }}">
        {% if entry.submenu and entry.submenu.has_items(request) %}
            <ul class="nav navbar-nav">

                {% for subentry in entry.submenu.get_entries() %}
                    {% if subentry.is_enabled(request) %}
                        {{ subentry.render(request)|safe }}
                    {% endif %}
                {% endfor %}
            </ul>
        {% endif %}
    </div>

</nav>

admin/menu/submenu.html

Conditionally render a nested menu inside a menu entry if needed

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{# Conditionally render a nested menu inside a menu entry if needed #}
{% if entry.submenu and entry.submenu.has_items(request) %}
    <ul class="dropdown-menu" aria-labelledby="{{ entry.id }}">

        {% for subentry in entry.submenu.get_entries() %}
            {% if subentry.is_enabled(request) %}
                {{ subentry.render(request)|safe }}
            {% endif %}
        {% endfor %}
    </ul>
{% endif %}

admin/menu/entry.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<li>
    <a id="{{ entry.id }}" href="{{entry.get_link(request)}}" {% if entry.submenu %}class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"{% endif %}>

        {# More information about icon placeholders http://jsfiddle.net/tagliala/7z9b557v/ and https://github.com/FortAwesome/Font-Awesome/wiki/Troubleshooting#need-a-blankempty-icon #}
        <i class="fa fa-fw {{ entry.icon }}"></i>
        {{ entry.label }}

        {% if entry.submenu and entry.submenu.has_items(request) %}
            <span class="{{ entry.caret }}"></span>
        {% endif %}
    </a>

    {% include "admin/menu/submenu.html" %}
</li>

admin/admin.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{% extends "admin/base.html" %}

{% block admin_content %}
<div id="admin-main">
    <h1>{{site_name}} Admin</h1>
</div>

<div class="row">
    <div class="col-md-12">
        {% for panel in panels %}
            {{panel|safe}}
        {% endfor %}
    </div>
</div>
{% endblock admin_content %}

admin/model_panel.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{% extends "admin/base_panel.html" %}

{% block panel_title %}
{{ title }} <span class="text-muted">({{count}})</span>
{% endblock panel_title %}

{% block panel_content %}
{% endblock panel_content %}

{% block panel_buttons %}
    {% if controls %}
        {% if request.has_permission('view', context) %}
            <a id="btn-panel-list-{{ model_admin.__name__ }}" class="btn btn-default btn-admin-list" href="{{ request.resource_url(model_admin, 'listing') }}">
                List
            </a>
        {% endif %}


        {% if request.has_permission('add', context) %}
            <a id="btn-panel-add-{{ model_admin.__name__ }}" class="btn btn-default btn-admin-list" href="{{ request.resource_url(model_admin, 'add') }}">
                Add
            </a>
        {% endif %}
    {% endif %}
{% endblock %}

admin/base.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{% extends "site/base.html" %}

{% block content %}

    {# Navbar menu #}
    {{ request.admin.get_admin_menu_entry().render(request)|safe }}

    {{context|admin_breadcrumbs|safe}}

    {% block admin_content %}
    {% endblock admin_content %}

    {% block crud_content %}
    {% endblock crud_content %}

{% endblock content %}

{% block extra_body_end %}
  <script src="{{ 'websauna.system:static/admin.js'|static_url }}"></script>
{% endblock %}

admin/base_panel.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div id="admin-panel-{{ model_admin.__name__ }}" class="panel panel-default panel-admin">
    {% block panel_heading%}
        <div class="panel-heading clearfix">

            <h3 class="panel-title pull-left">
                {% block panel_title %}
                    {{title}}
                {% endblock %}
            </h3>

            <div class="panel-buttons pull-right">
                {% block panel_buttons %}
                {% endblock panel_buttons %}
            </div>
        </div>
    {% endblock panel_heading %}

  <div class="panel-body">
        {% block panel_content %}
        {% endblock panel_content %}
  </div>

</div>

admin/breadcrumbs.html

Override spot for admin specific breadcrumbs.

If not overridden fall back to the default breacrumbs.

1
2
3
4
5
{# Override spot for admin specific breadcrumbs.

If not overridden fall back to the default breacrumbs.
#}
{% include "site/breadcrumbs.html" %}

CRUD

crud/resource_controls.html

Resource-specific actions bar rendered at the top of each page

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{# Resource-specific actions bar rendered at the top of each page #}
<div id="crud-page-controls clearfix">

    <div id="crud-page-buttons" class="pull-right">
        {% for button in resource_buttons %}
            {% if button.is_visible(context, request) %}
                {{ button.render(context, request)|safe }}
            {% endif %}
        {% endfor %}
    </div>

</div>

crud/column_header_controls.html

— description missing —

1
2
3
<th class="crud-column-{{column.id}} text-right">
    {{ column.name }}
</th>

crud/show.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{% extends base_template %}

{% block description %}
    <title>{{ title }}</title>
{% endblock description %}

{% block crud_content %}

  <div id="crud-show">
    {% include "crud/resource_controls.html" %}
    {% if title %}
        <h1>{{title}}</h1>
    {% endif %}

    {{form|safe}}
  </div>
{% endblock crud_content %}

crud/column_body.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<td class="crud-column-{{column.id}}">

    {% with target=column.get_navigate_url(instance, request), value=column.get_value(view, obj)  %}
        {% if target %}
            <a href="{{target}}">
                {{ value }}
            </a>
        {% else %}
            {{ value }}
        {% endif %}
    {% endwith %}
</td>

crud/base.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{% extends "site/base.html" %}

{# All pages showing CRUD content must define this block #}

{% block content %}
  {# We put CRUD content to base content block by default #}

  {% block crud_content %}
    {# crud_content block tells where you want the CRUD to appear on your page #}
  {% endblock %}
{% endblock %}

crud/add.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{% extends base_template %}

{% block description %}
    <title>{{ title }}</title>
{% endblock description %}

{% block crud_content %}

    {% include "crud/resource_controls.html" %}

    {% if title %}
        <h1>{{title}}</h1>
    {% endif %}

    {{form|safe}}
{% endblock crud_content %}

crud/listing.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{% extends base_template %}

{% block crud_content %}

    {% block title %}
        {# Page title and any content around it #}
        {% if title %}
            <h1>{{title}}</h1>
        {% endif %}
    {% endblock %}

    {% block controls %}
        {# Top control bar with buttons #}
        <div class="row">
            <div class="col-md-12">
               {% include "crud/resource_controls.html" %}
            </div>
        </div>
    {% endblock controls %}

    {% block listing %}
        {# List all CRUD items in a table #}
        {% if count %}
            <div class="table-responsive">
                <table class="table listing listing-{{crud.id}}">
                    <thead>
                        {% for column in columns %}
                            {%  include column.header_template %}
                        {% endfor %}
                    </thead>

                    <tbody>
                        {% for obj in batch %}
                            <tr class="crud-row crud-row-{{ obj.id }}">
                                {% with instance=crud.wrap_to_resource(obj) %}
                                    {% for column in columns  %}
                                        {% include column.body_template %}
                                    {% endfor %}
                                {% endwith %}
                            </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        {% endif %}
    {% endblock %}

    {% block count %}
        {# Display total count of items #}
        <div class="row">
            <div class="col-md-12 text-muted text-center">

            {% if not count %}
                <p id="crud-listing-no-items">
                    No items
                </p>
            {% else %}

                <div id="crud-listing-count">
                    Total {{count}} items
                </div>
            {% endif %}
            </div>
        </div>
    {% endblock %}

    {% block paginator %}
        {% include "crud/paginator.html" %}
    {% endblock %}
{% endblock crud_content %}

crud/column_body_friendly_time.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<td class="crud-column-{{column.id}}">

    {% with target=column.get_navigate_url(instance, request) %}
        {% if target %}
            <a href="{{target}}">

                <div class="friendly-time">
                    {{ column.get_value(view, obj)|friendly_time() }}
                </div>

                <div class="unfriendly-time">
                    <small>
                        {{ column.get_value(view, obj)|datetime(format=column.format, target_timezone=column.timezone, locale="en_US", show_timezone=True) }}
                    </small>
                </div>

            </a>
        {% else %}
            <div class="friendly-time">
                {{ column.get_value(view, obj)|friendly_time() }}
            </div>

            <div class="unfriendly-time">
                <small>
                    {{ column.get_value(view, obj)|datetime(format=column.format, target_timezone=column.timezone, locale="en_US", show_timezone=True) }}
                </small>
            </div>
        {% endif %}
    {% endwith %}
</td>

crud/edit.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{% extends base_template %}

{% block description %}
    <title>{{ title }}</title>
{% endblock description %}

{% block crud_content %}

    {% include "crud/resource_controls.html" %}

    {% if title %}
        <h1>{{title}}</h1>
    {% endif %}

    {{form|safe}}
{% endblock crud_content %}

crud/paginator.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<div class="pagination-wrapper">
    {% if not batch.required %}
        <div class="total-message total-message-only text-center">
            {{ batch.seqlen }} entries total
        </div>
    {% endif %}

    {% if batch.required %}
        <div class="text-center">
            <div class="label label-primary">
                Page #{{ batch.num+1 }} ({{ '%d-%d of %d' % (batch.startitem+1, batch.enditem+1, batch.seqlen) }})
            </div>
        </div>
    {% endif %}

    {% if batch.required %}
        <ul class="pager pager-compact">
            <li class="{% if not batch.first_url %}disabled{% endif %}">
                <a href="{{ batch.first_url or 'javascript:void(0)' }}">
                    <i class="fa fa-angle-double-left"></i> First
                </a>
            </li>

            <li class="{% if not batch.prev_url %}disabled{% endif %}">
                <a href="{{ batch.prev_url or 'javascript:void(0)' }}">
                    <i class="fa fa-angle-left"></i> Previous
                </a>
            </li>

            <li class="{% if not batch.next_url %}disabled{% endif %}">
                <a href="{{ batch.next_url or 'javascript:void(0)' }}">
                    Next <i class="fa fa-angle-right"></i>
                </a>
            </li>

            <li class="{% if not batch.last_url %}disabled{% endif %}">
                <a href="{{ batch.last_url or 'javascript:void(0)' }}">
                    Last <i class="fa fa-angle-double-right"></i>
                </a>
            </li>
        </ul>
    {% endif %}
</div>

crud/column_header.html

— description missing —

1
2
3
<th class="crud-column-{{column.id}}">
    {{ column.name }}
</th>

crud/resource_button.html

Link based button in the admin interface.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{# Link based button in the admin interface. #}
<a
  id="btn-crud-{{ button.id }}"
  class="btn btn-default"
  rel="nofollow"
  href="{{ button.get_link(context, request) }}"
  {%if button.tooltip %}data-toggle="tooltip" title="{{ button.tooltip }}"{% endif %}
  >
  {{ button.name }}
</a>

crud/form_button.html

Form based button in the admin interface.

Does HTTP POST, has CSRF token.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{# Form based button in the admin interface.

Does HTTP POST, has CSRF token.
#}
<form id="form-crud-btn-{{ button.id }}" action="{{ button.get_link(context, request) }}" method="POST">
  <input type="hidden" name="csrf_token" value="{{ request.session.get_csrf_token() }}">
  <button
    id="btn-crud-{{ button.id }}"
    class="btn btn-default"
    {%if button.tooltip %}data-toggle="tooltip" title="{{ button.tooltip }}"{% endif %}
    >
    {{ button.name }}
  </button>
</form>

crud/delete.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{% extends base_template %}

{% block description %}
    <title>Confirm delete</title>
{% endblock description %}

{% block crud_content %}

    <div class="text-center">
      <h1>Confirm delete</h1>

      <p>
        Are you sure you want to delete <strong>{{ context.get_title() }}</strong>?
      </p>

      {% include "core/interstitial_form.html" %}
    </div>

{% endblock crud_content %}

crud/column_body_controls.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<td class="crud-column-{{column.id}}">
    <div class="pull-right">

        {% if request.has_permission("view", instance) %}
            <a href="{{ instance|model_url('show') }}" class="btn-crud-listing-show">
                Show
            </a>
        {% endif %}

        {% if request.has_permission("edit", instance) %}
            <a href="{{ instance|model_url('edit') }}" class="btn-crud-listing-edit">
                Edit
            </a>
        {% endif %}

        {% if request.has_permission("delete", instance) %}
            <a href="{{ instance|model_url('delete') }}" class="btn-crud-listing-delete">
                Delete
            </a>
        {% endif %}
    </div>
</td>

User

admin/user_panel.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{% extends "admin/model_panel.html" %}

{% block panel_content %}
<p>
    {% if latest_user %}
        Latest user: <a id="latest-user-shortcut" href="{{ latest_user_url }}">{{latest_user.friendly_name}}</a>
        (
            <small class=text-muted>
                {{ latest_user.activated_at|friendly_time(source_timezone='UTC') }}
            </small>
        )
    {% endif %}
</p>
{% endblock panel_content %}

social/twitter/login_snippet.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{% extends "social/base/login_snippet.html" %}

{% block social %}
    <a href="">
    </a>

    <a href="">
        Login with Twitter
    </a>
{% endblock social %}

social/twitter/register_snippet.html

— description missing —

1
2
3
4
5
6
{% extends "social/base/register_snippet.html" %}

{% block social %}
    <i class="fa fa-twitter"></i>
    Sign up with Twitter
{% endblock social %}

social/google/login_snippet.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{% extends "social/base/login_snippet.html" %}

{% block social %}
    <form method="post" action="{{'login'|route_url}}/google">

        <input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}"/>

        <button class="btn btn-primary btn-block btn-lg btn-login-google">
            <i class="fa fa-google"></i>
            Login with Google
        </button>
    </form>
{% endblock social %}

social/google/register_snippet.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{% extends "social/base/register_snippet.html" %}

{% block social %}
  <form method="post" action="{{ 'login'|route_url }}/google">

    <input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}"/>

    <button class="btn btn-primary btn-block btn-lg">
      <i class="fa fa-google"></i>
      Sign up with Google
    </button>
  </form>
{% endblock social %}

social/facebook/login_snippet.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{% extends "social/base/login_snippet.html" %}

{% block social %}
    <form method="post" action="{{'login'|route_url}}/facebook">

        <input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}"/>

        <button class="btn btn-primary btn-block btn-lg btn-login-facebook">
            <i class="fa fa-facebook"></i>
            Login with Facebook
        </button>
    </form>
{% endblock social %}

social/facebook/register_snippet.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{% extends "social/base/register_snippet.html" %}

{% block social %}
  <form method="post" action="{{ 'login'|route_url }}/facebook">

    <input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}"/>

    <button class="btn btn-primary btn-block btn-lg">
      <i class="fa fa-facebook"></i>
      Sign up with Facebook
    </button>
  </form>
{% endblock social %}

social/base/login_snippet.html

— description missing —

1
2
{% block social %}
{% endblock social %}

social/base/register_snippet.html

— description missing —

1
2
{% block social %}
{% endblock social %}

login/email/activate.subject.txt

— description missing —

1
2
{% extends "email/base_subject.txt" %}
{% block subject %}Please verify your email{% endblock %}

login/email/forgot_password.body.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{% extends "email/base.html" %}

{% block content %}

    <p>
    Hello {{user.friendly_name}},
    </p>

    <p>
    Someone requested resetting your password on {{ site_name }}. If it was you please click the link below.
    </p>

    <p style="text-align: center; margin: 0 auto">
        <a class="btn-primary" style="font-size: 120%" href="{{link}}">Reset password for my account</a>
    </p>

    <p>
    This request expires in {{ expiration_hours }} hours.
    </p>

{% endblock content %}

login/email/activate.body.txt

— description missing —

1
2
3
4
5
6
7
{% extends "email/base.txt" %}

{% block content %}
Your account on {{site_name}} is pending for email activation. Please click the link below to continue.

{{link}}
{% endblock content %}

login/email/forgot_password.body.txt

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{% extends "email/base.txt" %}

{% block content %}
Hello {{user.friendly_name}},

Someone requested resetting your password on {{ site_name }}. If it was you, click here:

{{ link }}

If you don't want to change your password, please ignore this email message.
{% endblock content %}

login/email/forgot_password.subject.txt

— description missing —

1
2
{% extends "email/base_subject.txt" %}
{% block subject %}Reset your password{% endblock %}

login/email/activate.body.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{% extends "email/base.html" %}

{% block content %}
    <p>
    Your account on {{site_name}} is pending for email activation. Please click the link below to continue.
    </p>

    <p style="text-align: center; margin: 0 auto">
        <a class="btn-primary" style="font-size: 120%" href="{{link}}">Activate my account</a>
    </p>

    <p>
    The link expires in {{ expiration_hours }} hours.
    </p>

{% endblock content %}

login/forgot_password.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{% extends "site/base.html" %}

{% block content %}

    <div class="row">
        <div class="col-md-12">
            <h1>Forgot your password?</h1>

            <p>Please give your email address to start password reset.</p>
        </div>
    </div>

    <div class="row" id="forgot-password-form">
        <div class="col-md-12">
            {{ form|safe }}
        </div>
    </div>

{% endblock content %}

login/reset_password.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{% extends "site/base.html" %}

{% block content %}

    <div class="row">
        <div class="col-md-12">
            <h1>Reset</h1>

            <p>Please give the new password below.</p>
        </div>
    </div>

    <div class="row" id="reset-password-form">
        <div class="col-md-12">
            {{ form|safe }}
        </div>
    </div>

{% endblock content %}

login/register.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
{% extends "site/base.html" %}

{% block content %}

    <div class="row">
        <div class="col-md-12">
            <h1>Sign up to {{site_name}}</h1>
        </div>
    </div>

    <div class="row">
        {% if social_logins %}
            <div class="col-md-6">

                <h2>With social media login</h2>

                <div>
                    {% for social in social_logins  %}
                        {% set template = 'social/' + social + '/register_snippet.html' %}
                        {% include template %}
                    {% endfor %}
                </div>

                <p><!-- --></p>
                <p class="text-center">
                    <small>
                        We never post anything on your wall.
                    </small>
                </p>
            </div>
        {% endif %}


        <div class="col-md-6">
            <h2>With email</h2>

            <div id="sign-up-form">
                {{form|safe}}
            </div>
        </div>
    </div>

{% endblock content %}

login/login.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{% extends "site/base.html" %}

{% block description %}
<title>Sign in to {{ site_name }}</title>
<meta name="description" content="">
{% endblock %}

{% block content %}

    <div class="row">
        <div class="col-md-12">
            <h1>Login to {{site_name}}</h1>
        </div>
    </div>

    {% include "login/login_base.html" %}

{% endblock content %}

login/registration_complete.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{% extends "site/base.html" %}

{% block content %}
    <div id="sign-up-complete">
        <div class="alert alert-info">
            <i class="fa fa-check-square-o"></i>
            Your email is now verified. Thank you for signing up. Please sign in below.
        </div>
    </div>

    <div id="login-form">
        {{form|safe}}
    </div>

{% endblock content %}

login/login_base.html

— description missing —

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<div class="row">
    {% if social_logins %}
        <div class="col-md-6">

            {% if authomatic_result and authomatic_result.error %}
                <div class="alert alert-danger">
                    {{authomatic_result.error}}
                </div>
            {% endif %}

            <h2>With social media account</h2>

            <div>
                {% for social in social_logins  %}
                    {% set template = 'social/' + social + '/login_snippet.html' %}
                    {% include template %}
                {% endfor %}
            </div>
        </div>
    {% endif %}


    <div class="col-md-6">
        <h2>With email</h2>

        <div id="login-form">
            {{form|safe}}
            <p><a href="{{'forgot_password'|route_url}}">Forgot your password?</a></p>
            <p>Don't have an account? <a href="{{'register'|route_url}}">Sign up!</a></p>
        </div>
    </div>
</div>

login/waiting_for_activation.html

— description missing —

1
2
3
4
5
6
7
8
9
{% extends "site/base.html" %}

{% block content %}
    <div id="waiting-for-activation">
        <h1>Waiting for email activation</h1>

        <p>A confirmation email has been sent to <strong>{{user.email}}</strong>. Please click the link in the email to continue.</p>
    </div>
{% endblock content %}