Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Wagtail installation instructions #163

Merged
merged 19 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions en/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Current tutorials are:
* [Homework: add more to your website!](homework/README.md)
* [Homework: secure your website](authentication_authorization/README.md)
* [Homework: create comment model](homework_create_more_models/README.md)
* [Homework: Add Wagtail to your website](add_wagtail_to_your_website/README.md)
* [Optional: PostgreSQL installation](optional_postgresql_installation/README.md)

## Contributing
Expand Down
5 changes: 5 additions & 0 deletions en/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
* [Homework: add more to your website!](homework/README.md)
* [Homework: secure your website](authentication_authorization/README.md)
* [Homework: create comment model](homework_create_more_models/README.md)
* [Homework: Add Wagtail to your website](add_wagtail_to_your_website/README.md)
* [Wagtail Installation](add_wagtail_to_your_website/install_wagtail/README.md)
* [Wagtail - Adding the Homepage](add_wagtail_to_your_website/wagtail_integration_adding_homepage/README.md)
* [Wagtail - Adding Posts](add_wagtail_to_your_website/wagtail_integration_adding_posts/README.md)
* [Wagtail - Change Website Homepage](add_wagtail_to_your_website/change_website_homepage/README.md)
* [Optional: PostgreSQL installation](optional_postgresql_installation/README.md)
* [Optional: Domain](domain/README.md)
* [Deploy your website on Heroku](heroku/README.md)
Expand Down
21 changes: 21 additions & 0 deletions en/add_wagtail_to_your_website/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Homework: Add Wagtail to your website

