Bringing some structure into the theme: The Sidebar

Now that we have fonts and colors, we can start with the structure of the theme. Giving a page a clear structure is fundamental to enable it to be responsive later on.

Waipoua structure

The Waipoua theme is roughly structured as followed:

  • header (red background)
    • home icon
    • navigation
    • search
  • wrapper
    • second header
      • site title
      • site tagline
      • alternative: site icon added through theme options page
      • social media icons
    • content
    • sidebar (light gray background)
    • footer

The main idea of the wrapper is getting some padding on the left and right, when the display gets smaller. The red header will at a certain breakpoint become a single hamburger menu icon, that it will open a vertically sliding down navigation and search (the home icon is missing in this menu).

Blank theme structure

Now let’s look on the structure from our blank theme. This is what you get from the boilerplate (simplified):

  • header
    • site icon
    • site title
    • site tagline
    • navigation
  • content
  • footer

Comparing this to the Waipoua theme, it is a lot simpler. But we can already see something missing: the sidebar.

Adding a sidebar

Sidebars are something you don’t see too much anymore on current websites. But for a blog theme, they still make sense in my opinion. And since I’m rebuilding a theme that has one, I have to add it. Well, the theme even has an option to have two sidebars. The second one site between the content and the main sidebar showing all sticky posts:

A screenshot showing the front page with the content on the left, taking up about 40% of the width, the sidebars with the headline "featured posts" in the middle and the main sidebar on the right.

I couldn’t find a way to allow a selection of which template to use for all pages. Therefore, I decided to go with the single main sidebar for the first version of the theme.

But how do we even get a sidebar? We need an element, that we can use on multiple templates and that would always show the same content. The answer is: we need a “Synced Pattern”. You can create it at “Appearance > Editor > Patterns” where you click on the plus icon next to “Patterns” and select “Create pattern”. In the modal, use a name like “Sidebar” and make sure the “Synced” toggle is activated. After clicking “Create”, we can fill the sidebar. I did this in the following example with the default “widgets” from the classic theme:

Screenshot of the "List View" with all the blocks, each prepended with a heading block and all grouped. On the right in the block settings, a background color and paddings are set.

For the widget titles, I’ve used heading blocks. Some blocks need some settings being adjusted. For the Search block, I put the search button into the field and used the icon. On the Latest Comments block, I deactivated all settings, so it also shows the name and the blog post title.

One thing I’ve missed, when first creating the sidebar: adding a background color and some padding. So we also group the blocks in the sidebar, set the background color to “Background Secondary” and set the “Dimensions > Padding” to “20px” vertically and horizontally.

Placing the sidebar on the page

Now that we have the sidebar, we have to place it on every single template. Let’s start with the front page. We navigate to “Appearance > Editor > Templates” and select “Index” on the right, the only template we have so far. As mentioned earlier, the template is rather simple. It only used a “Query Loop” block as the content. This would be our “left column”. And indeed, we will use the Columns block to get our “content | sidebar” layout. The left columns will contain the Query Loop, the right one the Sidebar pattern. This is the result:

Screenshot of the "Index" template with the "List View" showing the "Query Loop" in the left column and the "Sidebar" pattern in the right one.

Let’s try to explain all the things I did here. First, I put the “Query Loop” into a left column and the “Sidebar” in a right column. The “Columns” block had the “Dimensions > Block Spacing” set to “50px” horizontally. The right “Column” block has a “Settings > Width” of “300px”, as the sidebar has a fixed width. The left “Column” however has an empty width value. This will allow it to take up the remaining width. So we get a responsive left column and a fixed width right column.

The group around the columns block is needed to give it a specific width. Instead of setting the width of this specific group on the “Index” template, we set it in the “Styles > Layout > Dimensions” (using the white/black icon in the top right). Here we set a fixed “Content” width of “1100px”.

The result

OK, after finishing all these steps, let’s see what we got now when visiting the front page of our new theme:

The frontend view of the front page with the two columns: content on the left, sidebar on the right with a light gray background.

Nice! Isn’t it? OK, not really the end result we want. The blocks in the sidebar still don’t look great, but as for today, we should be happy to have our layout with the content and sidebar next to each other done.

Conclusion

When trying this layout for the first time, I struggled a bit to get it as I wanted it. I couldn’t find a way to get those “50px” in between the two columns. I had to add a middle column with “2px” width, which would get “50px” in total with the default “24px” gap. Now, with the newer version of WordPress, we have been able to just set the gap to “50px” and get the result we want. Twenty Twenty-Four is still using columns to get the correct gap. It is even using “empty columns” left and right for some padding. Fortunately, we don’t need that anymore.

For next week, I think I will continue styling the header. We will also need a “widget area” there to place the social media links, and we will also align the elements. This might be tricky, since I haven’t yet found out how to align elements at the bottom.

Adding some colors to the Block Theme

Due to some personal topics, wasn’t able to work on the new theme, or write a new blog post for that matter. But now I’m back and will probably speed up a bit and write more frequently than just every second week. I still want to have my new theme ready by June for the blog birthday.

Adding colors

For many people, having the right (brand) colors makes a theme more recognizable. So let’s start with the main colors first. But before we start adding colors, we first have to deal with one of the hardest things in computer science: naming things.

Color names

There are different philosophies in how to name your colors. Some would go with primary, secondary, tertiary, etc. But as a non-native speaker, and being dyslexic, even the 3rd one is hard to spell correctly. And what is the 4th, 5th, etc. are named? So that why others use named like base, contrast, accent and for multiple variants, they add a numbered suffix, like contrast-2, contrast-3, etc. This is how Twenty Twenty-Four is doing it.

To be honest, I have no idea what the best way to name my colors is. But since this is a “revival” of a ElmaStudio theme, I checked how Ellen and Manuel are doing it right now. Looking at their latest themes Mugistore and SolarOne, they use combined color names like background-primary, font-primary, accent-primary, etc. So I try to go with this as well.

