mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2024-12-22 12:25:56 +01:00
370 lines
14 KiB
Markdown
370 lines
14 KiB
Markdown
|
# Engagement and dissemination
|
||
|
|
||
|
You can foster reader engagement and improve the dissemination of content
|
||
|
on your blog by providing an RSS feed that people can subscribe to and by
|
||
|
integrating a discussion system. To learn more about who is or is not reading
|
||
|
your posts, you may want to integrate an analytics system. You may also want
|
||
|
to post on social media when you public a new blog post. This tutorial gives
|
||
|
you a leg up on all of these topics.
|
||
|
|
||
|
__Time required:__ typically 30 minutes
|
||
|
|
||
|
## RSS feeds
|
||
|
|
||
|
An _RSS feed_ allows users to subscribe to a blog so that they get notified when
|
||
|
you publish new posts. RSS Feed readers are often used to access blogs that a
|
||
|
user follows. They usually support downloading the blog content for offline
|
||
|
consumption.
|
||
|
|
||
|
An easy way to create an RSS feed for your blog is to use the
|
||
|
[MkDocs RSS Plugin], which is well integrated with Material for MkDocs.
|
||
|
Since it is a third-party plugin, you need to install it before using it.
|
||
|
|
||
|
[MkDocs RSS Plugin]: https://guts.github.io/mkdocs-rss-plugin
|
||
|
|
||
|
|
||
|
!!! example "Add an RSS feed"
|
||
|
|
||
|
Install the RSS plugin into your project:
|
||
|
|
||
|
```
|
||
|
$ pip install mkdocs-rss-plugin
|
||
|
```
|
||
|
|
||
|
It is important that have the `site_name`, `site_description` and
|
||
|
`site_url` settings configured as [instructed in the basic blog tutorial].
|
||
|
The RSS plugin makes use of this information to construct the feed, so make
|
||
|
sure you have configured them.
|
||
|
|
||
|
[instructed in the basic blog tutorial]: basic.md#setting-up-your-blog
|
||
|
|
||
|
Now, configure the plugin in the `mkdocs.yml`. The options provided restrict
|
||
|
the pages that RSS entries are created for to the blog posts, which is
|
||
|
probably what you want. Also note the configuration of the date fields to
|
||
|
match the format that Material for MkDocs uses to accommodate both a
|
||
|
creation date and a date for updates.
|
||
|
|
||
|
```yaml hl_lines="9"
|
||
|
plugins:
|
||
|
- ...
|
||
|
- rss:
|
||
|
match_path: "blog/posts/.*"
|
||
|
date_from_meta:
|
||
|
as_creation: date.created
|
||
|
as_update: date.updated
|
||
|
```
|
||
|
|
||
|
Have a look at http://localhost:8000/feed_rss_created.xml to see the RSS
|
||
|
feed in all its XML glory. You can use a browser like Firefox or Chrome that
|
||
|
can display the raw RSS feed or use `curl` to get the feed and `xmllint` to
|
||
|
format it. (You may need to install these tools.)
|
||
|
|
||
|
```
|
||
|
curl -s http://localhost:8000/feed_rss_created.xml | xmllint --format -
|
||
|
```
|
||
|
|
||
|
You may also want to try your feed with a feed reader. There are various desktop
|
||
|
and mobile apps as well as online services. Of course, to use the latter you
|
||
|
will need to deploy your project somewhere that is accessible to them.
|
||
|
|
||
|
This minimal configuration should work well if you have not made any changes
|
||
|
to the default configuration of the blog plugin. For more information on adapting
|
||
|
the feed to your needs, see [the RSS plugin's documentation].
|
||
|
|
||
|
[the RSS plugin's documentation]: https://guts.github.io/mkdocs-rss-plugin/
|
||
|
|
||
|
## Social media buttons
|
||
|
|
||
|
Social media buttons can serve two purposes: to allow your readers to navigate
|
||
|
to your social media profiles or to share content you have published via their
|
||
|
own accounts.
|
||
|
|
||
|
### Profile links
|
||
|
|
||
|
Links to social media profiles a usually provided in the footer of pages and
|
||
|
Material for MkDocs makes this easy. All you need to do is to provide the
|
||
|
necessary links and define the icons to use.
|
||
|
|
||
|
!!! example "Adding social media profile links"
|
||
|
|
||
|
Add an `extra` section to your `mkdocs.yml` and, within it, a `social`
|
||
|
section to contain a list of link definitions. These consist of the logo
|
||
|
to use and the link to the profile.
|
||
|
|
||
|
```yaml
|
||
|
extra:
|
||
|
social:
|
||
|
- icon: fontawesome/brands/mastodon
|
||
|
name: squidfunk on Mastodon
|
||
|
link: https://fosstodon.org/@squidfunk
|
||
|
```
|
||
|
|
||
|
For the `icon`, you can choose any valid path to an icon bundled with the
|
||
|
theme. The `name` will be used as the title attribute for the icon and
|
||
|
including this improves accessibility.
|
||
|
For popular social media systems, the link needs to be absolute and
|
||
|
needs to include the scheme, most likely `https://`.
|
||
|
|
||
|
You can also use other schemes. For example, to cerate an icon that allows
|
||
|
people to create an email, add this:
|
||
|
|
||
|
```yaml
|
||
|
extra:
|
||
|
social:
|
||
|
- icon: /fontawesome/regular/envelope
|
||
|
name: send me an email
|
||
|
link: mailto:<email-address>
|
||
|
```
|
||
|
|
||
|
Finally, you can specify a URL within your site, such as to your contact
|
||
|
page. It is possible to specify only the path to the page:
|
||
|
|
||
|
```yaml
|
||
|
extra:
|
||
|
social:
|
||
|
- icon: /material/mailbox
|
||
|
name: contact us
|
||
|
link: /contact
|
||
|
```
|
||
|
|
||
|
### Share and like buttons
|
||
|
|
||
|
Adding buttons that let people share your content on social media is a bit
|
||
|
more involved, which is why there are companies offering components for this.
|
||
|
|
||
|
|
||
|
!!! tip "Data Protection"
|
||
|
|
||
|
"Share" and "Like" buttons that use integrations provided by social media
|
||
|
companies often leave copious data traces even when the user does not
|
||
|
interact with these buttons. If you choose to integate such feature on
|
||
|
your site please be aware of the data protection implications and your
|
||
|
duties as a provider to ensure that processing occurs only once the user
|
||
|
has granted consent.
|
||
|
|
||
|
This implementation of share buttons deliberately does not use third party code.
|
||
|
It supports sharing to Twitter/X and Facebook without causing a data flow to
|
||
|
these companies whenever someone views the pages. Only when someone clicks a
|
||
|
share button will there be interactions with those companies' servers.
|
||
|
|
||
|
!!! example "Add share buttons"
|
||
|
|
||
|
In order to add the share buttons, you can add a hook that appends buttons
|
||
|
for sharing the current page.
|
||
|
|
||
|
Create a directory `hooks` in your project root and configure it
|
||
|
in your `mkdocs.yml`:
|
||
|
|
||
|
```yaml
|
||
|
hooks:
|
||
|
- hooks/socialmedia.py
|
||
|
```
|
||
|
|
||
|
Add the file `hooks/socialmedia.py` with the following Python code:
|
||
|
|
||
|
```python
|
||
|
from textwrap import dedent
|
||
|
import urllib.parse
|
||
|
import re
|
||
|
|
||
|
x_intent = "https://twitter.com/intent/tweet"
|
||
|
fb_sharer = "https://www.facebook.com/sharer/sharer.php"
|
||
|
include = re.compile(r"blog/[1-9].*")
|
||
|
|
||
|
def on_page_markdown(markdown, **kwargs):
|
||
|
page = kwargs['page']
|
||
|
config = kwargs['config']
|
||
|
if not include.match(page.url):
|
||
|
return markdown
|
||
|
|
||
|
page_url = config.site_url+page.url
|
||
|
page_title = urllib.parse.quote(page.title+'\n')
|
||
|
|
||
|
return markdown + dedent(f"""
|
||
|
[Share on :simple-x:]({x_intent}?text={page_title}&url={page_url}){{ .md-button }}
|
||
|
[Share on :simple-facebook:]({fb_sharer}?u={page_url}){{ .md-button }}
|
||
|
""")
|
||
|
```
|
||
|
|
||
|
The hook first checks if the current page is a blog post and then appends
|
||
|
Markdown code for the share buttons. The buttons use icons, so you also need
|
||
|
to configure the following markdown extensions:
|
||
|
|
||
|
```yaml
|
||
|
markdown_extensions:
|
||
|
- attr_list
|
||
|
- pymdownx.emoji:
|
||
|
emoji_index: !!python/name:material.extensions.emoji.twemoji
|
||
|
emoji_generator: !!python/name:material.extensions.emoji.to_svg
|
||
|
```
|
||
|
|
||
|
|
||
|
## Add a discussion system
|
||
|
|
||
|
Allowing your readers to comment on your posts is a great way of receiving
|
||
|
feedback, learning something, as well as giving readers the opportunity to
|
||
|
discuss the content and the topic it is about.
|
||
|
|
||
|
There are plenty of discussion system out there and you will need to consider
|
||
|
your audience when choosing one appropriate for your blog. Likewise, you will
|
||
|
also need to consider existing commitments to communication channels. If you
|
||
|
are a heavy user Slack, for example, you may have a string preference for this
|
||
|
system. Consider that when you add a communication channel, you will need to
|
||
|
be prepared to use it regularly and to moderate discussions.
|
||
|
|
||
|
### Giscus integration
|
||
|
|
||
|
In this tutorial, we will be using [Giscus] because it is free, open source,
|
||
|
and uses [GitHub Discussions] as a backend. Because a lot of users of Material
|
||
|
for MkDocs use GitHub, this seems like an obvious choice.
|
||
|
|
||
|
[Giscus]: https://giscus.app/
|
||
|
[GitHub Discussions]: https://docs.github.com/en/discussions
|
||
|
|
||
|
To add Giscuss to your blog you will need to go through a number of steps:
|
||
|
|
||
|
1. Create a GitHub repository if there is not already one
|
||
|
2. Turn on discussions and install the [Giscus app]
|
||
|
3. Configure the code needed to embed Giscus into your blog
|
||
|
4. Add the code to your MkDocs project
|
||
|
|
||
|
[Giscus app]: https://github.com/apps/giscus
|
||
|
|
||
|
You may want to create a test repository for this tutorial that you can
|
||
|
scrap later on. The instructions below assume that you are user "example"
|
||
|
and that you create a repository "giscus-test." The repository will need
|
||
|
to be public for people to be able to use the discussions.
|
||
|
|
||
|
In the instructions given below, you will need to replace at least the username
|
||
|
but also the repository name if you chose another name such as when you
|
||
|
want to work directly on an existing repository.
|
||
|
|
||
|
!!! example "Turn on discussions and install the Giscus app"
|
||
|
|
||
|
Once the repository is set up, go to its settings page and find
|
||
|
`Features` in the `General` section. Tick the checkbox for `Discussions`.
|
||
|
You will see that `Discussions` appears in the top navigation for the
|
||
|
repository. If you are using a live repository then you may want to add some
|
||
|
minimal content to the dicussions section at this point and come back to the
|
||
|
tutorial.
|
||
|
|
||
|
Next, you need to install the [Giscus app] by following the link in this
|
||
|
sentence, and choosing `Install`, then following the instructions to choose
|
||
|
where the Giscus app is to be installed:
|
||
|
|
||
|
1. Choose the account or organization for the repository you want to use.
|
||
|
2. Choose to install only on select repositories and select the one you
|
||
|
want to use. Note that you can choose more than one repository here.
|
||
|
3. Select `Install` at the end. You may need to authenticate to give
|
||
|
permission for this to happen.
|
||
|
4. You will end up on the `Applications` page in your settings, where you
|
||
|
can control the Gicsus app and uninstall it if so desired.
|
||
|
|
||
|
That is all the preparation you will need for the repository. Next, it is time
|
||
|
to generate a piece of code that embeds Giscuss in your site. The resulting code
|
||
|
snippet will look something like this:
|
||
|
|
||
|
```html
|
||
|
<script src="https://giscus.app/client.js"
|
||
|
data-repo="<username>/<repository>"
|
||
|
data-repo-id="..."
|
||
|
data-category="Announcements"
|
||
|
data-category-id="..."
|
||
|
data-mapping="title"
|
||
|
data-strict="1"
|
||
|
data-reactions-enabled="1"
|
||
|
data-emit-metadata="1"
|
||
|
data-input-position="top"
|
||
|
data-theme="preferred_color_scheme"
|
||
|
data-lang="en"
|
||
|
data-loading="lazy"
|
||
|
crossorigin="anonymous"
|
||
|
async>
|
||
|
</script>
|
||
|
```
|
||
|
|
||
|
!!! example "Configure the code needed to embed Giscus into your blog"
|
||
|
|
||
|
Go to the [Giscus homepage] and configure the embedding code. There are a
|
||
|
number of settings:
|
||
|
|
||
|
1. Choose the language
|
||
|
2. Enter the username / organization name and repository name
|
||
|
3. Choose how the discussions are to be mapped to the page on your blog.
|
||
|
Because for a blog post the title is the basis of the URL, it makes
|
||
|
sense to use the `Discussion title contains page <title>` option.
|
||
|
4. Under `Discussion Category` choose `Announcements` to limit the creation
|
||
|
of new discussions to Giscuss and people with maintainer or admin
|
||
|
permissions.
|
||
|
5. Under `Features`, select the following:
|
||
|
1. Enable reactions for the main post
|
||
|
2. Emit discussion metadata
|
||
|
3. Place the comment box above the comments
|
||
|
6. Under `Theme`, select `Preferred color scheme` so that Giscus matches
|
||
|
the color scheme selected by the user for your site.
|
||
|
|
||
|
[Giscus homepage]: https://giscus.app/
|
||
|
|
||
|
With these settings in place, you now need to integrate the code into your
|
||
|
site. There is a partial `partials/comments.html` that exists for this purpose
|
||
|
and is empty be default. It is included by the `content.html` partial, so will
|
||
|
be included for every page on your site. You may or may not want this. In this
|
||
|
tutorial, you will limit the Giscus integration to only blog posts but it is
|
||
|
easy enough to leave out the code that achieves this if you want to have Giscus
|
||
|
discussions active for every page.
|
||
|
|
||
|
!!! example "Add Giscus integration code"
|
||
|
|
||
|
First, you need to create an `overrides` directory that will contain the
|
||
|
templates and partials you want to override.
|
||
|
|
||
|
```
|
||
|
mkdir -p overrides/partials
|
||
|
```
|
||
|
|
||
|
You need to declare it in your `mkdocs.yaml`:
|
||
|
|
||
|
```yaml hl_lines="3"
|
||
|
theme:
|
||
|
name: material
|
||
|
custom_dir: overrides
|
||
|
```
|
||
|
|
||
|
Now add a file `overrides/partials/comments.html` and paste in the code
|
||
|
snippet you obtained from the Giscus homepage. Look at the result locally
|
||
|
and you will see that the integration is active on all pages of the site.
|
||
|
If you want to restrict it to your blog posts, you need to add a conditional
|
||
|
around the Giscus script that tests if comments should be included. A simple
|
||
|
way of doing this is to test for a metadata flag:
|
||
|
|
||
|
```html
|
||
|
{% if page.meta.comments %}
|
||
|
<script>...</script>
|
||
|
{% endif %}
|
||
|
```
|
||
|
|
||
|
The disadvantage is that you now need to manually turn on comments for each
|
||
|
blog post - unless you want to turn them off on some. To get the comments
|
||
|
section on all blog posts, use code like this:
|
||
|
|
||
|
```html
|
||
|
{% if page.file.src_uri.startswith('blog/posts') %}
|
||
|
<script>...</script>
|
||
|
{% endif %}
|
||
|
```
|
||
|
|
||
|
You should see now that the Giscus comments are added at the bottom of your
|
||
|
blog posts but not on other pages.
|
||
|
|
||
|
## What's next?
|
||
|
|
||
|
This is the end of the blog tutorial. We hope you have enjoyed it and manage to
|
||
|
set up your blog the way you like it. There are numerous other features and
|
||
|
options that we have not been able to cover here. The [blog plugin reference]
|
||
|
provides comprehensive documentation for the plugin. You may also want to
|
||
|
look at the [social plugin tutorial] to generate social cards for your blog
|
||
|
posts that get displayed when you post links to social media systems.
|
||
|
|
||
|
[blog plugin reference]: https://squidfunk.github.io/mkdocs-material/plugins/blog/
|
||
|
[social plugin tutorial]: ../social/basic.md
|