Using gitattributes to make releasing WordPress themes easier

Zuari releases have been few and far apart in the last year. While I work on Zuari often, I cut a release only when I know I’ll have time to fix things in case they break for someone. This has meant that I haven’t paid much thought to the release process. Till now, I would create a copy of the directory, go through my list of files to delete, delete them and create an archive to upload to WordPress.org. As you can see this process is manual and error prone.

While looking at David’s syndication-links repository I saw a .gitattributes file. I had seen it before but never looked into it. Turns out, that among other things, you can use it to define a list of files to ignore when creating a git archive!

Continue reading “Using gitattributes to make releasing WordPress themes easier”

🔖 Musings About Building Websites out of WordPress Blocks (archive)

Gutenberg blocks solved the problem of content editing, but can they scale to solve full-site editing too? There is a significant jump in complexity between these two problems.

Site building requires smarter blocks. Ones that are dynamic and that can change according to the context of the site and the blocks that are around them. Block APIs will need to be able to do this and a lot more to really enable full-site editing.

🔖 Thoughts on Themes (archive)

Gutenberg is meant to be the common interaction point for making and customizing your website’s elements — navigation, content, site elements. It is not meant to take agency away from themes. Themes will continue to provide templates, designs and layouts. Blocks only make these things more portable and easier for the user.

Themes make overarching decisions of typography, color and design, this should make it easier for the user to make specific decisions for their website. The customizability that Gutenberg provides must be guided by themes.

🔖 The Good WordPress Theme (archive)

WordPress.org themes and premium WordPress themes differ in scope. The former is narrow and only handles styling and layout, the latter is supposed to be a one-stop-shop for a website. Good premium themes:

  • Solve a specific problem. They don’t try to do everything and instead, decide their limitations based on the use-case they’re solving for
  • Are integrated with plugins that help solve the said problem
  • Keep the users safe from themselves — by helping them take good design and plugin decisions, and itself — by not locking the users in.

By adding extensive customizability Gutenberg seems to be shifting these responsibilities from the theme to the user. Premium themes have long been responsible for moving the WordPress platform forward, the changes brought by Gutenberg might negatively affect this landscape.

Gutenberg editor color palettes for WordPress themes

One of my favorite features of the Gutenberg block editor is the editor color palette. It allows themes to register a color palette that is shown in the block editor whenever a block needs to choose a color.

Allowing the theme to have a say in the styling of the content of the post is a powerful idea. It helps guide the user’s design choices while still allowing them freedom to make changes. When working on Zuari, it was important for me to get this right since the theme is otherwise just black and gray. 

Editor colors from Zuari
Since I am not very good at colors, I collected over a hundred references on Pinterest to pick and tweak from.

Once we have the colors picked and named (This can be tricky. What is ecru?) we need to let WordPress know that our theme would like to register a palette, and add our colors to it:

add_theme_support( 'editor-color-palette', array(
                'name' => __('Brick', 'zuari'),
                'slug' => 'brick',
                'color' => '#825A58'
                'name' => __('Baby Pink', 'zuari'),
                'slug' => 'baby-pink',
                'color' => '#E0BAC0'
                'name' => __('Ecru', 'zuari'),
                'slug' => 'ecru',
                'color' => '#E1D9D3'
) );

Next, we’ll need to add two CSS classes for each of these colors so that they can be used on the different blocks as background and foreground colors. The naming convention for these classes is has-{slug}-color and has-{slug}-background-color:

