`
which can be loaded by including ``{% load wagtailcore_tags %}`` at the top of
your template file.
In this tutorial, we use the `richtext` filter to escape and print the contents
of a ``RichTextField``:
.. code-block:: html+django
{% load wagtailcore_tags %}
{{ page.body|richtext }}
Produces:
.. code-block:: html
**Note:** You'll need to include ``{% load wagtailcore_tags %}`` in each
template that uses Wagtail's tags. Django will throw a ``TemplateSyntaxError``
if the tags aren't loaded.
A basic blog
------------
We are now ready to create a blog. To do so, run
``python manage.py startapp blog`` to create a new app in your Wagtail site.
Add the new ``blog`` app to ``INSTALLED_APPS`` in ``mysite/settings/base.py``.
The following example defines a basic blog post model in ``blog/models.py``:
.. code-block:: python
from django.db import models
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel
from wagtail.wagtailsearch import index
class BlogPage(Page):
date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = RichTextField(blank=True)
search_fields = Page.search_fields + [
index.SearchField('intro'),
index.SearchField('body'),
]
content_panels = Page.content_panels + [
FieldPanel('date'),
FieldPanel('intro'),
FieldPanel('body', classname="full")
]
.. note::
On Wagtail versions before 1.5, ``search_fields`` needs to be defined as a tuple:
.. code-block:: python
search_fields = Page.search_fields + (
index.SearchField('intro'),
index.SearchField('body'),
)
Create a template at ``blog/templates/blog/blog_page.html``:
.. code-block:: html+django
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block body_class %}template-blogpage{% endblock %}
{% block content %}
{{ page.title }}
{{ page.date }}
{{ page.intro }}
{{ page.body|richtext }}
{% endblock %}
Run ``python manage.py makemigrations`` and ``python manage.py migrate``.
.. figure:: ../_static/images/tutorial/tutorial_4.png
:alt: Create page screen
.. figure:: ../_static/images/tutorial/tutorial_5.png
:alt: Page edit screen
Image support
~~~~~~~~~~~~~
Wagtail provides support for images out of the box. To add them to your
model:
.. code-block:: python
from django.db import models
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtailsearch import index
class BlogPage(Page):
main_image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = RichTextField(blank=True)
search_fields = Page.search_fields + [
index.SearchField('intro'),
index.SearchField('body'),
]
content_panels = Page.content_panels + [
FieldPanel('date'),
ImageChooserPanel('main_image'),
FieldPanel('intro'),
FieldPanel('body'),
]
Run ``python manage.py makemigrations`` and ``python manage.py migrate``.
Adjust your blog page template to include the image:
.. code-block:: html+django
{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags %}
{% block body_class %}template-blogpage{% endblock %}
{% block content %}
{{ page.title }}
{{ page.date }}
{% if page.main_image %}
{% image page.main_image width-400 %}
{% endif %}
{{ page.intro }}
{{ page.body|richtext }}
{% endblock %}
.. figure:: ../_static/images/tutorial/tutorial_6.png
:alt: A blog post sample
You can read more about using images in templates in the
:doc:`docs <../topics/images>`.
Blog Index
~~~~~~~~~~
Let us extend the Blog app to provide an index.
.. code-block:: python
class BlogIndexPage(Page):
intro = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('intro', classname="full")
]
The above creates an index type to collect all our blog posts.
``blog/templates/blog/blog_index_page.html``
.. code-block:: html+django
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block body_class %}template-blogindexpage{% endblock %}
{% block content %}
{{ page.title }}
{{ page.intro|richtext }}
{% endblock %}
Related items
~~~~~~~~~~~~~
Let's extend the BlogIndexPage to add related links. The related links
can be BlogPages or external links. Change ``blog/models.py`` to
.. code-block:: python
from django.db import models
from modelcluster.fields import ParentalKey
from wagtail.wagtailcore.models import Page, Orderable
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import (FieldPanel,
InlinePanel,
MultiFieldPanel,
PageChooserPanel)
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtailsearch import index
# ...
class LinkFields(models.Model):
link_external = models.URLField("External link", blank=True)
link_page = models.ForeignKey(
'wagtailcore.Page',
null=True,
blank=True,
related_name='+'
)
@property
def link(self):
if self.link_page:
return self.link_page.url
else:
return self.link_external
panels = [
FieldPanel('link_external'),
PageChooserPanel('link_page'),
]
class Meta:
abstract = True
# Related links
class RelatedLink(LinkFields):
title = models.CharField(max_length=255, help_text="Link title")
panels = [
FieldPanel('title'),
MultiFieldPanel(LinkFields.panels, "Link"),
]
class Meta:
abstract = True
class BlogIndexPage(Page):
intro = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('intro', classname="full"),
InlinePanel('related_links', label="Related links"),
]
class BlogIndexRelatedLink(Orderable, RelatedLink):
page = ParentalKey('BlogIndexPage', related_name='related_links')
.. figure:: ../_static/images/tutorial/tutorial_7.png
:alt: Blog index edit screen
Extend ``blog_index_page.html`` to show related items
.. code-block:: html+django
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block body_class %}template-blogindexpage{% endblock %}
{% block content %}
{{ page.title }}
{{ page.intro|richtext }}
{% if page.related_links.all %}
{% endif %}
{% endblock %}
You now have a fully working blog with featured blog posts.
.. figure:: ../_static/images/tutorial/tutorial_8.png
:alt: Barebones blog index
Where next
----------
- Read the Wagtail :doc:`topics <../topics/index>` and :doc:`reference <../reference/index>` documentation
- Learn how to implement :doc:`StreamField <../topics/streamfield>` for freeform page content
- Browse through the :doc:`advanced topics <../advanced_topics/index>` section and read :doc:`third-party tutorials <../advanced_topics/third_party_tutorials>`