> Part of this chapter is based on Wagtail’s official [Getting Started tutorial](https://docs.wagtail.org/en/stable/getting_started/tutorial.html).

We can make our blog even more professional by adding Wagtail to our website while at the same time we are
developing our coding skills in Python and Django. Wagtail is an open source content management system built on
Django, with a strong community and commercial support. It's focused on user experience,
and offers precise control for designers and developers.

The website we built through following the tutorial is a simplified content management system because it allows us
to add and manage content as well as serve it to the visitors of our blog. Wagtail on the other hand is a more complex
content management system with more advanced features. Adding Wagtail to our website will enable us to learn more about
Django and see what cool applications we can build with it.

In this part of the tutorial, we will cover the following aspects:
- [Installing Wagtail and Configuring Wagtail](install_wagtail/README.md)
- [Adding the Homepage](wagtail_integration_adding_homepage/README.md)
- [Adding Posts](wagtail_integration_adding_posts/README.md)
- [Change Website Homepage](change_website_homepage/README.md)

So let's get started!
137 changes: 137 additions & 0 deletions en/add_wagtail_to_your_website/change_website_homepage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Change Website Homepage to Wagtail Blog Homepage

The Wagtail admin has a nicer and a more user-friendly interface compared to the default Django admin user interface.
For this reason, we would rather use our Wagtail blog as our main blog and ignore the blog we created in the main
tutorial.

We will not remove our initial blog, we will leave it as it is as we may need to use it for more learning. We will
however change the root of our project to point to our Wagtail blog. Make the following changes to your
`mysite/urls.py` as shown below:

First change the `URL` for your first blog to the following:

```python
path('blog/', include('blog.urls')),
```

Next change the `URL` for the Wagtail blog to the following:

```python
path('', include(wagtail_urls)),
```

Your `mysite/urls.py` should now look like below:

{% filename %} mysite/urls.py {% endfilename %}
```python
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path

from wagtail.admin import urls as wagtailadmin_urls
from wagtail import urls as wagtail_urls

urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
path('cms/', include(wagtailadmin_urls)),
path('', include(wagtail_urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

```

This will make your Wagtail accessible by visiting `http://127.0.0.1:8000` as shown below

![New Website Homepage](images/wagtail_as_root.png)

and your first blog will now be at `http://127.0.0.1:8000/blog/` as shown below.

![Old Blog's New URL](images/old_blog_url.png)

# Committing our changes to GitHub

Now that we have managed to get Wagtail working well with out blog, we can deploy our changes to our live website
which we deployed to PythonAnywhere earlier on during the main tutorial. To do this, we need to first push our code to
GitHub as we have done before by typing the following in our command line:

```
(myvenv) ~/djangogirls$ git status
```

This will list all the files we have changed. Once we have confirmed those are the changes we have made, we can go
ahead and add the files to be committed by typing the following command:

```
(myvenv) ~/djangogirls$ git add .
```

Next we need to add a commit message for our changes to be saved by typing the following command:

```
(myvenv) ~/djangogirls$ git commit -m "Add Wagtail to our blog"
```

Lastly, we need to push the commit to GitHub by typing the following command:

```
(myvenv) ~/djangogirls$ git push origin HEAD
```

This will push our new changes to GitHub and we are now ready to deploy these changes to PythonAnywhere!

# Deploying the changes to PythonAnywhere
To deploy our changes to [PythonAnywhere](https://pythonanywhere.com) and click `Consoles` and click on
`Bash Console in virtualenv` to open a new Bash console with an activated virtual environment and then type in the
following command:

```
$ git pull origin HEAD
```

This command will pull your changes from GitHub to your PythonAnywhere project.

Next, you need to update the requirements for your project by installing Wagtail and its dependencies. Since we
updated our requirements file, you only need to type in the following command to install the required packages:

```
$ pip install -r requirements.txt
```

Next step is to run migrations for the new models and create the necessary tables in the database. To do this, type the
following command:

```
$ python manage.py migrate
```

Next, you need to run the `collectstatic` command to copy the static files required by Wagtail to the `static` root
folder specified in our `settings.py` file.

```
$ python manage.py collectstatic
```

Lastly, go to `Web` tab and reload your webapp by clicking the `Reload <your-username>.pythonanywhere.com` button and
open `https://<your-username.pythonanywhere.com` in another tab to see your blog now using Wagtail CMS.

You should get the `Welcome to your new Wagtail site!` on your homepage to show that Wagtail is now working as your
website root.

To change the root page of your Wagtail blog visit `https://<your-username.pythonanywhere.com/cms/` and login.

Then follow the steps in [Changing the Wagtail Homepage](../wagtail_integration_adding_homepage/README.md#changing-homepage) section of this tutorial to create a new homepage and change it to be the root of the blog.

To create new posts, follow instructions in the [Adding posts](../wagtail_integration_adding_posts/README.md#adding-blog-posts) section of this tutorial.

After adding your posts, you should see that only posts/pages that have been published are the ones displayed on your blog.
In other words, Wagtail only shows posts which are `live` and a post is only `live` after you click the `Publish` button.
The `Save draft` button merely saves the post without publishing it or making it live.

Also, take note that `live` posts are displayed in the order in which they are published, that is, they are ordered by date.
In Django, the statement to get blog posts would look like `BlogPage.objects.filter(published=True).order_by(published_date)`.

That's all for this tutorial. If you want to learn more about Wagtail, you can read the
amakarudze marked this conversation as resolved.
Show resolved Hide resolved
[Wagtail documentation](https://guide.wagtail.org/en-latest/) or search for more tutorials on Wagtail online.

Happy coding!
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
176 changes: 176 additions & 0 deletions en/add_wagtail_to_your_website/install_wagtail/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# Wagtail Installation and Configuration

In this section, we will cover how to install and configure Wagtail in an already existing project. The experience will
amakarudze marked this conversation as resolved.
Show resolved Hide resolved
slightly be different from just launching a new Wagtail project as we already have a working project that we need to
improve by adding the powerful and wonderful capabilities of Wagtail.

## Wagtail Installation
To install Wagtail, type the following command in the command prompt:

```
(myvenv) ~/djangogirls$ pip install wagtail
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn’t there be a specific (LTS) version specified here? Our Wagtail 5.2 LTS is due for release on November 1st so might be a good one to use. It’ll be supported until 2024-11-01.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can confirm this will break at some point, as Wagtail 6.0 due for release in February 2024 will drop Django 3.2 compatibility. So for now I’d recommend:

Suggested change
(myvenv) ~/djangogirls$ pip install wagtail
(myvenv) ~/djangogirls$ pip install wagtail>=5.2,<5.3

```

Now that we have installed Wagtail, we need to add it to our `requirements.txt` so that we can keep track of our
requirements and we can easily install all our project dependencies when we deploy the changes to our website. To
update the `requirements.txt`, type the following command in the command prompt:

```
(myvenv) ~/djangogirls$ pip freeze > requirements.txt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like to do the installation this way around in some respect, but shouldn’t this be aligned with the main tutorial and:

  1. First instruct people to add wagtail>=5.2,<5.3 in requirements.txt
  2. Then pip install -r requirements.txt

I’m happy either way but thought I’d check. Aside from the steps, the main difference in results is that the pip freeze locks all dependency versions, not just Wagtail.

```

## Wagtail Settings
The next thing we need to do is to add some configuration for Wagtail in `mysite/settings.py`. The first thing we need
to add is Wagtail and its associated apps to `INSTALLED_APPS` so that it looks like below:
amakarudze marked this conversation as resolved.
Show resolved Hide resolved

```python
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"wagtail.contrib.forms",
"wagtail.contrib.redirects",
"wagtail.embeds",
"wagtail.sites",
"wagtail.users",
"wagtail.snippets",
"wagtail.documents",
"wagtail.images",
"wagtail.search",
"wagtail.admin",
"wagtail",
"modelcluster",
"taggit",
"blog",
]
```

So far we have only been using Django's inbuilt middleware. However to use Wagtail, we need to add its custom middleware.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only needed if we want to use Wagtail’s redirects, which is an optional feature. It’s a really useful feature so seems fair to me we’d install it from the get-go, but I think the instructions should acknowledge it’s optional / specific to redirects.

Or – remove the extra middleware (and redirects from the INSTALLED_APPS) for the sake of simplicity.

We need to add the following line to the `MIDDLEWARE` setting:

```python
"wagtail.contrib.redirects.middleware.RedirectMiddleware",
```

The `MIDDLEWARE` setting should now look like this:

```python
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"wagtail.contrib.redirects.middleware.RedirectMiddleware",
]
```

We also need the `MEDIA_ROOT` and `MEDIA_URL` settings as shown below:

```python
MEDIA_ROOT = BASE_DIR / 'media'
MEDIA_URL = '/media/'
```

The last setting to be added is the `WAGTAIL_SITE_NAME`. This will be displayed on the main dashboard of the
Wagtail admin backend. This should look like below:

```python
WAGTAIL_SITE_NAME = 'Django Girls Blog'
```

## URL Configuration
We also need to add Wagtail URLs to our root URLs file, that is `mysite/urls.py` so that we are able to access Wagtail
views. We will add the following lines to `mysite/urls.py` right below the imports we have. The Wagtail imports should
be below the Django imports so that we follow best practices for handling imports. This is because Wagtail imports are
**third party** imports so should be below the main Django imports.

```python
from wagtail.admin import urls as wagtailadmin_urls
from wagtail import urls as wagtail_urls
```

Then we need to add the following lines to `urlspatterns` list to include Wagtail URLs.
```python
path('cms/', include(wagtailadmin_urls)),
path('pages/', include(wagtail_urls)),
```

Wagtail comes with its own custom admin interface provide by `wagtailadmin_urls` which we will be able to access by
amakarudze marked this conversation as resolved.
Show resolved Hide resolved
visiting the URL`/cms/`. This is different from the Django admin interface provided by `django.contrib.admin`we have
been accessing by the `/admin/` URL. In a typical Wagtail only project, the admin site would be at `/admin/` but
because we are adding Wagtail to an already existing Django project, this would clash with our , admin URL so we are
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
because we are adding Wagtail to an already existing Django project, this would clash with our , admin URL so we are
because we are adding Wagtail to an already existing Django project, this would clash with our admin URL so we are

using `/cms/` to access the Wagtail admin interface and keep using `/admin/` to access the Django admin interface.

Wagtail also comes with a user interface for serving Wagtail pages which is provided for by `wagtail_urls` and can be
accessed by visiting the `/pages/` URL. In our current setup, Wagtail will handle Wagtail URLs under `/pages/` and leave
our the root and admin URLs to be handled by our normal Django project. Alternatively, we can have Wagtail serve all
amakarudze marked this conversation as resolved.
Show resolved Hide resolved
URLs, which we will work towards in this project, but for now, we will leave things as they are.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
our the root and admin URLs to be handled by our normal Django project. Alternatively, we can have Wagtail serve all
URLs, which we will work towards in this project, but for now, we will leave things as they are.
our the root and admin URLs to be handled by our normal Django project. Alternatively, we can have Wagtail serve all
URLs not handled by other views, which we will work towards in this project, but for now, we will leave things as they are.

I think worth clarifying that it’s common for Wagtail to be used as a "catch-all", so "all URLs except those defined to be served with something else".


Wagtail also has `wagtail.documents` to be used for documents management which we could also import as
`wagtaildocs_urls`. However, since we will not be managing any documents for now, we can skip that and just add the two
Wagtail URLs.

We also need to add the media URLs to our `mysite/urls.py` to enable us to serve user uploaded files by adding the
following lines to the top of the file:

```python
from django.conf import settings
from django.conf.urls.static import static
```
and then add the line below to the end of the file, right after the closing brace for `urlpatterns` to add it to the
list of URLs:

```python
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```

Our `mysite/urls.py` should now look like below:

{% filename %}mysite/urls.py{% endfilename %}
```python
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path

from wagtail.admin import urls as wagtailadmin_urls
from wagtail import urls as wagtail_urls

urlpatterns = [
path("admin/", admin.site.urls),
path('', include('blog.urls')),
path('cms/', include(wagtailadmin_urls)),
path('pages/', include(wagtail_urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```

We should now be able to get the following when we visit `http://127.0.0.1:8000/cms/`:

![Wagtail CMS homepage](images/wagtail_cms.png)


We should also get the following when we visit `http://127.0.0.1:8000/pages/`:

![Wagtail homepage](images/wagtail_pages.png)


Our existing root URL for the blog at `http://127.0.0.1:8000` should also still be working

![Blog homepage](images/blog_home.png)


as well as our Django admin interface at `http://127.0.0.1:8000/admin/`.

![Django admin interface](images/django_admin.png)


Looks like we are all set to use Wagtail in our project. We are ready to move to the next stage where will integrate our
blog to use Wagtail.

Let's keep going!
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading