For an overview of the project, see Building a Campus Wiki in Python (part 1). This article stands alone and creates a front page of editable content that shows some of the basic uses of Wagtail. At the end of this article is the github address of the project file created in this paper. More detailed, beginners can try, but preferably with some Django background.





Overview of project structure

  • The first to usewagtail start genius(pip install wagtailInstall dependencies) created by namegeniusProject folder,cd geniusGo to the directory.
  • Enter in the Windows command linetree /a /f > 1.txtGenerated in the current directory1.txtSee the project structure below.
    E:.
    |   manage.py
    |   requirements.txt
    |   
    +---genius
    |   |   urls.py
    |   |   wsgi.py
    |   |   __init__.py
    |   |   
    |   +---settings
    |   |       base.py
    |   |       dev.py
    |   |       production.py
    |   |       __init__.py
    |   |       
    |   +---static
    |   |   +---css
    |   |   |       genius.css
    |   |   |       
    |   |   \---js
    |   |           genius.js
    |   |           
    |   \---templates
    |           404.html
    |           500.html
    |           base.html
    |           
    +---home
    |   |   models.py
    |   |   __init__.py
    |   |   
    |   +---migrations
    |   |       0001_initial.py
    |   |       0002_create_homepage.py
    |   |       __init__.py
    |   |       
    |   \---templates
    |       \---home
    |               home_page.html
    |               
    \---search
      |   views.py
      |   __init__.py
      |\---templates \---search search.htmlCopy the code
    1. manage.pyisDjangoCommon management scripts for the project (passPython manage.py specifies a command parameterUse).
    2. requirements.txtA dependency list used to store the current project (automatically generated asDjangoandwagtail, available in virtualenvpip freeze >> requirements.txtAdditional).
    3. geniusContains the main information of the project, including the main route (urls.py), WSGI interface (wsgi.py), configuration folder (basic configurationbase.py, development environment configurationdev.pyConfigured with the production environmentproduction.py, the latter two depend on the base configuration), global static resource folder (static) and the template resource folder (templates).
    4. homeIt’s an automatically generated app folder that containsmodels.pyPage data model andtemplatesTemplate folder. Default generatedmodels.pyDefines a simpleHomePageClass (inherited fromwagtailthePageClass) to represent a page (the default welcome page) (the editable content portion of this simple model is onlytitleField). inwagtailPage model and template file are associated by default, as inHomePageThe default template istemplates/home/home_page.html(Note the named transformation relationship), while the welcome pagehttp://127.0.0.1:8000Most of the content is in this templateextendsStatements inheritancegenius\templates\base.htmlAnd the use ofblockStatement to fill in the corresponding content. As follows:
      You can view the welcome page locally by migrating the database before starting the servicepython manage.py migrate
      python manage.py runserverCopy the code




      The welcome page






      Welcome page templates – templates/home/home_page.html

    5. searchIs automatically generated to provide the search function of the APP folder, due to basedwagtail.wagtailsearchSo it only containsviews.pyView files andtemplatesTemplate folder. Leave it at that.

Creating the Wiki home page

  • Let’s clear the database,python manage.py flushOr just delete itdb.sqlite3Database files.
  • Delete in the project root directoryhomeFolder, create a new folder namedwikiThe folder representswikiThe app, and will begenius\settings\base.pyAround line 28 in the configuration fileINSTALLED_APPSIn the listhomeInstead ofwikiTo register our app with the profile. And in thewikiAdd directory and empty file to folder:
    \---wiki
      | models.py
      | __init__.py
      |   
      +---migrations
      | __init__.py
      |       
      \---templates
          \---wikiCopy the code
  • Now create our home page model with the following main elements:






    ourWikiHomeThe page model needs a series of fields highlighted in red in the figure, wheretitleFields inherit fromPageClass, no need to add,imageThe field is connect towagtailimages.ImageForeign keys of the model.content_panelsThe list provides the page model to manage the rendering content of the edit page behind the scenes.

    In addition, forTopLinkandLittleIntrosWe need to create two more inheritanceswagtailTo provide theOrderable( Make the order) non-page model.






    WikiHomeLittleIntrosThe field hasfontawesomeIcon class name, subtitle, and brief description as shown below. It also contains onewagtailProvided by theForeignKeyWith a layer of encapsulationParentalKeyThe foreign key is connected to the one it belongs toWikiHomePage. Similarly,panelsIndicates that it appears in the editable area.











    WikiHomeTopLinkSimilarly, for clearer hierarchy, multiple inheritance is used inmodels.pyOnly in the definitionParentalKeyForeign key, which is defined in another fileRelatedLinkModel, contains the field has the link text and the specific link, but the specific link may be the external chain, a page or a document, occupied three fields, in addition to also use@propertyDecorators are added for the modellinkProperty to return its specific link, which can be used in the template.linkThe call.

    In conclusion,models.pyThe content is:

# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals

from django.db import models
from modelcluster.fields import ParentalKey

from wagtail.wagtailcore.models import Page, Orderable
from wagtail.wagtailadmin.edit_handlers import (
    FieldPanel, InlinePanel)
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel

from .umodels import RelatedLink


# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- home -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
class WikiHome(Page):
    logoname = models.CharField(
        max_length=255,
        help_text=U "Page name displayed in the upper left corner"
    )
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text=U "Large background"
    )
    intro = models.TextField(
        blank=True,
        help_text=U "Simple slogan below"
    )

    content_panels = Page.content_panels + [
        FieldPanel('logoname'),
        InlinePanel('toplinks', label="Top right link"),
        ImageChooserPanel('image'),
        FieldPanel('intro', classname="full"),
        InlinePanel('little_intros', label="The bottom row of promotion briefs."),]class WikiHomeTopLink(Orderable, RelatedLink):
    page = ParentalKey('wiki.WikiHome', related_name='toplinks')


class WikiHomeLittleIntros(Orderable):
    page = ParentalKey(WikiHome, related_name='little_intros')
    fa_name = models.CharField(blank=True, max_length=250,
                               help_text=FontAwesome icon class name - refer to FontAwesome. IO/ICONS/")
    title = models.CharField(blank=True, max_length=250,
                             help_text=U "subheadings")
    caption = models.CharField(blank=True, max_length=1000,
                               help_text=U "description")

    panels = [
        FieldPanel('fa_name'),
        FieldPanel('title'),
        FieldPanel('caption'),]Copy the code

Create a new umodels.py file next to models.py for reference:

#--------------------------umodels.py----------------------------#
from django.db import models
from wagtail.wagtailadmin.edit_handlers import (FieldPanel,
                                                PageChooserPanel,
                                                MultiFieldPanel)
from wagtail.wagtaildocs.edit_handlers import DocumentChooserPanel


class LinkFields(models.Model):
    link_external = models.URLField("External link", blank=True)
    link_page = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        related_name='+'
    )
    link_document = models.ForeignKey(
        'wagtaildocs.Document',
        null=True,
        blank=True,
        related_name='+'
    )

    @property
    def link(self):
        if self.link_page:
            return self.link_page.url
        elif self.link_document:
            return self.link_document.url
        else:
            return self.link_external

    panels = [
        FieldPanel('link_external'),
        PageChooserPanel('link_page'),
        DocumentChooserPanel('link_document'),]class Meta:
        abstract = True


# Related links
class RelatedLink(LinkFields):
    title = models.CharField(max_length=255, help_text="Link display text")

    panels = [
        FieldPanel('title'),
        MultiFieldPanel(LinkFields.panels, "Link"),]class Meta:
        abstract = TrueCopy the code
  • Our wiki home page model is now defined.
  • It is time to create a template for the page model in the Wiki foldertemplates\wiki\wiki_home.htmlTemplate file.
  • The first thing to think about is the general style of the template and what do we do, thanks to the open source world, we find something that is lightweight and beautifulpurecssFramework.





    It’s available in a rangelayoutsFor our use, choose the most suitable for this home pagestyleCheck the source code for details. Here, for simplicity, we use links to additional stylesheets for this layout (preferably handled as a native CSS style file, using Django static tag references).

    For a template, its corresponding page model is in its context, and all elements of the page model can be called from the template (using Djangos)Template language). We will fill in the elements according to page layout.

    Modify thewiki_home.htmlThe contents are as follows:

{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags %}

{% block extra_css %}
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/build/pure-min.css">

    <link rel="stylesheet" href="https://unpkg.com/[email protected]/build/grids-responsive-min.css">

    <link rel="stylesheet" href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css">

    <link rel="stylesheet" href="Https://purecss.io/combo/1.18.13? /css/layouts/marketing.css">
{% endblock %}

{% block body_class %}wiki-homepage{% endblock %}