.has-brick-color { color: #825a58; }
.has-baby-pink-color { color: #e0bac0; }
.has-ecru-color { color: #e1d9d3; }

.has-brick-background-color { background-color: #825a58; }
.has-baby-pink-background-color { background-color: #e0bac0; }
.has-ecru-background-color { background-color: #e1d9d3; }
Screenshot of Color settings in Gutenberg

That’s it! This will add the color palette to the block inspector for any blocks that need color, and show the right colors in the website once they’re selected.

I hope that WordPress adds these colors as options in the Customizer panels as well, allowing for more design guidance coming from the theme. I’ve been thinking about WordPress themes as design patterns and guidelines rather than skeletons for a website. I’ll be writing about this soon.

Setting up WordPress’s PHP coding standards for your theme

Setting up coding standards for your project is always a good idea. While it is ideal to start with one from the beginning, sometimes you have to do it after you’ve already written quite a bit of code (looks at Zuari 👀). Here is a quick guide on setting up the WordPress PHP Coding Standards for your theme or plugin:

For the purpose of this guide you’d need PHP and Composer installed locally, even if you are using docker for local development. We start by running composer init. This sets up the composer.json file and adds it to .gitignore. Next to get the phpcs and the WordPress coding standards, we run:

composer require squizlabs/php_codesniffer --dev
composer require wp-coding-standards/wpcs --dev
composer require dealerdirect/phpcodesniffer-composer-installer --dev
composer require phpcompatibility/php-compatibility --dev
Continue reading “Setting up WordPress’s PHP coding standards for your theme”

Dark mode & accessibility improvements in Zuari

This update has been a long time coming. I had added a ticket to support dark mode almost a year ago when I first came across the Webkit support blog post. The code sample was straightforward:

@media (prefers-color-scheme: dark) {
    :root {
        --special-text-color: hsla(60, 50%, 70%, 0.75);
        --border-color: white;

Philip added the initial support and with a few adjustments to the Customizer we added the ‘Allow the operating system’s dark mode to override my color settings‘ checkbox. I didn’t want to force this change on every site because it would break the colors that people have picked for their page and headers. But if you do select it, the site changes colors based on the operating system’s setting:

Notice the increased line-height in the dark mode to improve readability

More recently, I was able to complete my laundry list of accessibility improvements including:

  • Adding aria markers where needed
  • Making sure all HTML was semantic
  • Improving keyboard navigation

You can get all these changes in version 1.4.0 from Github, or the latest from the themes repository. I have also requested another round of review from the WordPress theme review team so that I can officially add the accessibility-ready tag, but, I am not sure what the process here is. Hoping someone picks it up soon 🤞🏽

Zuari on WordPress.org

After staying in review for nearly seven weeks, my WordPress theme finally got approved and deployed on the WordPress.org theme directory. Big thanks to @rabmalin for the review 🙏🏽

The Zuari theme on latest page of WordPress.org theme directory.
The Zuari theme as seen on WordPress.org

I wanted to make a theme that supported the new Gutenberg block styles, and gave a lot of customization options to the users. I have been working on it on and off since November last year. The idea was to give it an hour everyday, but travel and life did not let me be as consistent as I’d like. By March I realized that it might be better to work on a subset of features and do a version one release first. Now that this is done, I am excited about making improvements.


  • Use ITCSS to better architect the CSS. It’ll also help in getting the editor styles out.
  • Add microformats support for the IndieWeb.
  • Plugin support for the IndieWeb plugins.
  • Improve animations.
  • Bug fixes.
  • More customization options.
  • Accessibility improvements.

Hopefully by the end of the year I can actually recommend the theme to people who want to join the IndieWeb 🤞🏽 If you give it a spin and run into problems do raise an issue and I’ll try to help. Pull requests are welcome too!

Migrating to Dreamhost

My websites have been hosted on WebFaction since I can I remember, but with them recently getting acquired by GoDaddy, I started to look for alternatives. Looking for a cheap shared host to keep the three WordPress sites I maintain, I decided to check WordPress.org for recommendations. They suggested Bluehost, DreamHost and SiteGround. After a week of trying, Bluehost support couldn’t convert my domain account to a hosting account so I setup a new one on DreamHost.

The migration went smoothly but it took me a while to get used to the way DreamHost manages users, sites, and apps. Now that the DNS has (hopefully) fully propagated, the website is up and running on the new server, on https (for the first time 🥳), and using the new theme I am working on. Excited to be working on my site again!

Docker Compose for local WordPress development

Docker, specifically Docker compose, has served me well in keeping a sane development environment for my WordPress projects. MAMP was too much of a black box, and having a local PHP and SQL for both MediaWiki and WordPress was going to be more maintenance than I would have time for. With compose I have little to no maintenance burden, and my system is squeaky clean.

The following docker-compose.yml file starts two services — using the mysql, and the wordpress images:

version: '3.3'
     image: mysql:5.7
       - ./dbdata:/var/lib/mysql
     restart: always
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
       - db
     image: wordpress:latest
       - "8008:80"
       - ./wp-content:/var/www/html/wp-content
     restart: always
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress

The way this is setup is that both the services share a part of their file system with the host. The mysql one shares all the database data, making it easier for me to move test data around different instances and configurations of WordPress that I might be running. And, to be able to work on plugins and themes the wordpress service shares the wp-content directory. This way, I can easily clone and work on anything directly on my local system.

With this, all I need to do now to setup a new WordPress install is — create a new directory, copy this YAML file into it, and run docker-compose up. I change the wordpress service’s port mapping when I need to run multiple instances at once. That’s it!

WordPress meet-up, December 2017

Siddharth has been organizing WordPress meet-ups in Goa for the last three years. Unfortunately, I am often not in the city to attend them. So, this time, to ensure that I am there, I offered to help him organize it.
Both of us have recently joined a co-working place, 91Springboard, and they offered to host the event. Hampus made us a logo, complete with coconut trees, a Portuguese style house, and a fish thali! Sid wanted circular transparent stickers which we got printed from Midway.

Wordpress Goa sticker on a laptop

Along with the informal meeting, we decided to have two short talks. The first by Abhishek about Open Source, and the second by me about Gutenberg. This was really an excuse for me to explore WordPress’ new editor.

On the day of the meet-up, we were a bit disappointed with the turnout. Of the 40 people who RSVP’d on meetup.com, only 15 came. We started the talks at 6:15 pm and in an hour both were done. What followed was a lively discussion about the future of WordPress, the nuances of theme licensing, and the standard of government websites. Later, everyone went to Joseph’s to get a drink, but I got sleepy soon after and left for home. What had started with disappointment turned into the realization that the people who did come were the perfect ones.

WordPress Goa, Prateek talking

For next time, we need to remember to start a little late, 5:00 pm on a Friday is too early. We also need to try and get the word out to students. If you would like to attend, talk, or have any suggestions, do get in touch.

The Year Without Pants

by Scott Berkun

This book is a form of participatory journalism where the author talks about his experience of being one of the first managers at Automattic (the company that runs WordPress.com) . He gives a commentary on the culture of the company as it moves from a flat to a hierarchical structure. He often contrasts it with his experience at Microsoft.

A Year Without Pants

This contrast isn’t as clear as Cathedral and Bazaar. The author even points out instances where WordPress’ culture tends towards cathedral and Microsoft’s towards bazaar. The quality and quantity of work done amidst the chaos of the open source project amazes him, and he attributes this success to the people at the organization – who are passionate about their work, and to Matt Mullenweg – who grants these people autonomy, and encourages them to experiment. He also talks about how he manages his team which is distributed across the world and sometimes even across timezones.

This is the first time I’ve read about open source culture from a manager’s viewpoint. His critique for the communication tools used at Automattic resonated deeply with me. Reading it I was able to look at the Wikimedia Foundation, its work, and my place in it through a new lens.

Feed Me

I haven’t posted on Facebook or Twitter in a while. I see my feed sometimes and use Facebook chat (over BitlBee) regularly. The recent scare about privacy probably triggered this, but I must confess that I don’t understand it fully. Not understanding is scary.

In my time away, I realized that I wasn’t missing anything. I no longer had to decide whether the person I met once at that café was a friend, no longer had to see what my 2nd grade classmate ate for lunch, and no longer scrolled past every  update my favorite game studio made to their new release.

I was still following blogs using Feedly, so I knew what my sister was eating, what Yuvi was hacking on, and what Super Pietpiet was drawing. I could see that effort was taken to create this content and I felt better consuming it. No one was limited to 140 characters and Facebook didn’t forcefully crop their pictures into a square.

There was one thing that I continued liking about these sites though — they had a feed of my life.

This feed wasn’t complete or accurate, and though limited by the time I was active on these sites, it was a good record. I posted links that I wouldn’t be interested in now, photos that’d embarrass me, and status updates that could have altogether been avoided, but, those things were truly what I was doing and thinking then. Only after a grueling conversation with Arun, and later Rhea, did I become comfortable with this annoying past self. Arun even convinced me that the worst that could happen by continuing this is that I’d have something to laugh about later. That didn’t sound too bad.

And so I continue to embarrass the future me — by maintaining this blog, on my server, rather than elsewhere. I made this theme so that I am not limited to full text posts. With Sid’s help, _s, and ACF, I was able to setup multiple post types. I can post check-ins, photos, quotes, statuses and albums like most social networks. I have complete control over how they look, right down to the tiles I want to use in the map. I like to call this theme Feed Me — it gives me the flexibility to add even more post types and the freedom to make them look the way I want.

Oh, and most importantly, in a dire situation I can delete everything on my server and all the embarrassment along with it.