# Basic blogs Blogs are a great way to engage with your audience. Software developers can use a blog to announce new features, demonstrate their usage and provide background information. You can demonstrate competence by commenting on the state of the art or document your own work as best practice. Posts on current topics can help draw in visitors for your main website and can keep your audience engaged. Of course, you can blog about any topics close to your heart. The [blog plugin] makes running a blog alongside your other content easy but you can also configure it to run a stand-alone blog if posts are the only kind of content you need. After a brief overview of the basic concepts of a blog, this tutorial guides you through the process of configuring the [blog plugin], setting up your blog, creating posts, and defining post metadata. [blog plugin]: ../../plugins/blog.md __Time required:__ typically 20 minutes ## Key concepts **Post, excerpt**: a blog consists of a number of self-contained _posts_ (often called articles) and an index page that shows the posts in reverse chronological order, with the most recent post at the top. The index page usually shows only a short _excerpt_ and a link that the user can click to navigate to the full post. **Metadata**: both the index page and the post itself list information such as when you published the post, when you updated it, who the author is, and what the expected reading time is. **Slug**: since the blog posts are primarily arranged by time and not into a hierarchy, their URLs do not reflect such a structure. Instead, each post's URL contains a shortened description, the _slug_, which is usually derived from the first heading in the post. **Navigation**: the main navigation structure is the timeline, which you can subdivide into _categories_. The main index page shows the more recent posts while an _archive_ section allows access to older ones, organized by year. In addition, posts can be _tagged_ and _tag index pages_ provide an additional navigation structure based on content. You can see all these elements on the [Material for MkDocs blog]. [Material for MkDocs blog]: https://squidfunk.github.io/mkdocs-material/blog/ ## Setting up your blog The blog plugin is part of Material for MkDocs but you need to configure it in the `mkdocs.yml`. !!! example "Set up a blog" If you have not done so already, create a project for your blog, then edit the `mkdocs.yml` file to make sure if has the following content: ```yaml site_name: Blog Tutorial site_description: an example blog set up following the tutorial site_url: http://www.example.com theme: name: material plugins: - search - blog ``` The blog plugin will create a directory structure for your blog posts if it does not exist, so simply run `mkdocs serve` to get: ``` docs ├── blog │   ├── index.md │   └── posts └── index.md ``` Now create your first blog post in `docs/blog/posts`. You can use any naming convention and directory structure you like for your posts, as long as they are inside `docs/blog/posts`. Each post _must_ have a page header, which appears at the top of the Markdown code between lines with three dashes. Within this header, you need to have at least a `date` entry but you can add other data, as you will see below. Following the header comes the page content. Note that it is important to have a level one heading as the plugin uses it to produce the _slug_. Also, by adding `` to the page, you can define where the excerpt will end that the index page shows. !!! example "Write your first post" Create a file `docs/blog/posts/myfirst.md` with the following contents: ``` --- date: created: 2023-12-31 --- # Happy new years eve! We hope you are all having fun and wish you all the best for the new year! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ``` Then, run `mkdocs serve` and point your web browser at `http://localhost:8000/blog`. The blog plugin automatically creates navigation elements for the blog. The index page shows only the extract. When you select the "Continue reading" link, you will get to the full blog post. Note how it has a URL generated from the first-level heading. !!! tip "Navigation" We also have a [tutorial on navigation] that shows you how to change the automatically created navigation and integrate the blog into your existing navigation structure. It shows how to create secondary nagigation, produce author pages, and control pagination. [tutorial on navigation]: navigation.md ## Post metadata In addition to the date, you can provide other metadata and give the plugin instructions, such as to treat a post as a draft or to pin it. ### Drafts You may want to produce a draft of a blog post and work with it locally but exclude it from the build that you publish. Simply add a field to the page header to indicate that a post is still in draft form. !!! example "Create a draft" Create a second blog post in `docs/blogs/posts/draft.md` with the following contents: ```hl_lines="3" --- date: created: 2024-01-01 draft: true --- # Happy new year! Happy 2024 to everyone. Wishing you all the best! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ``` Now, note how the draft appears on the index page but with a label that indicates that it is a draft. When you run `mkdocs build`, the draft will _not_ appear in the output: ``` $ mkdocs build $ ls site/blog site/blog ├── 2023 │   └── 12 │   └── 31 │   └── happy-new-years-eve │   └── index.html ... ``` The first blog post for 2024 is not there yet because it is still in draft stage. Remember to remove the `draft` setting in the header when it is time to publish it. If you are using the [Insiders Edition], you can also create a folder to keep your drafts in and use the [Meta plugin] to add the `draft` header setting to all the posts in that folder. This has the advantage that it is easier to see which posts are still in draft form. We will cover the Meta plugin later on. [Meta plugin]: ../../plugins/meta.md ### Edits Sometimes, bloggers need to update a post. This might happen when you make a mistake or when something changes that you need to reflect in the post. To indicate you have edited a post, you can include an `updated` date in the page header. !!! example "Editing a post" Make a change to your first blog post, then add an edit date to the header: ```hl_lines="3 4" --- date: created: 2023-12-31 updated: 2024-01-02 --- ``` The Metadata section of the blog post itself will contain the edit date, though the index page omits this detail by default. ### Reading time To give the reader some idea of how long it might take them to read a post, a read time is automatically calculated. If you want to override this, you can do so in the page header by specifying the number of minutes you estimate your readers will take the read the post. !!! example "Overriding the reading time" Add a reading time override to your first blog post: ```hl_lines="5" --- date: created: 2023-12-31 updated: 2024-01-02 readtime: 15 --- ``` ### Pinning Sometimes, blog authors want to 'pin' a specific post so that it will always appear at the top of the index page, no matter what else gets published. If you are using the [Insiders Edition], you can achieve this by adding the `pin` attribute in the page header: !!! example "Pin a post " Add the `pin` attribute to your first blog post: ```hl_lines="5" --- date: created: 2023-12-31 updated: 2024-01-02 readtime: 15 pin: true --- ``` Observe how this makes the post appear on top of the index page even though its publication date is prior to other posts. A small pin icon shows that the post has been pinned. ### Related links When your blog is part of a wider site such as technical documentation, you will want to provide links from blog posts into your other content. One way you can do this is to have a related links section. In the [Insiders Edition], the blog plugin can create one for you if you provide link targets in your page header: !!! example "Add a related links section " Add the following to a blog post: ``` hl_lines="5-7" --- date: created: 2023-12-31 ... links: - index.md - blog/index.md --- ``` The related links appear underneath the Metadata section. The nice thing here is that you do not need to provide a page title. The plugin will deduce the link text by applying the same logic that MkDocs uses for the main navigation. In fact, the syntax is the same as that of the `nav` section in the `mkdocs.yml`, so you can override the title if you want and even define subsections: !!! example "Override the page titles" Change the link section to override the page titles: ```hl_lines="6-9" --- date: created: 2023-12-31 ... links: - Homepage: index.md - Blog index: blog/index.md - External links: - Material documentation: https://squidfunk.github.io/mkdocs-material --- ``` The plugin renders related links in the left sidebar on screens that are wide enough and at the bottom of the post on narrow screens. Change the size of your browser window to see this in action. ## Meta plugin The Meta plugin is available in the [Insiders Edition]. It helps simplify the management of metadata that is common to a group of files in the same subdirectory. Instead of having to repeat the same metadata in the page headers of a number of files, you can add a `.meta.yml` file in the directory and the Meta plugin will merge its contents into the headers of all the pages contained. Settings from the page header take precedence, so you can always override settings by adding them to a post's header. For example, you may want to manage drafts by keeping them in a directory together so that they are not only flagged as drafts but also easier to find. (Otherwise, you would need to inspect the page headers or trace back from the output to the files to figure out which posts are drafts.) !!! example "Drafts using the Meta plugin " You first need to activate the plugin in your `mkdocs.yaml`: ```yaml hl_lines="4" plugins: - search - blog - meta ``` Now create the folder for the drafts: === "MacOS/Linux" ```bash $ mkdir docs/blog/posts/drafts ``` === "Windows" TODO Now, within this folder, crate a file `.meta.yml` that contains: ```yaml draft: true ``` Add another blog post and store it in `docs/blog/posts/drafts`. When you look at it locally, you will see the label that identifies it as a draft, while in the version built for publication it does not appear. To move a post from draft status to published, simply move it outside `drafts/`. [Insiders Edition]: ../../insiders/index.md ## What's next? You should now have a working blog. However, as it accumulates content, you may want to make sure that people can find posts they are interested in, so you may want to add secondary navigation with tags and categories. You may have more than one author and want to attribute posts to them as well as generate author pages for them. We have a [tutorial on navigation, pagination, and authors] that covers these topics. [tutorial on navigation, pagination, and authors]: navigation.md You may want to increase engagement with your blog by allowing people to subscribe to an RSS feed or by setting up a comment system. The [engagement and dissemination tutorial] walks you through setting these up. [engagement and dissemination tutorial]: engage.md