Assigning color values to color names

Now that I decided on which naming scheme to use, I wanted to assign all colors from the Waipoua theme to a color name in the new theme. So I first searched for all colors in the theme and found 26 different colors. That’s quite a lot! But some of those were only used for very specific CSS selectors, and others were used for colored buttons or boxes using shortcodes.

After researching every single color and where they are used, I came up with the following color definitions:

{
	"settings": {
		"color": {
			"defaultPalette": false,
			"palette": [
				{
					"slug": "black",
					"color": "#000000",
					"name": "Black"
				},
				{
					"slug": "white",
					"color": "#ffffff",
					"name": "White"
				},
				{
					"slug": "grey",
					"color": "#909090",
					"name": "Grey"
				},
				{
					"slug": "red",
					"color": "#F55243",
					"name": "Red"
				},

				{
					"slug": "background-primary",
					"color": "#ffffff",
					"name": "Background Primary"
				},
				{
					"slug": "background-secondary",
					"color": "#f6f6f6",
					"name": "Background Secondary"
				},
				{
					"slug": "background-tertiary",
					"color": "#b3b4ae",
					"name": "Background Tertiary"
				},
				{
					"slug": "background-quarternary",
					"color": "#909090",
					"name": "Background Quartenary"
				},

				{
					"slug": "font-primary",
					"color": "#333333",
					"name": "Text Primary"
				},
				{
					"slug": "font-secondary",
					"color": "#4c4a4a",
					"name": "Text Secondary"
				},

				{
					"slug": "primary",
					"color": "#f55243",
					"name": "Brand Primary"
				},

				{
					"slug": "border-primary",
					"color": "#ececec",
					"name": "Border Primary"
				},
				{
					"slug": "border-secondary",
					"color": "#dddddd",
					"name": "Border Secondary"
				},

				{
					"slug": "input-background",
					"color": "#ffffff",
					"name": "Input Background"
				},
				{
					"slug": "input-background-hover",
					"color": "#fcfcfc",
					"name": "Input Background Hover"
				},
				{
					"slug": "input-border",
					"color": "#999999",
					"name": "Input Border"
				},

				{
					"slug": "social-icons-background",
					"color": "#b3b4ae",
					"name": "Social Icons Background"
				},
				{
					"slug": "social-icons-background-hover",
					"color": "#333333",
					"name": "Social Icons Background Hover"
				},

				{
					"slug": "red-btn-box",
					"color": "#e22727",
					"name": "Red Button & Box"
				},
				{
					"slug": "green-btn-box",
					"color": "#71b247",
					"name": "Green Button & Box"
				},
				{
					"slug": "blue-btn-box",
					"color": "#56b3b7",
					"name": "Blue Button & Box"
				},
				{
					"slug": "yellow-btn",
					"color": "#f9d93a",
					"name": "Yellow Button"
				},
				{
					"slug": "yellow-box",
					"color": "#f7ec69",
					"name": "Yellow Box"
				},
				{
					"slug": "white-box",
					"color": "#fff",
					"name": "White Box"
				},
				{
					"slug": "lightgrey-box",
					"color": "#f6f6f6",
					"name": "Lightgrey Box"
				},
				{
					"slug": "grey-btn-box",
					"color": "#d3d3d3",
					"name": "Grey Button & Box"
				},
				{
					"slug": "dark-box",
					"color": "#333",
					"name": "Dark Box"
				},
				{
					"slug": "black-btn",
					"color": "#000",
					"name": "Black Button"
				}
			]
		}
	}
}

In total, these are 29 color definitions. If you open up the color picker in the block editor, like on a paragraph block, this is what you would see:

The color picker with the 29 defined colors, with some of them being shown multiple times.

Some of the colors are “double”, but this is also how the other ElmaStudio themes do it, and I think it’s a good idea. Let’s say you want to change the social icons color only, then you can do this by changing the two specific color values. It would also be possible in the “style book”, but this is easier, especially in a customization or child theme.

Using the colors

Now that we have some colors, let’s use some of them. To get a bit more “branding” into the theme, we could start with the color for the header. As we will create the correct markup for it a bit later, let’s start with setting them in the site editor:

Screenshot of the Site Editor with the header template opened and the colors for the first group block set as described.

How do we get to this result? First, we navigate to “Appearance > Editor”. Then click into the header twice and click on the “Edit” button. Another way to get into the header template is “Appearance > Editor > Patterns >Header”, then select the header you want to edit (we currently have only one) and either click on the “edit icon” (the pencil) in the top left or simple on the header in the main window.

We now open the “List View” and select the top “Group” block. On the right, we select the “Block” settings and the “Styles” tab (the black/white circle). For the “Background” color, we select the “Brand Primary” color (red). Then we click on the “Text” color.

Since the Waipou theme is using a white with a 75% opacity, we first select “White” (the second color in the top row). After that, we click on the “preview area”, this is the white (in the screenshot with the “checkered pattern”) square above the one with “White #FFFFFF” (in the screenshot “Custom #FFFFFFBF”) in it. Now we can either type in a HEX code with an opacity (in this case “#FFFFFFBF”), or we click on the dropdown and select RGB or HSL and change the “A” value to “75”. This should give us the result in the screenshot.

I hope you were able to follow along. Having screenshots for every single step would have been too much. Maybe next time I have to record a video. πŸ˜€

Save changes to the theme

All the changes we have done to the header are saved into the database. They do not reflect in our theme files. To get the changes from the header template, we could just copy the raw HTML from the site editor and save it to our file. We can then safely reset the customizations in the site editor.

An easier way is using the Create Block Theme plugin again. It adds an icon into the site editor, that allows you to download the current state of the theme as a ZIP file or to save the changes directly into the theme’s folder. But be aware that this overwrites all the files. I hope you are all using version control and a good IDE, then it’s not too much of an issue, but still be careful.

Screenshot showing the "Create Block Theme" options to "Save Changes" and "Export Zip" with an alter indicating, that changes have been saved successfully.

After clicking on the “wrench” icon, it will open the “Create Block Theme” plugin page. You can now click on the “Save Changes” button. This will save everything – not just the current template/part – to the theme and reset the customizations in the database.

We are going to use this option every time we made any changes to the theme using the Site Editor. Sure, we could always just write code directly into the theme.json or other files, but why would we, when instead we can more easily just build the theme in the Site Editor with a live preview.

Conclusion

Setting some colors sounds easy, but there is some planning involved as well. You want to make sure you got this right, before you start using your colors all over the place, as changing this later on might add a lot of extra work.

Now that we have made our first changes using the Site Editor, we are going to set the layout in the next step. That would be columns/sidebars, page width, elements in header and footer, etc. There were some things I didn’t though would be possible, but with WordPress 6.5 just being released, it might become easier. If that worked out, you will see in the next blog post.

Adding fonts to our block theme

After we’ve created the raw theme in the last blog post, it’s time to add some basic things to our theme. To quickly get some similar appearance, let’s start with fonts.

My blog is using the default fonts from Waipoua, but I have changed the main colors in a child theme. This is how the theme looks like with no customizations:

Screenshot of the original design of the Waipoua theme, showing the blog listings front page with social icons in the top right and the gray sidebar on the right.

As you can see here, I’ve changed the red tone of the header, the background color of the sidebar, and I’ve also colored the social icons in the top right widget area. The rest looks pretty much like in the parent theme.

Adding the fonts

Now, this is an interesting chapter. As of today, you would usually do the following:

  1. Download the fonts – for Google Fonts, I usually use theΒ google-webfonts-helper and download all variants
  2. Save fonts in a folder in your theme
  3. Define the fonts in the theme.json file

If you want to follow this manual path, there is an excellent guide from Carolina on the “Full Site Editing With WordPress” site.

But since there is a new way of adding fonts to a block theme coming up, let’s try this way. With the current WordPress version 6.4, you have to install the Gutenberg plugin in order to use this option, since it is not yet “final” and therefore hasn’t been merged into Core with WordPress 6.4, so we have to wait a little longer.

With Gutenberg installed and activated, navigate to “Appearance > Manage Theme Fonts”. Here you will find the following view:

Screenshot of the "Manage Theme Fonts" admin page, showing the current fonts in a list on the right, a preview area in the middle and buttons to add Google and local fonts.

Here you find an overview of all theme fonts on the right as well as preview area for these fonts. In the top right, you can use the buttons “Add Google Font” or “Add Local Font” to add a new font family to your theme.

Let’s add the font family for headlines first, which is the Google Font “Oswald”. We click the button “Add Google Font” and then search in the “Select Font” dropdown for the font. We are then presented with all available variants. I’ve just clicked the checkbox in the table header to select all of them:

Screenshot of the "Add Google font to your theme" admin page, showing the available variants.

The Waipoua theme only included the 400 weight variant, but as with a block theme you have more control on which font you use where, I think it’s best to have all the variants available, so which ever weight (and style, if available) is used, the text looks best.

After clicking the “Add Google fonts to your theme” button, you should see a success message like “Oswald font added to Kauri theme”. Now we do the same for the “PT Sans” font, again selecting all the variants.

If we navigate back to the “Manage Theme Fonts” admin page, we should see those new fonts in the right sidebar and a preview of them. In total, we have added 2 fonts with a total of 10 variants and a total size of 1.5 MB:

Screenshot of the "Manage Theme Fonts" admin page, showing the fonts imported in the previous step.

Result of the fonts import

Now what did we get after this step? Let’s take a look at the themes folder structure first:

$ tree .
.
β”œβ”€β”€ assets
β”‚Β Β  └── fonts
β”‚Β Β      β”œβ”€β”€ oswald_normal_200.ttf
β”‚Β Β      β”œβ”€β”€ oswald_normal_300.ttf
β”‚Β Β      β”œβ”€β”€ oswald_normal_400.ttf
β”‚Β Β      β”œβ”€β”€ oswald_normal_500.ttf
β”‚Β Β      β”œβ”€β”€ oswald_normal_600.ttf
β”‚Β Β      β”œβ”€β”€ oswald_normal_700.ttf
β”‚Β Β      β”œβ”€β”€ pt-sans_italic_400.ttf
β”‚Β Β      β”œβ”€β”€ pt-sans_italic_700.ttf
β”‚Β Β      β”œβ”€β”€ pt-sans_normal_400.ttf
β”‚Β Β      └── pt-sans_normal_700.ttf
β”œβ”€β”€ parts
β”‚Β Β  β”œβ”€β”€ footer.html
β”‚Β Β  └── header.html
β”œβ”€β”€ readme.txt
β”œβ”€β”€ screenshot.png
β”œβ”€β”€ style.css
β”œβ”€β”€ templates
β”‚Β Β  └── index.html
└── theme.json

We do have a new folder “assets/fonts” and in this folder we can find the Google fonts. As these can only be downloaded in the TTF format from fonts.google.com, this is what we also get with the (current) font management solution in Gutenberg.

But let’s take a look at the theme.json file, because this is the more interesting part of this whole step. You should now see something like this:

{
	"settings": {
		"typography": {
			"fontFamilies": [
				{
					"fontFamily": "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif",
					"name": "System Font",
					"slug": "system-font"
				},
				{
					"fontFamily": "Oswald",
					"slug": "oswald",
					"fontFace": [
						{
							"fontFamily": "Oswald",
							"fontStyle": "normal",
							"fontWeight": "200",
							"src": [
								"file:./assets/fonts/oswald_normal_200.ttf"
							]
						},
						{
							"fontFamily": "Oswald",
							"fontStyle": "normal",
							"fontWeight": "300",
							"src": [
								"file:./assets/fonts/oswald_normal_300.ttf"
							]
						},
						{
							"fontFamily": "Oswald",
							"fontStyle": "normal",
							"fontWeight": "400",
							"src": [
								"file:./assets/fonts/oswald_normal_400.ttf"
							]
						},
						{
							"fontFamily": "Oswald",
							"fontStyle": "normal",
							"fontWeight": "500",
							"src": [
								"file:./assets/fonts/oswald_normal_500.ttf"
							]
						},
						{
							"fontFamily": "Oswald",
							"fontStyle": "normal",
							"fontWeight": "600",
							"src": [
								"file:./assets/fonts/oswald_normal_600.ttf"
							]
						},
						{
							"fontFamily": "Oswald",
							"fontStyle": "normal",
							"fontWeight": "700",
							"src": [
								"file:./assets/fonts/oswald_normal_700.ttf"
							]
						}
					]
				},
				{
					"fontFamily": "PT Sans",
					"slug": "pt-sans",
					"fontFace": [
						{
							"fontFamily": "PT Sans",
							"fontStyle": "normal",
							"fontWeight": "400",
							"src": [
								"file:./assets/fonts/pt-sans_normal_400.ttf"
							]
						},
						{
							"fontFamily": "PT Sans",
							"fontStyle": "italic",
							"fontWeight": "400",
							"src": [
								"file:./assets/fonts/pt-sans_italic_400.ttf"
							]
						},
						{
							"fontFamily": "PT Sans",
							"fontStyle": "normal",
							"fontWeight": "700",
							"src": [
								"file:./assets/fonts/pt-sans_normal_700.ttf"
							]
						},
						{
							"fontFamily": "PT Sans",
							"fontStyle": "italic",
							"fontWeight": "700",
							"src": [
								"file:./assets/fonts/pt-sans_italic_700.ttf"
							]
						}
					]
				}
			]
		}
	}
}

Following the “System Font” we can find our two new font families with one definition per variant. This is a lot of code that was created for us automatically, so we don’t have to.

If you refresh the page now, we won’t see any change. That’s because we have only imported the fonts into our theme and defined it in the theme.json file, but we are not using them.

Set fonts for body and headings

You can set a font family for the whole page, some “types” of elements or for individual blocks. To get the result we want, the following has to be added to the theme.json file:

{
	"styles": {
		"elements": {
			"heading": {
				"typography": {
					"fontFamily": "var(--wp--preset--font-family--oswald)",
					"fontWeight": "400"
				}
			}
		},
		"typography": {
			"fontFamily": "var(--wp--preset--font-family--pt-sans)",
			"fontWeight": "400"
		}
	}
}

This will set the font for the body and all headlines, so inside the content, as well as the core/site-title, and other “headlines” blocks. We have to fine tune this later, but for the moment, we have the following result:

The front page with the two fonts.

As for fonts, this now looks a lot more like the original theme. But it’s just the first step. We still need to work on many aspects.

Bonus: Use WOFF2 instead of TTF fonts – or both

With the current solution, I really don’t like that it is using TTF fonts. They are usually used on desktop, not on the web. And even though most browsers can use them, they are a lot larger.

Using the google-webfonts-helper, I’ve downloaded all fonts in the WOFF2 format and adjusted the theme.json file accordingly. I’ve also put each font family files into a subfolder, to better organize them.

With these changes, the size of the web fonts could be reduced from 1.5 MB to only around 590 KB, for all variants. So while this step is not absolutely necessary, I would highly recommend to use WOFF2 files. Unless you have to support some really old browsers. Then you can always decide to download them in a different format with the google-webfonts-helper.

You can also keep the TTF files as a fallback. It would then look like this as an example:

{
	"fontFamily": "Oswald",
	"fontStyle": "normal",
	"fontWeight": "200",
	"src": [
		"file:./assets/fonts/oswald/oswald-v53-cyrillic_cyrillic-ext_latin_latin-ext_vietnamese-200.woff2",
		"file:./assets/fonts/oswald/oswald-v53-cyrillic_cyrillic-ext_latin_latin-ext_vietnamese-200.ttf"
	]
}

You can find the full example in the themes’s GitHub repository.

Hidden gem using the “Manage Theme Fonts” functionality

When committing the changes to the theme, I’ve recognized that the readme.txt file was change as well. First I thought, that I’ve probably changed something in this file as well. But then I saw these additions:

Oswald Font
Copyright 2016 The Oswald Project Authors (https://github.com/googlefonts/OswaldFont) 
This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: https://scripts.sil.org/OFL 
License URL: https://scripts.sil.org/OFL 
Source: http://www.sansoxygen.com
-- End of Oswald Font credits --

PT Sans Font
Copyright Β© 2009 ParaType Ltd. All rights reserved. 
Copyright (c) 2010, ParaType Ltd. (http://www.paratype.com/public), with Reserved Font Names "PT Sans", "PT Serif" and "ParaType". 
License URL: http://scripts.sil.org/OFL_web 
Source: http://www.paratype.com
-- End of PT Sans Font credits --

So not only does the functionality take care of downloading the fonts, storing them in your theme, updating your theme.json file. It does also make sure that you have the credits to legally use those fonts in your readme.txt file. How cool is that?! πŸ€“

Summary

Adding Google fonts (or fonts from other sources) can be done in two ways: manually and with the “Manage Theme Fonts” functionality. While the latter is still not “finished”, it worked pretty well with this theme. If they also add an option to download different file formats (or change the default), I can’t wait to see this land in core.

I initially planned to also write about how to set colors and the site width in this blog post, but I think the fonts topic is enough for this one.

Kickoff for my new blog theme

This will be the start of the blog series for my new blog theme. As mentioned in the previous blog post, the goal is to create a theme that comes as close as possible to the current design, while using the Site Editor to create all necessary styles and templates.

Creating the theme

When I developed from scratch in the past, I’ve usually used _s (underscores), but since this is a classic starter theme, I needed something different. Fortunately, there is the “Create Block Theme” plugin, you can use to create a theme from your WordPress installation.

After installing and activating the plugin, navigate to “Appearance > Create Block Theme” and choose the “Create blank theme” option on the left. You are then presented with a form on the right, asking you for name, description, etc. for the new theme. This is the data that is usually found in the style.css header comment.

After filling out the form, click the “Generate” button in the bottom left. This will create the new theme in the WordPress installation. Now you can activate the theme for your site. The result would look like this:

The frontend result of the theme with the site title in the top left, a navigation sith "Sample Page" in the top right, the "Hello World" blog post in the middle, and the "Proudly Power by WordPress" in the bottom, all with no styles.

Isn’t that beautiful? OK, not quite what we need. But we do have a full Block Theme now, and can start adding all the styles we need.

The theme’s file structure

But before we start working on the theme, let’s take a look at what we have. This is the initial file structure of our new theme:

$ tree
.
β”œβ”€β”€ parts
β”‚Β Β  β”œβ”€β”€ footer.html
β”‚Β Β  └── header.html
β”œβ”€β”€ readme.txt
β”œβ”€β”€ screenshot.png
β”œβ”€β”€ style.css
β”œβ”€β”€ templates
β”‚Β Β  └── index.html
└── theme.json

2 directories, 7 files

Not all that much. But we do have template parts for a header and a footer. The only “page template” we have is an index.html file. The style.css file is basically empty, it mainly consists of the header comment with the data from the form. Interestingly, we find a line Requires PHP: 5.7 in this file, even though this PHP version never existed. πŸ˜…

The most important file however is the theme.json file. In this base version, it is only 35 lines long and has definitions for the layout sizes, spacing units, a system font family and the header and footer template parts.

In the next blog posts of this series, we will work with this file quite a lot.

The name of the new theme

You might have recognized, that I have chosen the name “Kauri” for the new theme (and the development site). The current theme of my blog is named Waipoua. Elmastudio named many of their themes after things in New Zealand or Asia. Waipoua Forest is a forest in the Northland Region of New Zealand. This forest shows some examples of kauri trees. And by now you should know why I’ve chosen this name. 😊

Next steps

In the next episode, we will make our initial changes to the theme.json file, maybe adding the fonts or setting the general width of the theme. So stay tuned.

If you want to follow along with the code, you can find the current state on GitHub. But please don’t create any issues or pull requests, before this blog series is finished. 😁

New year, new project, new theme – what’s coming in 2024

It’s not the new “blog year”, but a new on our calendars. In previous years, I often wanted to finally start reworking the theme of my blog over the holidays. This time I finally did it … but only started at 1 January πŸ˜…

Continuing #project26

First things first: I will continue with #project26, posting every two weeks. I usually don’t plan blog posts in advance, but this year I have a second project, I want to follow, so topics will hopefully be easier this year. But I will also post about other topics in between.

A new, old theme

I’m currently using the nice Waipoua theme from Elmastudio. I have been using this theme since July 2012, and I still love its classical blog design. But given how old it is, there are some aspects that don’t make it the perfect theme anymore. Especially, some accessibility issues are reasons to replace it.

Start fresh, but copy the overall look

The optimal outcome would be a theme on a new technical foundation, but with the exact same “pixel perfect” result. As I only want to use the Site Editor for the new theme, that might not be possible. Not being sure about what I would set myself as a goal, I’ve asked around at Twitter:

Click here to display content from Twitter.
Learn more in Twitter’s privacy policy.

From the results and the comments, most people say, I should just try to re-create the overall look of the theme. And this is what I’ll try to do.

A step by step blog post series

For the future blog posts, I’m planning to document every step I take in re-creating the theme. I hope that this will potentially be helpful for many of you with a similar idea. And since I’m usually not creating (new) themes in my daily work, it’s also a great learning opportunity for me, to get more familiar with the Site Editor.

My first long blog series

I’ve had some blog series before, but this one is expected to last well into the second quarter of this year. Maybe I can launch the new theme for the blog’s birthday in June.

I will also try to publish the progress in code in the open and also create a staging site with the current state. But more on this on my next blog post.

If you happen to use that theme as well, I would highly appreciate your feedback on what you would like to see in the new theme. Or maybe you’ve done something similar, then I would be happy if you leave a comment here.

Quick debugging for SSH connections

Once again this week, I had issues connecting to a server using SSH. It was with a different user, and something was just not working. When debugging such issues, I always have to search for that debugging mode, so why not write down the solution on my blog, so I’ll find it faster next time.

Starting an additional OpenSSH daemon in debug mode

You can activate debugging mode on the client side, but often times the issue is on the server. To debug this, you have to run the server part in debug mode. While you can activate this for the main SSH daemon, it is often easier and safer, to start an additional SSH daemon, using a different port, and with debugging activate. To do this, run the following command as root:

/usr/sbin/sshd -ddd -D -p 22222

You need to use the full path to sshd to run this command. With the -D parameter, sshd will not detach and doesn’t become a daemon, so you can see the log output in the terminal. With the -ddd parameter, you turn on the maximum debugging level. And with -p 22222 we will use a different port.

Using client side debugging mode

Now that we have the server part running in debugging mode and waiting for incoming connections, let’s connect to it from a client. We will do so with the following command:

ssh -vvv -p 22222 -i ~/.ssh/id_ed25519 [email protected]

In this example, we are using the previously set port 22222. We also use a custom secret key file we want to test with -i ~/.ssh/id_ed25519 and with -vvv we also use the maximum verbosity in debugging for the client.

Two typical errors for SSH server and client

Now we should be able to find the errors for the server and/or client process. Here are two typical ones, I often come across.

Wrong permissions on the server

Issues with SSH are very often due to wrong file and folder permissions. This is a typical one:

debug1: trying public key file /home/user/.ssh/authorized_keys
debug1: Could not open authorized keys '/home/user/.ssh/authorized_keys': Permission denied

When you see this issue, you might have added the public key correctly to the authorized_keys file, but it is not readable by the SSH daemon. To fix this, make sure to change the folder/file permission to something like this:

chmod 700 /home/user/.ssh/
chmod 644 /home/user/.ssh/authorized_keys

If you got an error in the last attempt to connect, the server process will most probably have died, so make sure to restart it, for the next debug-attempt.

Wrong permissions on the client

On the client, the file permissions are also very often the case of the issues. When the permissions are “too open”, you usually see a message like this on the client:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for 'id_ed25519' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "id_ed25519": bad permissions
debug2: we did not send a packet, disable method
debug1: No more authentication methods to try.
[email protected]: Permission denied (publickey).

The solution to this is similar to the server. You have to make sure, that the permissions are correct, but in this case, you have to limit the access down to only the user for the private key:

chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

The public key can be readable by others as well. So the second command is usually optional.

Conclusion

There are many different issues you may have to face when configuring SSH on a server. It is really strict, when it comes to file and folder permissions, mainly to protect you from sharing secure data with others. If you happen to have a secret key too open, and you share the client/machine with multiple users, it’s probably best to discard the key and create a new one. When you use ssh-keygen to create one, the file permissions are set automatically.

I usually only use SSH nowadays to connect to servers for terminal access and for file transfer. Using key pairs is often the best way to go. But those file permissions can really be a struggle. Hopefully, you now know how to debug those issue – and I do as well, looking up how to start that debugging mode again. πŸ˜€

Show and fix Stylelint errors in PhpStorm while coding

Following coding styles is important, not only when developing for yourself, but even more when working in a team. It means fewer issues, and it also avoids unnecessary changes when using version control, which can easily cause conflicts as well.

I use PhpStorm as my main IDE and when developing WordPress plugins or themes, I nowadays use “wp-scripts” to compile SCSS or JavaScript. This package also comes with “Stylelint“, a command line tool for “linting” of your code.

Running a linter on the command line

You can configure the “lint-style” command from “wp-scripts” in your package.json file. Then you run it like this:

$ npm run lint:style

> @2ndkauboy/[email protected] lint:style
> wp-scripts lint-style


src/style-dark-mode.scss
  5:3   βœ–  Expected empty line before comment  comment-empty-line-before
 11:22  βœ–  Expected a leading zero             number-leading-zero
 22:6   βœ–  Expected indentation of 2 tabs      indentation
 27:9   βœ–  Expected indentation of 2 tabs      indentation
 72:6   βœ–  Expected empty line before at-rule  at-rule-empty-line-before

5 problems (5 errors, 0 warnings)

After running the command, you will find a list of all issues that have been found. They also give you the rule names in the last column. If you want to ignore/exclude some of them in your project, you can use a custom configuration in your project.

Running the tests inside the PhpStorm code editor

While these tools are great to be used on the terminal, or later in CI (like a GitHub Action), those tests usually come only after you made the mistakes and/or even committed them. Wouldn’t it be nice to see the issues earlier? Fortunately, PhpStorm has an integration for Stylelint. You can find it at “Settings | Languages & Frameworks | Style Sheets | Stylelint”. Here you have to “Enable” it and set some configuration parameters.

When you are on Windows, using WSL2, something like this would be the settings you want to use (adjust path for your local setup):

Stylelint package: \wsl$\Ubuntu\home\bernhard\PhpstormProjects\theme-tests\wp-content\plugins\dark-mode-for-astra\node_modules\stylelint
Configuration file: \wsl$\Ubuntu\home\bernhard\PhpstormProjects\theme-tests\wp-content\plugins\dark-mode-for-astra\node_modules\@wordpress\scripts\config.stylelintrc.json
Run for files: **/src/{**/*,*}.{css,scss}

On Linux/Mac, it could look like this (adjust path for your local setup):

Stylelint package: ~/PhpstormProjects/theme-tests/wp-content/plugins/dark-mode-for-astra/node_modules/stylelint
Configuration file: ~/PhpstormProjects/theme-tests/wp-content/plugins/dark-mode-for-astra/node_modules/@wordpress/scripts/config.stylelintrc.json
Run for files: **/src/{**/*,*}.{css,scss}

In this example, I’ve limited the “Run for files” to the src folder only. On my Linux machine, it otherwise tried to check every single CSS/SCSS file in the entire project and killed my machine. If you have used a custom configuration file, like explained before, you can use this file for the “Configuration file” setting. If you don’t have one, use the default one as shown here. When you have set the path of the “Stylelint package” correctly, you should also see its version number in the settings window:

Settings for "Stylelint" showing the version number "14.16.1" at the end of the "Stylelint package" settings line.

Checking issues while you type

Now that we have set up the Stylelint integration, let’s open that file we got errors for to see them in the editor:

The errors shown in the editor, with one of them highlighted, opening a modal showing more details on that error.

In this screenshot, you can see different things regarding the Stylelint errors. On the right scrollbar, you see red indicators for each error found in the file. In the top right, you also see the 5 errors we have in total (like we also had when running the command in a terminal). In the code editor, every error is underlined in red. When hovering over the error, you see more details, including the rule name.

Repairing errors using the command line

Stylelint comes with a parameter to automatically fix all issues in a file – that can be fixed. These are usually white-space issues. To automatically fix all fixable issues, run the following command:

npm run lint:style -- --fix

Since we use “wp-scripts” in a npm script, we have to add two extra dashes in between the command and the parameter we want to pass to it.

Reparing errors in PhpStorm

Since we already integrated Stylelint into the editor, we can also fix the issues from there. To do that, click on underlined error. After a second, click on the down caret next to the red lightbulb and choose “Stylelint: Fix current file” – this should fix all fixable issues in the current file:

Conclusion

Following coding standards is very important. The right tools can help you with that, and PhpStorm with its integration of many of those “Quality Tools” makes it even easier. I only wish that PhpStorm would automatically detect these type of tool – even on a “per folder basis”, and not just for the whole project. But for me this small initial setup help me to save a lot of time to solve these errors later on.

Add text to the “Privacy Policy Guide” for your plugin or theme

With WordPress 4.9.6, we got some new privacy tools. This includes the new “Privacy Policy Guide”. Have you ever heard of it or even used it? If not, you should take a look at it on your site. You will find it at “Settings | Privacy” and then in the “Policy Guide” tab.

Overview of text snippets for your privacy policy

When you run WordPress and have a couple of plugins installed, some of them might store user data. Even the theme might do that. In those cases, the GDPR and similar laws enforce you to inform the users about that data in your privacy policy. Yet, it can be hard to know what data is stored and for what purpose. Themes and plugins can provide you with a text snippet you can copy to your privacy policy page.

Adding a text snippet to the Privacy Policy Guide for your plugin or theme

When you develop themes or plugins and store user data, make sure to add a custom text to this special page, so anyone using your plugin or theme can copy it. To add text to this page, you have to call the wp_add_privacy_policy_content() function and pass it a title and policy text. This could look something like this:

function privacy_policy_demo_plugin_content() {
    $content = sprintf(
        '<p class="privacy-policy-tutorial">%1$s</p><strong class="privacy-policy-tutorial">%2$s</strong> %3$s',
        __( 'Privacy Policy Demo Plugin is using local Storage ...', 'privacy-policy-demo-plugin' ),
        __( 'Suggested text:', 'privacy-policy-demo-plugin' ),
        __( 'This website uses LocalStorage to save ...', 'privacy-policy-demo-plugin' )
    );
    wp_add_privacy_policy_content(
        __( 'Privacy Policy Demo Plugin', 'privacy-policy-demo-plugin' ),
        wp_kses_post( wpautop( $content, false ) )
    );
}
add_action( 'admin_init', 'privacy_policy_demo_plugin_content' );

With this snippet in your plugin or theme, you should be able to see the text on the Privacy Policy Guide like this:

The "Privacy Policy Guide" with our custom text as well as one for "Twenty-Twenty-One" with the notice "Removed December 17, 2023".

As you can see in this screenshot, you will find different text snippets here. A click on the button “Copy suggested policy text to clipboard” will only copy the text after the “Suggested text:” headline, so your text might need also to include the plugin or theme name, to make sense.

Update notices

You can also see a text snippet for “Twenty Twenty-One” here with the notice “Removed December 12, 2023”. Any text that is added using this functionality will be “versioned”. WordPress will automatically detect, if the text was updated, or in this case, if the theme or plugin has been removed or deactivate. This indicates, to the site’s owner, that they might want to update their privacy policy page or remove some old text from it.

Conclusion

Even though this feature is around since May 2018, many have never recognized it’s there and/or have used the text snippets presented here. If you, like me, haven’t checked this page for your sites for some time, maybe now is a good time to take another or first look at it.

Limit resources used by Docker

For many years now, I am using Docker for my local development environment. In the beginning I was using my own custom images, but lately I’m mainly using “abstractions” like DDEV or wp-env, especially when working with WordPress projects. I run those mainly on Linux, but also have a setup on a Windows dual boot machine.

My previous Linux work laptop was only a Core i5-7200U dual-core with 16GB of RAM. Since I sometimes worked on different projects at the same time, my machine was on its limit pretty fast, with multiple PhpStorm instances and Chrome browser tabs open. Checking the resources, it became clear, that Docker was the issue, taking 50% of all resources.

Measuring resources used by Docker

Different operating systems have different tools to measure the running processes. If you want to find out, which process if using how much, you usually use them. But there is also a command build into Docker itself: docker stats. With this command, you get an output like this:

$ docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
NAME                                                 CPU %     MEM USAGE / LIMIT
34774832e449e0c5323d0c6eb5b88fdf-tests-cli-1         0.00%     628KiB / 15.01GiB
34774832e449e0c5323d0c6eb5b88fdf-cli-1               0.00%     1.133MiB / 15.01GiB
34774832e449e0c5323d0c6eb5b88fdf-tests-wordpress-1   0.01%     15.95MiB / 15.01GiB
34774832e449e0c5323d0c6eb5b88fdf-wordpress-1         0.00%     16.63MiB / 15.01GiB
34774832e449e0c5323d0c6eb5b88fdf-tests-mysql-1       0.02%     180.4MiB / 15.01GiB
34774832e449e0c5323d0c6eb5b88fdf-mysql-1             0.02%     183.1MiB / 15.01GiB
ddev-router                                          0.82%     43.99MiB / 15.01GiB
ddev-theme-tests-web                                 0.03%     144.4MiB / 15.01GiB
ddev-theme-tests-db                                  0.11%     150.6MiB / 15.01GiB
ddev-ssh-agent                                       0.32%     5.805MiB / 15.01GiB
ddev-theme-tests-dba                                 0.01%     20.1MiB / 15.01GiB

Changing the resource limits in WSL2

This is an example taken from within a WSL2 Docker setup. You can see two projects running with their containers. The “MEM USAGE” column also shows you the “LIMIT” all containers can take. On this machine with 32GB of RAM, it’s 50% of the available memory.

This limitation is set by WSL itself. By default, it takes 50% of the available memory or 8GB, whichever is less. On older builds however (before 20715), it was taking up to 80% of the memory! This can bring even powerful machines down easily.

Fortunately, it’s quite easy to overwrite this. All you have to do is create a .wsconfig file in your user’s home directory (%UserProfile%). Here, you create a file with the following content:

[wsl2]
memory=8G

Now you have to restart WLS2 with the following command (in Windows CMD or PowerShell), which will shut down all running distros, so make sure this is OK on your environment:

wsl --shutdown

Docker for Windows will now probably report, that Docker was stopped, and you can hit the “Restart” button. Now running the docker stats command again, you should only see a 8GB memory limit. There are more settings you can overwrite in that .wslconfig file, like the number of processors used. Since the virtual server, this blog is hosted, also only has 4GB of RAM, the 8GB I have defined here is still very generous.

Limiting the resources in other operating systems

I don’t use a Mac, so I can’t tell you how to change the settings there. And on Linux, there are many different options to achieve the same. It would be a bit too much to name all the different variants. But I do have a tip for those of you using Linux.

Limiting the resources per project

Instead of limiting the resources globally, you can limit them per container or for a project using docker-compose.yml files. When running a container manually, you can pass the resources into the call. But with a docker-compose.yml file, you can also set them for an individual service, like this, in which I’ve edited the file for the wp-env project:

version: '3.7'
services:
  mysql:
    image: mariadb
    deploy:
      resources:
        limits:
          memory: 2GB
# ...

Using the resources key, you can change different values for each service. With this change applied, the stats now look like this:

$ docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
NAME                                                 CPU %     MEM USAGE / LIMIT
34774832e449e0c5323d0c6eb5b88fdf-cli-1               0.00%     576KiB / 7.761GiB
34774832e449e0c5323d0c6eb5b88fdf-wordpress-1         0.01%     15.87MiB / 7.761GiB
34774832e449e0c5323d0c6eb5b88fdf-mysql-1             0.02%     177.6MiB / 2GiB
34774832e449e0c5323d0c6eb5b88fdf-tests-cli-1         0.00%     2.664MiB / 7.761GiB
34774832e449e0c5323d0c6eb5b88fdf-tests-wordpress-1   0.00%     16.17MiB / 7.761GiB
34774832e449e0c5323d0c6eb5b88fdf-tests-mysql-1       0.03%     86.56MiB / 7.761GiB

As you can see, all services use the previously defined 8GB, but the MySQL service is limited to 2GB now. As the MySQL service is usually the one using the most memory, this is the service I would recommend limiting first.

Conclusion

This is not a blog post on how to optimize the resources for Docker containers in all operating systems and in all different scenarios. But I hope it gives you an idea on the options and helps you, you quickly limit them on a machine with a low amount of total RAM or one few processors/threads. For my old work laptop, it really helped, and I was able to get work done a lot faster, as the other processes didn’t have to share the remaining 50% of memory.

How to get rid of the “-2” suffix on a page

If you are reading this blog post, you probably came across this issue yourself. You try to set the slug of a page (or other post type), and WordPress is appending a “-2” suffix to the slug. You are searching for a page with this slug, but can’t find one. But where is the issue coming from?

The problem

Let’s say we have a website about Berlin, and we want to create a page about the “Brandenburger Tor” (Brandenburg Gate), we would give it that title, write some content and then publish the page. We would hope to get a URL like example.com/brandenburger-tor, but we get example.com/brandenburger-tor-2 instead. But why?

The cause: media library items

With WordPress 6.4, that was just released, attachment pages are gone. But they are not really. For those of you how don’t know them, attachment pages were frontend pages one could navigate to, and that would just show the title/slug and the attachment. In some themes, it would even show the user who uploaded the file and when. This is how it looks like in WordPress 6.3 with TwentyTwenty:

Frontend screenshot showing the title/slug "brandenburger-tor", the post meta information, the image in the content and the beginning of the comment area

As you can see here as well, those attachment pages have the ability to be commented. There might be some website that would use them, but for most, they were rather useless.

With WordPress 6.4, those pages have been “removed”. When you access the URL for them, they would just redirect to the attachment file.

But the pages are not really removed. They are just not accessible anymore. They still exist in the database and have a title/slug. Now if we upload an image with a name like brandenburger-tor.jpg to the media library, the slug brandenburger-tor will be used for the attachment page, even with WordPress 6.4 without those frontend pages.

The solution: changing the slug of the attachment page

Now, to “free” the slug for our page, we have to change the slug of the attachment page. So let’s see how we can do this.

Finding the page

First, we search for the attachment name (we can also search for the slug):

List of media items with the search term "brandenburger-tor" with one entry showing the image

Editing the slug for the attachment page

We then click on the media item. At the bottom right, we find some links for the media item. With the first one, we can open that attachment page (this redirects us to the media item with WordPress 6.4) and with the second one, we can β€œEdit more details”:

The "Attachment details" pop with the "Edit more details" link highlighted

This will open up the “Edit Media” view, where you can see the Permalink for the image:

The "Edit Media" view with the "Permlink" at the top

In older versions of WordPress, there was an “Edit” button next to it, but this button does not exist anymore. Instead, you have to use the “Slug” screen element (meta box), which you probably first have to “active”, using the “Screen Options”:

The "Screen Options" opened with the "Slug" checkbox highlighted and checked

Now you can scroll down the page to this new meta box and change the slug for the attachment page. You could simply attach a suffix like “-attachment-page” to it:

Meta box to change the "Slug" for the page and the "Update" button on top

After you have changed the slug, hit the “Update” button.

Change the slug of the page

Now you can finally navigate to the page and update the slug. WordPress should now no longer add the “-2” suffix to the permalink.

Bonus: using the WP-CLI

If you are using the WP-CLI, you can change the slug of the attachment page using the wp post update command.

First, you have to find the ID of the page. You can find this when you hover the “Edit more details” link, or you search for attachments using the WP-CLI as well:

$ wp post list --post_type=attachment
+----+-------------------+-------------------+---------------------+-------------+
| ID | post_title        | post_name         | post_date           | post_status |
+----+-------------------+-------------------+---------------------+-------------+
| 35 | brandenburger-tor | brandenburger-tor | 2023-11-19 16:09:23 | inherit     |
+----+-------------------+-------------------+---------------------+-------------+

Once you have the ID, updating the slug works like this:

$ wp post update 35 --post_name=brandenburger-tor-attachment-page
Success: Updated post 35.

Conclusion

Having a page with that “-2” suffix is really annoying. And when you name your images or other media files similar to page names and also upload them into the media library before creating the page, you might run into this issue.

My advice would be to either create the page first, before uploading the media files, or even better, use better and more descriptive (longer) media file names before adding them to the page or media library.

If you happen to have run into this issue, now you should know how to fix this manually.