{% block content %}

    <div class="header">
        <div class="home-menu pure-menu pure-menu-horizontal pure-menu-fixed">
            <a class="pure-menu-heading" href="">{{ page.logoname }}</a>

            <ul class="pure-menu-list">
                <li class="pure-menu-item pure-menu-selected"><a href="{{ page.url }}" class="pure-menu-link" style="color:white">Home page</a></li>
                {% for item in page.toplinks.all %}
                    <li class="pure-menu-item"><a href="{{ item.link }}" class="pure-menu-link">{{ item.title }}</a></li>
                {% endfor %}
            </ul>
        </div>
    </div>

    {% image page.image original as image %}
    <div class="splash-container" style="background-image: url({{ image.url }}); background-size:cover">
        <div class="splash">
            <h1 class="splash-head" style="color: black">{{ page.title }}</h1>
            <p class="splash-subhead">
            </p>
            <p>
                <form class="pure-form" action="/search">
                    <input type="text" name="query" placeholder="Please enter your search here...">
                    <button type="submit" class="pure-button pure-button-primary">Get Started</button>
                </form>
            </p>
        </div>
    </div>

    <div class="content-wrapper">
        <div class="content">
            <h2 class="content-head is-center">{{ page.intro }}</h2>
            <div class="pure-g">

            {% for item in page.little_intros.all %}
                <div class="l-box pure-u-1 pure-u-md-1-2 pure-u-lg-1-4">

                    <h3 class="content-subhead">
                        <i class="fa {{ item.fa_name }}"></i>
                        {{ item.title }}
                    </h3>
                    <p> {{ item.caption }} </p>
                </div>
            {% endfor %}

            </div>
        </div>

        <div class="l-box-lrg pure-g" style="height:20px">
        </div>

        {% load wiki_tags %}
        {% wikihome_footer %}

    </div>
{% endblock %}

{% block extra_js %}

{% endblock %}Copy the code
  • So that’s pretty much it, but in the last few lines of the template{% load wiki_tags %} {% wikihome_footer %}It’s not implemented yet. It’s the footer circled in yellow in the previous image. Given that the content of the footer is usually fixed, we use snippets and template tags. It allows us to modify the content of the footer in the administrative control page, but also allows the footer to have its own small HTML template that can be easily invoked by other templates.
  • inwikiUnder foldermodels.pyCreate a new one next to the filesnippets.pyFile, add the following:
from wagtail.wagtailsnippets.models import register_snippet
from django.db import models
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel


@register_snippet
class FooterText(models.Model):

    body = RichTextField()

    panels = [
        FieldPanel('body'),]def __str__(self):
        return U "Text at the bottom of the page - single"

    class Meta:
        verbose_name_plural = U 'Bottom text of page'Copy the code

In fact, it still creates a Django model that contains only a rich text field, but with the Register_Snippet decorator provided by Wagtail we can easily register it with the admin interface and modify it there. You need to register it with Djangos tag system, create a new wiki folder, templateTags, and a new wiki_tags.py file in that folder, and add the following. Again, the template tag is registered with a simple decorator and is bound to the Wiki /tags/footer.html fragment template, providing footer_TEXT as a context.

from django import template
from wiki.snippets import FooterText


register = template.Library()


@register.inclusion_tag('wiki/tags/footer.html', takes_context=True)
def wikihome_footer(context):
    footer_text = ""
    if FooterText.objects.first() is not None:
        footer_text = FooterText.objects.first().body

    return {
        'footer_text': footer_text,
    }Copy the code

Then it’s time to create the corresponding fragment template file. Corresponding to the HTML file path bound in the above code, create a templates\wiki\tags\footer.html file in the wikiApp directory and add the following:

{% load wagtailcore_tags %}

<div class="footer l-box is-center">
    {{ footer_text|richtext }}
</div>Copy the code
  • Well, all the code parts of the home page are over. Let’s try to run it. Execute in project root:
python manage.pyNames, Hoisting # Create database migration filespython manage.pyMigrate # Perform database migrationpython manage.pyCreatesuperuser # Create a super administratorpython manage.pyRunserver # Start the serviceCopy the code
  • Log in to the management page:http://127.0.0.1:8000/admin/






    Click the part circled in red to go to the following page and delete the default page.






    After confirming the deletion, select create a page in the root directory






    This brings us to the page element fill screen for our created WikiHome model, fill it in and then Publish the commit by pressing the red circle.






    After the page is created, we need to mount it to the site and display it properly. Click the red box below to create the site






    Create and save as shown below,Root PageSelect the newly created page.






    Finally, accesshttp://127.0.0.1:8000/You can see what the page looks like.





  • But if you’re careful, you’ll notice that the footer is empty. You’ll also need to set the footer in the admin interface, click on the Snippets bar, and click on the red circle









Create and save





  • Done, our footer is also perfect, the entire home page production is complete. All the code and the sample page are in the database on Github, Wagtail-tutorial-1, which can be run directly. The administrator account is Lake and the password is 123, or another administrator can be created.