1
0
mirror of https://github.com/squidfunk/mkdocs-material.git synced 2024-12-18 18:36:07 +01:00
mkdocs-material/docs/tutorials/blogs/engage.md
Peter Barber 117e35d1a5
Documentation (#7679)
Should publish new blog post not public new blog post
2024-11-08 14:10:50 +01:00

14 KiB

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 publish 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.

!!! 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.

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.

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://x.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.

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

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:

<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.

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.