Kirki is a free open-source (MIT-licensed) framework built for developers who are looking to add Customizer Controls to their themes or plugins.
Aristeides Stathopoulos, Kirki’s lead developer has been working on the framework since 2014. Thanks to the continuous updates and improvements, Kirki has built a community on Github which includes over 1000 stars and 300 forks.
Before Kirki I never touched the customizer. Kirki helped me to understand the customizer and do a lot in less time!
LebCit – WordPress Theme Developer
WordPress Core Customizer Controls
WordPress Core includes a handful of basic Customizer Controls by default. For example: text, textarea, checkbox, radio, select, dropdown-pages, email, URL, number, hidden, and date controls.
Kirki supports the Core Controls too, plus around twenty more. Generally speaking, the Kirki controls cover the more advanced use-cases. For example:
- Typography
- Color Palettes
- TinyMCE Editor
- Sortable Fields
Kirki also offers functionality not available in Core WordPress, such as the auto-generation of your CSS output and postMessage scripts. These features, which we’ll look at later in this article, can easily cut your development time in half.
Kirki is Slow
One criticism commonly held against Kirki is that it’s slow. In fact, this criticism is used against most frameworks (including WordPress). It makes sense, right? You are loading a lot of code you might never use.
In this case, the reality is that the opposite is true. Most of the time control panels built using Kirki will actually be faster than the same panels built with Core Controls.
This is because Kirki adds an optimization layer that isn’t built into WordPress.
When the Customizer is initialized WordPress instantly tries to load all the controls, even if they are within a section or panel and the user can’t interact with them yet. In comparison, Kirki postpones the loading until just before the user will be interacting with the control.
To see the effect of this in practice, let’s try adding 50 color controls using each method.
Core Method:
for ($i = 0; $i < 50; $i++){ $wp_customize->add_setting( 'color_setting_hex_' . $i , array( 'default' => '#0088CC' ) ); // add color picker control $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'color_setting_hex_' . $i, array( 'label' => 'Color Control', 'section' => 'title_tagline', 'settings' => 'color_setting_hex_' . $i, ) ) ); }
With Kirki:
for ($i = 0; $i < 50; $i++) { Kirki::add_field( 'config_id', array( 'type' => 'color', 'settings' => 'color_setting_hex_' . $i, 'label' => __( 'Color Control', 'kirki' ), 'section' => 'title_tagline', 'default' => '#0088CC', ) ); }
The results:
As you can see, the initial load speed is considerably faster when using Kirki. The code required to create the controls is more concise too.
Integrating Kirki Into Your Project
There are multiple ways to integrate the Kirki Framework into your project, the official documentation does a good job of explaining the different methods.
I recommend developers guide the user to install the plugin version of Kirki, rather than including the framework directly within your project’s code. This can be done using TGMPA or the script provided.
The reasoning behind taking the plugin route is that Kirki is frequently updated and improved. By installing the plugin version, your users will have instant access to bug fixes and security updates.
In contrast, when you include the framework as part of your project, users will only receive updates when you update your theme or plugin, which might be less frequently than is required.
Whichever method you use, be sure to check Kirki is initialized before you add your settings:
// Early exit if Kirki doesn’t exist. if ( ! class_exists( 'Kirki' ) ) { return; }
Fields
In the Core Method example, we first created a setting and then created a control for it. In most cases, the two are directly linked. Kirki simplifies the process and allows us to create a ‘Field’ instead. When a field is created, it builds the setting and control in the background for us.
Fields support all the control arguments you would expect (label, description, section, default), as well as some Kirki-specific arguments.
The ‘type’ argument allows you to choose one of Kirki’s 30 control types: https://kirki.org/docs/controls/
Sections
Customizer Sections allow you to group Controls together. WordPress has six built-in sections that you can add your controls too:
- title_tagline – Site Identity
- colors – Colors
- header_image – Header Image
- background_image – Background Image
- static_front_page – Homepage Settings
- custom_css – Additional CSS
Sections in Kirki work exactly the same as in Core, the Kirki::add_section() method is simply a wrapper for $wp_customize->add_section() and accepts the same parameters and arguments.
Kirki::add_section( 'section_id', array( 'title' => esc_html__( 'My Section', 'kirki' ), 'description' => esc_html__( 'My section description.', 'kirki' ), ) );
Panels
Panels allow you to create another level of hierarchy by grouping Sections together. WordPress Core has one built-in panel, which is ‘Menus’.
Again, the Kirki implementation is simply a wrapper for the Core functionality.
Kirki::add_panel( 'panel_id', array( 'priority' => 10, 'title' => esc_html__( 'My Panel', 'kirki' ), 'description' => esc_html__( 'My panel description', 'kirki' ), ) );
‘transport’ => ‘auto’
Traditionally when creating Customizer Controls you have two options for the transport argument:
- Refresh – Each time the user makes a change the preview pane is refreshed to show the changes. This can take a couple of seconds.
- postMessage – Each time the user makes a change the preview pane is updated using Javascript which doesn’t require a refresh and is near-instant.
postMessage is undoubtedly the superior method for updating the previewer and should be used where possible. However, there is one downside, using postMessage means you need to create write custom JS code for each of your controls. A simple implementation looks something like this:
// Update the site title in real time... wp.customize( 'blogname', function( value ) { value.bind( function( newval ) { $( '#site-title a' ).html( newval ); } ); } );
When you have a lot of settings, this can quickly become repetitive.
This is where Kirki shines, it adds a third option: ‘transport’ => ‘auto’.
‘transport’ => ‘auto’ works together with another argument Kirki adds named ‘output’. When both values are defined, Kirki will auto-generate the postMessage scripts for you. Which means you get all the benefits of using postMessage without having to write any of the Javascript code.
A field using transport => ‘auto’ looks like this:
Kirki::add_field( ‘config_id’, array( 'type' => 'color', 'settings' => 'color_setting_hex', 'label' => __( 'Color Control', 'kirki' ), 'section' => ‘colors’, 'default' => '#0088CC', 'transport' => 'auto', 'output' => array( array( 'element' => 'body', 'property' => 'background-color', ), ), ) );
This time-saving feature of Kirki means that most of the time you will no longer need to write or enqueue your own postMessage scripts.
Frontend CSS Output
Another part of creating Customizer settings is generating the CSS output on the frontend. A simple example might look like this:
/** * Output the Customizer CSS to wp_head */ function wptavern_customizer_css() { $bg_color = get_theme_mod( 'color_setting_hex' ); ?> <style> body { background-color: <?php echo sanitize_hex_color( $bg_color ); ?>; } </style> <?php } add_action( 'wp_head', wptavern_customizer_css );
Like the postMessage example, writing this code can quickly become repetitive if you have a lot of settings.
Fortunately, ‘transport’ => ‘auto’ takes care of the frontend output for you too. Even in our simplified example, ‘transport’ => ‘auto’ has reduced the code we need to write by ~50%.
Conclusion
In this article, we’ve looked at just the basics of the Kirki Framework and two of its arguments, already we can see how it allows us to create Customizer Controls faster and without compromising on performance.
When you dive into Kirki you will quickly discover the wealth of functionality it adds on top of the Customize API. It’s no surprise that it’s in use on over 300,000 websites and a core part of some of the biggest WordPress themes on the market.