Skip to content

Commit 50d7c54

Browse files
alexvosssquidfunk
andauthored
Added blog and social cards tutorials (#7014)
* added tutorials page and blog tutorial * proof reading, some language improvements * split blog tutorial into parts and reworked on the basis of comments, improved language, added missing things * + custom slugify function example * +blog tutorial on engagement * + section blog ToC * + instructions for X/FB share buttons and started discussion system * fix: module name `code` shadowed Python standard library module * added What's next section * +blog tutorial engagement part * fix: updated Giscus code snippet * trying multiple tutorials with headings for each group * + basic social cards tutorial * + custom social card tutorial * + estimated time for custom card tutorial * added tutorial sections to nav * fixed typos, removed sponsor icon from level one heading * removed "tutorial" from level one heading * added headings to custom layout example * fixed broken link * fixes after run-through, added links to template repos * added comment for @squidfunk * clarified use of logos, some proof-reading * removed question I left for @squidfunk * clarified relationship between background color and image * added override for the background image * fixed wording and indentation * changed example to be releases, not events * being more specific where to add the last bit of code in the layout --------- Co-authored-by: squidfunk <[email protected]>
1 parent c8ee11f commit 50d7c54

File tree

7 files changed

+1682
-0
lines changed

7 files changed

+1682
-0
lines changed

docs/tutorials/blogs/basic.md

+375
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
# Basic blogs
2+
3+
Blogs are a great way to engage with your audience. Software developers can use
4+
a blog to announce new features, demonstrate their usage and provide background
5+
information. You can demonstrate competence by commenting on the state of the
6+
art or document your own work as best practice. Posts on current topics can help
7+
draw in visitors for your main website and can keep your audience engaged. Of
8+
course, you can blog about any topics close to your heart.
9+
10+
The [blog plugin] makes running a blog alongside your other content easy but you
11+
can also configure it to run a stand-alone blog if posts are the only kind
12+
of content you need.
13+
14+
After a brief overview of the basic concepts of a blog, this tutorial guides you
15+
through the process of configuring the [blog plugin], setting up your blog,
16+
creating posts, and defining post metadata.
17+
18+
[blog plugin]: ../../plugins/blog.md
19+
20+
__Time required:__ typically 20 minutes
21+
22+
## Key concepts
23+
24+
**Post, excerpt**: a blog consists of a number of self-contained _posts_ (often called
25+
articles) and an index page that shows the posts in reverse chronological order, with
26+
the most recent post at the top. The index page usually shows only a short _excerpt_ and a
27+
link that the user can click to navigate to the full post.
28+
29+
**Metadata**: both the index page and the post itself list information such as
30+
when you published the post, when you updated it, who the author is, and what the
31+
expected reading time is.
32+
33+
**Slug**: since the blog posts are primarily arranged by time and not into a hierarchy,
34+
their URLs do not reflect such a structure. Instead, each post's URL
35+
contains a shortened description, the _slug_, which is usually derived from
36+
the first heading in the post.
37+
38+
**Navigation**: the main navigation structure is the timeline, which you can
39+
subdivide into _categories_. The main index page shows the more recent posts
40+
while an _archive_ section allows access to older ones, organized by year.
41+
In addition, posts can be _tagged_ and _tag index pages_ provide an additional
42+
navigation structure based on content.
43+
44+
You can see all these elements on the [Material for MkDocs blog].
45+
46+
[Material for MkDocs blog]: https://squidfunk.github.io/mkdocs-material/blog/
47+
48+
## Setting up your blog
49+
50+
The blog plugin is part of Material for MkDocs but you need to configure it
51+
in the `mkdocs.yml`.
52+
53+
!!! example "Set up a blog"
54+
55+
If you have not done so already, create a project for your blog,
56+
then edit the `mkdocs.yml` file to make sure if has the following content:
57+
58+
```yaml
59+
site_name: Blog Tutorial
60+
site_description: an example blog set up following the tutorial
61+
site_url: http://www.example.com
62+
63+
theme:
64+
name: material
65+
66+
plugins:
67+
- search
68+
- blog
69+
```
70+
71+
The blog plugin will create a directory structure for your blog posts if it
72+
does not exist, so simply run `mkdocs serve` to get:
73+
74+
```
75+
docs
76+
├── blog
77+
│   ├── index.md
78+
│   └── posts
79+
└── index.md
80+
```
81+
82+
Now create your first blog post in `docs/blog/posts`. You can use any
83+
naming convention and directory structure you like for your posts, as long as
84+
they are inside `docs/blog/posts`.
85+
86+
Each post _must_ have a page header, which appears at the top of the Markdown
87+
code between lines with three dashes. Within this header, you need to have at
88+
least a `date` entry but you can add other data, as you will see below.
89+
Following the header comes the page content. Note that it is important
90+
to have a level one heading as the plugin uses it to produce the _slug_. Also,
91+
by adding `<!-- more -->` to the page, you can define where the excerpt will end
92+
that the index page shows.
93+
94+
!!! example "Write your first post"
95+
96+
Create a file `docs/blog/posts/myfirst.md` with the following contents:
97+
98+
```
99+
---
100+
date:
101+
created: 2023-12-31
102+
---
103+
104+
# Happy new years eve!
105+
106+
We hope you are all having fun and wish you all the best for the new year!
107+
<!-- more -->
108+
109+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
110+
tempor incididunt ut labore et dolore magna aliqua.
111+
```
112+
113+
Then, run `mkdocs serve` and point your web browser at
114+
`http://localhost:8000/blog`.
115+
116+
The blog plugin automatically creates navigation elements for
117+
the blog. The index page shows only the extract. When you select the
118+
"Continue reading" link, you will get to the full blog post. Note how it
119+
has a URL generated from the first-level heading.
120+
121+
!!! tip "Navigation"
122+
123+
We also have a [tutorial on navigation] that shows you how to change the
124+
automatically created navigation and integrate the blog into your existing
125+
navigation structure. It shows how to create secondary nagigation, produce
126+
author pages, and control pagination.
127+
128+
[tutorial on navigation]: navigation.md
129+
130+
## Post metadata
131+
132+
In addition to the date, you can provide other metadata and give the plugin
133+
instructions, such as to treat a post as a draft or to pin it.
134+
135+
### Drafts
136+
137+
You may want to produce a draft of a blog post and work with it locally but
138+
exclude it from the build that you publish. Simply add a field to the page
139+
header to indicate that a post is still in draft form.
140+
141+
!!! example "Create a draft"
142+
143+
Create a second blog post in `docs/blogs/posts/draft.md` with the following
144+
contents:
145+
146+
```hl_lines="3"
147+
---
148+
date:
149+
created: 2024-01-01
150+
draft: true
151+
---
152+
153+
# Happy new year!
154+
155+
Happy 2024 to everyone. Wishing you all the best!
156+
<!-- more -->
157+
158+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
159+
tempor incididunt ut labore et dolore magna aliqua.
160+
```
161+
162+
Now, note how the draft appears on the index page but with a label that
163+
indicates that it is a draft. When you run `mkdocs build`, the draft will
164+
_not_ appear in the output:
165+
166+
```
167+
$ mkdocs build
168+
$ ls site/blog
169+
site/blog
170+
├── 2023
171+
│   └── 12
172+
│   └── 31
173+
│   └── happy-new-years-eve
174+
│   └── index.html
175+
...
176+
```
177+
178+
The first blog post for 2024 is not there yet because it is still in draft
179+
stage. Remember to remove the `draft` setting in the header when it is time
180+
to publish it.
181+
182+
If you are using the [Insiders Edition], you can also create
183+
a folder to keep your drafts in and use the [Meta plugin] to add the
184+
`draft` header setting to all the posts in that folder. This has the advantage
185+
that it is easier to see which posts are still in draft form. We will cover the
186+
Meta plugin later on.
187+
188+
[Meta plugin]: ../../plugins/meta.md
189+
190+
### Edits
191+
192+
Sometimes, bloggers need to update a post. This might happen when you make
193+
a mistake or when something changes that you need to reflect in the post. To
194+
indicate you have edited a post, you can include an `updated` date in the page
195+
header.
196+
197+
!!! example "Editing a post"
198+
199+
Make a change to your first blog post, then add an edit date to the header:
200+
201+
```hl_lines="3 4"
202+
---
203+
date:
204+
created: 2023-12-31
205+
updated: 2024-01-02
206+
---
207+
```
208+
209+
The Metadata section of the blog post itself will contain the edit date,
210+
though the index page omits this detail by default.
211+
212+
### Reading time
213+
214+
To give the reader some idea of how long it might take them to read a post,
215+
a read time is automatically calculated. If you want to override this, you can
216+
do so in the page header by specifying the number of minutes you estimate
217+
your readers will take the read the post.
218+
219+
!!! example "Overriding the reading time"
220+
221+
Add a reading time override to your first blog post:
222+
223+
```hl_lines="5"
224+
---
225+
date:
226+
created: 2023-12-31
227+
updated: 2024-01-02
228+
readtime: 15
229+
---
230+
```
231+
232+
### Pinning
233+
234+
Sometimes, blog authors want to 'pin' a specific post so that it will always
235+
appear at the top of the index page, no matter what else gets published. If you
236+
are using the [Insiders Edition], you can achieve this by adding the `pin`
237+
attribute in the page header:
238+
239+
!!! example "Pin a post <!-- md:sponsors -->"
240+
241+
Add the `pin` attribute to your first blog post:
242+
243+
```hl_lines="5"
244+
---
245+
date:
246+
created: 2023-12-31
247+
updated: 2024-01-02
248+
readtime: 15
249+
pin: true
250+
---
251+
```
252+
253+
Observe how this makes the post appear on top of the index page even though
254+
its publication date is prior to other posts. A small pin icon shows that the
255+
post has been pinned.
256+
257+
### Related links <!-- md:sponsors -->
258+
259+
When your blog is part of a wider site such as technical documentation, you
260+
will want to provide links from blog posts into your other content. One way you
261+
can do this is to have a related links section. In the [Insiders Edition], the
262+
blog plugin can create one for you if you provide link targets in your page
263+
header:
264+
265+
!!! example "Add a related links section <!-- md:sponsors -->"
266+
267+
Add the following to a blog post:
268+
269+
``` hl_lines="5-7"
270+
---
271+
date:
272+
created: 2023-12-31
273+
...
274+
links:
275+
- index.md
276+
- blog/index.md
277+
---
278+
```
279+
280+
The related links appear underneath the Metadata section.
281+
282+
The nice thing here is that you do not need to provide a page title. The plugin
283+
will deduce the link text by applying the same logic that MkDocs uses for the
284+
main navigation. In fact, the syntax is the same as that of the `nav` section
285+
in the `mkdocs.yml`, so you can override the title if you want and even define
286+
subsections:
287+
288+
!!! example "Override the page titles"
289+
290+
Change the link section to override the page titles:
291+
292+
```hl_lines="6-9"
293+
---
294+
date:
295+
created: 2023-12-31
296+
...
297+
links:
298+
- Homepage: index.md
299+
- Blog index: blog/index.md
300+
- External links:
301+
- Material documentation: https://squidfunk.github.io/mkdocs-material
302+
---
303+
```
304+
305+
The plugin renders related links in the left sidebar on screens that are wide
306+
enough and at the bottom of the post on narrow screens. Change the size of your
307+
browser window to see this in action.
308+
309+
## Meta plugin <!-- md:sponsors -->
310+
311+
The Meta plugin is available in the [Insiders Edition].
312+
It helps simplify the management of metadata that is common to a group of
313+
files in the same subdirectory. Instead of having to repeat the
314+
same metadata in the page headers of a number of files, you can add a
315+
`.meta.yml` file in the directory and the Meta plugin will merge its contents
316+
into the headers of all the pages contained.
317+
Settings from the page header take precedence, so you can always override
318+
settings by adding them to a post's header.
319+
320+
For example, you may want to manage drafts by keeping them in a directory
321+
together so that they are not only flagged as drafts but also easier to find.
322+
(Otherwise, you would need to inspect the page headers or trace back from the
323+
output to the files to figure out which posts are drafts.)
324+
325+
!!! example "Drafts using the Meta plugin <!-- md:sponsors -->"
326+
327+
You first need to activate the plugin in your `mkdocs.yaml`:
328+
329+
```yaml hl_lines="4"
330+
plugins:
331+
- search
332+
- blog
333+
- meta
334+
```
335+
336+
Now create the folder for the drafts:
337+
338+
=== "MacOS/Linux"
339+
340+
```bash
341+
$ mkdir docs/blog/posts/drafts
342+
```
343+
344+
=== "Windows"
345+
TODO
346+
347+
Now, within this folder, crate a file `.meta.yml` that contains:
348+
349+
```yaml
350+
draft: true
351+
```
352+
353+
Add another blog post and store it in `docs/blog/posts/drafts`. When you
354+
look at it locally, you will see the label that identifies it as a draft,
355+
while in the version built for publication it does not appear. To move a
356+
post from draft status to published, simply move it outside `drafts/`.
357+
358+
[Insiders Edition]: ../../insiders/index.md
359+
360+
## What's next?
361+
362+
You should now have a working blog. However, as it accumulates content, you
363+
may want to make sure that people can find posts they are interested in, so
364+
you may want to add secondary navigation with tags and categories. You may
365+
have more than one author and want to attribute posts to them as well as
366+
generate author pages for them. We have a [tutorial on navigation, pagination,
367+
and authors] that covers these topics.
368+
369+
[tutorial on navigation, pagination, and authors]: navigation.md
370+
371+
You may want to increase engagement with your blog by allowing people to
372+
subscribe to an RSS feed or by setting up a comment system. The [engagement
373+
and dissemination tutorial] walks you through setting these up.
374+
375+
[engagement and dissemination tutorial]: engage.md

0 commit comments

Comments
 (0)