Default ACF Flexible Content Fields

ACF Default Content Blocks

I had a recent request to set up some default Advance Custom Fields Flexible Content Fields for new posts. We often use FCF blocks for a lot of our page creation to allow for greater customization and flexibility. While this might seem like limiting some of that flexibility it comes with the benefit of streamlining things for your client.

Limiting the filter to only run on certain post types I can set up some default blocks and settings to make things easier and quicker to get up and running. This makes it easier on the client, and makes them happy. And a happy client, is a happy coder.

The ACF filter we’ll use is acf/load_value/name={$field_name}, read more on the ACF Docs. You need to set the name as the name of your flexible content blocks field name.

In this example I name mine content_blocks

add_filter( 'acf/load_value/name=content_blocks', 'default_fields', 10, 3 );
function default_fields( $value, $post_id, $field ) {

  // Only add default content for new posts
  if ( $value !== null ) {
    return $value;

  // Only add default content for certain post types
  if ( ! in_array(
		get_post_type( $post_id ),
			@TODO Post Types
		) ) ) {
		return $value;

  // Set up your initial post, then get the field id's of the settings you want to set
  // They look like: field_5b4e57efd0660_field_5b4e63e479d81
  // Add them after the acf_fc_layout
  $value = array(
      'acf_fc_layout' => 'name_of_layout',
      'field_5b4e57efd0660_field_5b4e63e479d81' => 'Default Value'
      'acf_fc_layout' => 'another_layout',

  return $value;

First we check the $value and make sure it’s set to null. If not than the post has already been created and we need to return early.

Next I check against the post type. There are a variety of checks you could do to make sure you’re only added default blocks where you want. You could check against the post template, post type, or even specific post ID’s.

Once you’re done checking you can setup the $value variable. The variable is an array, made up of arrays for each block you want to create.

The first value key pair you’ll need to set is the acf_fc_layout. This corresponds to the name of your layout in the flexible content field.

Any other fields that you want to set by default you need to first list the field key, and then your default value.

Finding Field Keys

You can find the field keys you need for this array in a couple of ways. You can go into your screen settings of the field group and toggle on the Field Keys

You can also go to a post that you have already created and want to use as default and output the $value variable. To do so you could add the following to your above filter:

echo ‘<pre>’;print_r($value); echo ‘</pre>’

Do this before you return early since the post has already been created. Then you’ll see an output of all the field keys and easily match them to the settings you want to set up as default.

However I prefer to use Kint for my debugging. Then you only have to add:


Wrapping Up

ACF is full of extra filters for doing pretty much anything you can imagine. Check out the docs and support forums if you ever get stuck.

MAMP PRO for Local WordPress Development

I’ve used a few different options for local development on my laptop over the years. I’m at a transition point in my career and I thought I would take a minute to post on my workflow. I hope it helps others and serves as a reference point for me in the future.

For a while I used MAMP. Everything was subfolders of localhost and it worked. It wasn’t fancy but it gave me a working development environment to build and break things.

I remember when I updated my version of MAMP I screwed up and lost a lot of my local databases. Nothing lost was critical, but a lot of the learning projects I had built over the years. Because of this I was pretty frustrated with MAMP and I decided instead I should change my approach. I knew about VVV from listening to WordPress podcasts and it seemed like the right way to go.

Variable Success

VVV is great, though I’m not sure if I ever got the most out of it with my older laptop. I’m still rocking a MacBook Pro late 2009. It gets the job done and I’m looking for the next option but it never quite liked having Vagrant running. I remember the first time I used vagrant up it took FOREVER to download and run everything. When it finally started running I did enjoy using VVV as well as Variable VVV for site creation. The custom local domains and everything did work, for a while.

Over time I ran into more and more problems with VVV. It was either my Vagrant, or Oracle’s Virtual Server, or something else altogether. It’s quite possible I was doing something wrong, but I never did figure it out. One day several sites stopped working and no amount of restarting could alleviate the problem.

I tried to use Desktop Server, but it saw that I had another virtual machine installed on my computer. Even though I had deleted everything Desktop Server would never let me install.

By this point I need something that would work. I decided to throw some money at the problem and ponied up for MAMP PRO.

The main issue I have with MAMP is the lack of good documentation. There some info on their site and now that I have things running I’m having a good time. I hope this post will help others who look for ways to get the most out of the MAMP PRO software.

MAMP PRO Workflow

I started a new remote position about a month ago and many of the projects are editing existing websites. This meant I first needed to get a working local copy of the website. And several of them are HTTPS.

MAMP PRO has a easy way to set a server to use https. When making a new site or changing an existing one you can go to the SSL tab and check the box to turn on SSL. If you have certificate files you could point to them, or you can “Create self-signed certificate…” which lets you setup your own local certificate. Enter any info, it doesn’t matter. When you open the site in browser it will warn you saying that the certificate isn’t secure. You agree that you understand it will continue to the site and work as normal.


Apache or Nginx

A nice feature of MAMP PRO is the ability to individually select Apache or Nginx for each site. I started with doing everything as Apache as that’s what I’m used to and it made the transition easy. But I ran into a situation where switching to Nginx was a game changer.

The development sites all had repositories for the theme and I used WP Migrate DB PRO to pull down the database. But instead of downloading all the images they use an Nginx directive to rewrite the file locations to point everything to the live server.

Local Development, Remote Images

In the Nginx tab of MAMP PRO you can add extra parameters for the directive. Here I add

location ~ ^/wp-content/uploads/(.*) {
  if (!-f $request_filename) {
    rewrite ^/wp-content/uploads/(.*)$$1 redirect;

After the location tag is a regex. It’s looking at any file request that has a beginning, then references /wp-content/uploads/. Then collects whatever comes afterward. If it’s a filename being requested we rewrite that same regex and change it to the live site and use that saved file extension from the search.

Now you don’t have to deal with downloading years worth of images from an existing website.


I found that this works, but with Nginx I have an issue with any of my links. They all lead to 404’s. While still in the Nginx tab add the following to the try_files parameter

$uri $uri/ /index.php?q=$uri$args;

This line uses Nginx’s rewrite rules to work with WordPress routing and run everything through index.php. It also keeps the arguments that are part of the url. The $uri here is commonly used to represent everything after the domain name in the URL.

MAMP Bonus

Another bonus to using MAMP is the ability to install “Extras” which include WordPress. With a couple clicks you can install, and setup a database for your WordPress development. Combo this with some command line skills to pull down your favorite WordPress starter theme and you’re all set to build new and exciting WordPress sites.

There is a file that is created in the root directory called extras to show an icon in your MAMP Hosts for each extra you have installed. It’s a little annoying and I normally delete it or just include in my gitignore.

Is anyone else out there using MAMP Pro for your local WordPress development?

Rediscover Theme Settings with the WordPress Customizer

Rediscover Theme Settings with the WordPress Customizer

Image above taken by Stewart Savage of Abaton Consulting.

This article is a companion piece to my talk at WordCamp Sacramento 2016 of the same title.

The WordPress Customizer became included into core in version 3.4. Over the years it has seen many improvements to use and functionality. It is a tool for previewing changes to your site before you commit them. For new users the most common uses are for the Site’s name and Description. Adjusting colors and managing Menu’s and Widgets are also popular. The default WordPress Customizer has many useful settings and the ability to add and even create our own makes the future exciting.

What is the Customizer?

As I prepared to give this talk at WordCamp Sacramento 2016 it surprised me how many times people asked this question. Many of the attendees and other WordCamp Speakers had no experience using the Customizer, even the default settings in core.

After hearing this I put together the following clip to open my talk. It shows the interface and some examples of things the Customizer can do. Changing the title or description of the site, changing colors, reordering widgets, etc.

WordPress Customizer Example

Accessing the Customizer is easier than ever. You can get to it via the dashboard under the Appearance section. Or while logged in and browsing the site the Customize button appears next to the Dashboard button in the admin bar. When you use this link you’ll open the Customizer and preview the page that you were currently on.

The Customizer is everything

At last years inagural WordCamp US Matt Mullenweg talked about the Customizer and his view of it’s importance. He said customization is the biggest opportunity for improving new user experience. During this summer Jeff Chandler from WP Tavern asked Matt to expand on this. Here’s an excerpt from that interview:

Jeff ChanlerAt WordCamp US you said that Customization is the single biggest opportunity for improving the WordPress experience, and I wanted to know, could you expand on this? And how important is the Customizer in this regard?

Matt MullenwegThe Customizer is everything.

JC – Really?

MM – Yeah. You know, I think that the Customizer is definitely, like if I think about leading a release, I could see the Customizer being a main focus of it. You know? That, it’s so important to the user experience of someone new to WordPress especially, but also to everyone who uses WordPress day to day, and it’s also probably our weakest area to be honest. I mean, it’s had a ton of work, it’s so much better than it was, but if you just look at like we’re only as strong as our weakest link, and right now I think our weakest link in user experience is the customization—it’s not just the Customizer it’s also themes—but the customization of the frontend of someone’s site

Here is the link to the entire podcast.

At the end he hints at the need for customization on the front-end. I think this is the direction that the Customizer is heading, but more on that later.

Getting Started With The Customizer

To make any changes or additions to the Customizer we use the customize_register hook.

function themeslug_customize_register( $wp_customize ) {
  // Add/Get/Remove Customizer Settings
add_action( 'customize_register', 'themeslug_customize_register' );

The function you hook in needs to include the $wp_customize argument as this is the WordPress Customize Manager object. This bootstraps the WordPress Customizer experience and serves as the factory to create controls and settings.

It’s best practice to create this function in a customize.php file that you have an an /inc/ folder of your theme/plugin. But there is no requirement to use the Customizer other than using the aforementioned hook.

There are four main Customizer objects that you will access from the Customize Manager: Panels, Sections, Settings, and Controls. Each Object has three methods, add, get, and remove, that you use to make any changes.

Panels are the highest level of hierarchy and hold one or more sections.

Sections hold one or more setting and will not display until there is at least one setting. Panels wont display until one of their sections has a setting.

Setting and Controls are dependent on each other. The Control is the user input and settings determine how that control saves to the database.


Within the function you can begin to make your changes to the Customizer. WordPress sets up several sections and panels by default. You can remove them if you don’t need them or want to recreate the functionality.

$wp_customize->remove_setting( 'blogname' );

By accessing the Customize Manager and using remove_setting we can pass in an id of a section to remove it from the Customizer. You could remove a panel, setting, or control the same way.


The Get method lets you change parameters that have already been set either through the defaults or one added by a parent theme. Here is an example of how TwentySixteen uses the get method.

$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
$wp_customize->get_setting( 'blogdescription' )->transport  = 'postMessage';

When you pass in an id the method returns the object you requested. Then you can access any of that objects properties. You could save this to a variable, or in this example change the value of the transport property to postMessage.

Adding to the Customizer

The add method is how we add our own panels, sections, settings and controls to the Customizer. Lets dive in to each one and look at the properties required.

Adding a Panel

        'priority'   	   => 160,
        'title'      	   => __( 'Panel Title' ), 
        'description'	   => __( 'Panel Description' ),
        'capability' 	   => 'edit_theme_options',

The ability to add a new panel to your top level hierarchy came in WordPress 4.0. While you can do this, it’s not recommended for your themes. Panels should provide a specific contextual areas of WordPress like Menus and Widgets. If you’re creating a plugin that has several sections about one specific area then it would be a good option.

The priority determines the placement in the top level hierarchy. Each section and panel already added by WordPress has their own priority, and we’ll see a list of those later.

For themes it is recommended to use the default sections and create your own sections based on the content you are changing.

Adding a Section

        'priority'        => 10,
        'title'           => __( 'Section Title' ),
        'description'     => __( 'Section Description' ),
        'panel'           => '',    
        'active_callback' => '',

Sections hold one or many controls. You can add your own controls to the core sections or create your own. In most cases your section only needs a couple parameters. Title and perhaps priority if you have a particular place you want to place the section. By default your sections begin below the core sections.

The panel property is only needed if you want to include this section in a specific panel. Also the active_callback property is only needed if you want to display it based on other factors. We’ll cover active_callback more in a bit.

The sections and panels in WordPress core are as followed:

Title ID Priority (Order)
Site Title & Tagline title_tagline 20
Colors colors 40
Header Image header_image 60
Background Image background_image 80
Menus (Panel)* menus 100
Widgets (Panel) widgets 110
Static Front Page static_front_page 120

If you want to add to or remove a section you can access it with the ID. If you want to remove the Menu panel it requires more than just remove_panel(‘menus’). Check out this stack overflow article for more information on removing the panel.

Adding a Setting and Control

        'type' => 'theme_mod',
        'capability' => 'edit_theme_options',
        'theme_supports' => '',
        'default' => '',
        'transport' => 'refresh',
        'sanitize_callback' => '',
        'validate_callback' => '',

Settings handle the live-previewing, saving, sanitation and validation.

  • Type is how it’s saved into the database
  • Capabilities are who has access to the setting
  • Theme Supports not commonly necessary
  • Default is a default value to display
  • Transport controls live previewing options
  • Sanitize_Callback will sanitizing the value before it saving to the database
  • Validate_Callback will confirm the value before attempting to save
        'priority' => 10,
        'label' => _( 'Control Label' ),
        'description' => _( 'Control Description' ),
        'type' => 'text',
        'section' => 'section_id',
        'input_attrs' => array(),
        'active_callback' => '',

The Control creates the User Interface that the user will interact with to make changes.

  • Type creates the UI for the customizer
  • Section is the section the control should appear in
  • Input_Attrs are attributes you can give to the Input HTML element.
  • Active_Callback is a contextual control of display

The control type property tells the Customizer what type of UI to generate for the user. This could be a textbox, a set of radio options, or even an image selector. There are many basic and advanced types built into core, here are most of the basic ones:

text textarea date
range url email
password hidden checkbox
radio select dropdown-pages
number time datetime
week search

Advanced types need a little extra work to use and we’ll cover those in a moment. You can also create your own types.

theme_mod vs. option

While the control type creates the ui for the user, the setting type tells the Customizer how the input saves to the database.


Settings saved with theme_mod are tied to the current active theme. Each time you activate a theme WordPress creates a new row in the wp_options table as theme_mods_THEMENAME. All your settings using theme_mod save into an array in this row. This is the default for all settings that you add to the Customizer.

When you change your theme you’ll lose all these changes, but when you switch back everything returns.


The option type will save each setting in the wp_options table. The setting ID you assign will be the name of the new table row. This type is not recommended by WordPress for Customizer settings added to themes. If you change your theme the settings will stay. If you’ve added the settings to the Customizer in your theme than the options will not be visible to the user.

If you want to add settings to the Customizer that will work for the user cross-themes you should use a plugin.

Transport Property

The transport property is how the customizer previews new values.


Using a full page refresh is the default property for new settings. This was all we had when Customizer became a part of core. The good thing about refresh is it is accurate and doesn’t need any extra code to get working. The user changes the value in the Customizer and the preview screen refreshes to show the changes.

The downside is the page refreshes after every little change. And if the page has a lot of elements the load time could be slow and annoying for the user.


With postMessage any change no longer triggers a full page refresh. Instead the Customizer makes an asyncronous request. The new values go to the preview window and you need to update the preview using Javascript. Seeing the updates live gives a better user experience. But it does need a little more setup and in some cases you are duplicating your logic to render the page.

Transport properties in action

Below is a simple example of a user updating a text field and how it updates using the two transport types.

WordPress Customizer Refresh Example
WordPress Customizer Refresh Example


WordPress Customizer PostMessage Example
WordPress Customizer PostMessage Example


Using postMessage

To utilize the live updating of postMessage we’ll need to enqueue a Javascript file using the customize_preview_init hook. This way our file is only loading when using the Customizer.

function thememod_preview_js() {
        array( 'customize-preview', 'jquery' )
 add_action( 'customize_preview_init', 'thememod_preview_js' );

When you enqueue the file you’ll need to include two dependencies, jQuery and customize-preview. The later will include the Customize Manager Object that will give us access to the Customizer settings.

Here is some boilerplate Javascript that you can use to set up your postMessage setting.

( function( $ ) {

  wp.customize( 'setting_id', function ( value ) {
    value.bind( function( to ) {
      $( '#custom-theme-css' ).html( to );
    } );
  } );

} )( jQuery );

The wp object gives us access to the customize method in our Javascript. This is similar to the $wp_customize->method we were using in PHP.

Here we pass in the setting_id and a callback function. The callback function takes the value which is the original value. We use bind so that when it changes we target a CSS selector and update the html to the new value.

You could also use this to update CSS or toggle a class. You could do more complicated logic, but you don’t want to go overboard with postMessage. There is a new tool since WordPress 4.5 that makes updating complicated logic easier, and that is Selective Refresh.

Selective Refresh

Added in WordPress 4.5 we can now refresh just an area that we have linked to a setting. This is less disruptive than a full frame refresh. It also allows you to use the same PHP that you wrote to add the elements to the page in the first place.

To use Selective Refresh you need to register a partial that creates a link between your setting and a CSS Selector on your page.

NOTE: This partial is different than a PHP partial that we might include in a page as part of a template part.

         'settings' => 'partial_id'
         'selector' => '#css-selector',
         'container_inclusive' => false,
         'render_callback' => function() {
             // function name or php logic
         'fallback_refresh' => true

Creating a partial is like adding a setting except that you use the selective_refresh method as well as the add_partial method of that object.

You give your partial an ID, and you also declare this same ID in the settings parameter. But if you don’t include the settings parameter it will default to what you have already set as the partial ID.

  • Selector is the element in the page that we want to link to. If you use a selector that has many entities on the page it will only select the first one.
  • Container Inclusive is a booleon value. True means that you want to refresh the parent node as well as it’s children instead of just the children.
  • Render Callback is your PHP logic to update the page. You could do an anonymous function, or pass in the name of a function you have already created.
  • Fallback Refresh simple says that if it can’t find the CSS selector than it will do a full page refresh.

Note that you’ll need to keep your transport property set to postMessage. Otherwise the preview will perform a full page refresh no matter what.

A Selective Refresh Example

Lets take a closer look at creating a new setting that uses Selective Refresh. Selective Refresh allows us to do more than just update a value. We can render our content through a function and see the effect update.

First we need to add a setting and a control to work with:

         'capability' => 'edit_theme_options',
         'transport' => 'postMessage',
         'default' => 'Lorem Ipsum',

         'type' => 'text',
         'priority' => 10,
         'section' => 'custom_section', 

Then we add our partial

        'selector' => '.backwards-text',
        'render_callback' => 'ajs_customizer_partial_backwardstext',

You’ll notice a couple things when you look at these example code blocks. First, I use the same ID for my Control, Setting, and Partial. This works, and I prefer it to better organize my code.

Next I reference a new function called ajs_customizer_partial_backwardstext. Let’s make that now.

function ajs_customizer_partial_backwardstext() {
    echo strrev(get_theme_mod('backwardstext_setting_id'));

I’m getting the value of my setting from the database. Then reversing the string and echoing out the content. I’ve used this function in the page template to display the initial value.

This isn’t a practical example. But it shows you that the content is rendering through my function. Here’s what it looks like as I update the value in the Customizer.

WordPress Customizer Selective Refresh Example
WordPress Customizer Selective Refresh Example

Only the paragraph tag that has the class .backwards-text is refreshing. It’s using my function to reverse the string before it prints it to the screen.

More Selective Refresh Benefits

Now that we have a link created between the WordPress Customizer control and a section of the page we have a few more features that Selective Refresh adds.

The first allows you to shift-click on the element in the preview window and the Customizer will jump to and focus on that setting.

WordPress Customizer Selective Refresh Shift Click Example
WordPress Customizer Selective Refresh Shift Click Example

This is great, but it’s not obvious. I expect more work done to let users know about this feature either with hover states on partials or indicators next to the partial.

There is another benefit, but it deals with Validation which we’ll get to in a little bit.

Contextual Controls

Sections and Controls both have the active_callback parameters to control when displayed.

WordPress Customizer Contextual Control


The above example shows a Front Page Section that disappears when the Customizer Preview changes to a different page. When you are in a section that becomes no longer visible the Customizer Panel moves back to the main panel.

'active_callback' => 'is_front_page'

// or

'active_callback' => function() {
    return is_page();

The parameter can take either the name of a function, or an anonymous function as long as it returns a truthy value. WordPress includes many conditional functions that you can use like my use of is_front_page above.

You can do this with an entire section, or just an individual control. You can also base the context not on a page, but on the value of another control.

Otto has a great example that I used during my talk, but you can read about it on his page.

Customizer Sanitization

Any content that you let users add to the database must be sanitized. WordPress has some built in functions that you can use, but to be as safe as possible it would be better to create your own sanitization function.

Here’s an example of using a WordPress function:

'sanitize_callback' => 'sanitize_text_field'

This would work great for simple text fields or text areas. There is also sanitize_hex_color for other simple customizer values.

But if you have a radio or select field there isn’t a default way to know what your values are to sanitize them. Let’s set up a radio setting and sanitization function.

$wp_customize->add_setting( 'radio_setting_id', array(
    'default' => 'blue',
    'sanitize_callback' => 'thememod_customizer_sanitize_radio',
) );

$wp_customize->add_control( 'radio_setting_id', array(
    'type' => 'radio',
    'section' => 'custom_section',.
    'label' => __( 'Custom Radio Selection' ),
    'description' => __( 'This is a custom radio input.' ),
    'choices' => array(
        'red' => __( 'Red' ),
        'blue' => __( 'Blue' ),
        'green' => __( 'Green' ),
) );

function thememod_customizer_sanitize_radio( $input ) {
    $valid = array(
        'red' => __( 'Red' ),
        'blue' => __( 'Blue' ),
	'green' => __( 'Green' ),

    if( array_key_exists( $input, $valid ) ) {
	return $input;
    } else {
	return '';

We’ve added a control with three radio options, red blue and green. We also declared our sanitize_callback and wrote the function below. This function takes the $input of what the user entered in the field.

In our sanitize function we first setup a new array of what the valid responses could be. This would be dependent on your own options. Then we check if the array key from the input value is found within that valid array. If it is we return it, otherwise we return an empty string.

One problem with Sanitization is when the input is bad an unexpected value returns.  Another example could be the user didn’t input a correct email address. The sanitized value saves and the user isn’t given an information about what went wrong. Validation added in WordPress 4.6 fixes this problem.

Customizer Validation

Validation checks the validity of the values. If an error occurs it returns the dirty values, notifies the users, and the data is never sent to the database. In fact if one setting has a validation error nothing saves.

The Customizer also jumps to a section that has a validation error if the user has moved to another panel or section in the Customizer.

Lets take a look at an example from the WordPress handbook, setting up an established year setting.

'validate_callback' => 'validate_established_year'


function validate_established_year( $validity, $value ) {
    $value = intval( $value );
    if ( empty( $value ) || ! is_numeric( $value ) ) {
        $validity->add( 'required', __( 'You must supply a valid year.' ) );
    } elseif ( $value < 1900 ) {
        $validity->add( 'year_too_small', __( 'Year is too old.' ) );
    } elseif ( $value > gmdate( 'Y' ) ) {
        $validity->add( 'year_too_big', __( 'Year is too new.' ) );
    return $validity;

We pass in two variables to our Validation function, $validity and $value.

The $value is what the user entered into the control similar to Sanitation. $validity will add any errors that occur in the validation, if it returns empty than no validation errors have occurred.

In this example we first do a little sanitation making sure the value is positive integer. Then we check to make sure it is a number. If not we use the $validity->add method with two parameters. The first is the id of the error, the next is the text displayed to the user in a notification.

After checking to make sure the value exists, we check if it is lower than 1900 or greater than the current year. $validity return errors if either are true.

You can do this with any of your settings. This adds a level of communication with users as they add content to the customizer.

WordPress Customizer Validation

Here is that example in action. When I hit Save & Publish the Customizer jumps back to the section that had the error and gives me the notification. When I fix the error and click Save again, the notification goes away. The Saved & Publish button changes to Saved, showing the save was successful.

It would be better if the error went away as soon as the user fixed the issue instead of having to hit save and publish the changes.

This is possible and it’s thanks to Selective Refresh

Validation with Selective Refresh

Earlier I mentioned that Selective Refresh creates a link between the preview and the control. Every time the refresh occurs the control goes through validation.

When an error occurs the notification will appear and the dirty value will remain in the input. However in the preview it will revert to the last saved value.

After the user fixes the error than the Customizer removes the notification.

Lets set up selective refresh with the above example.

        'selector' => '.established-year',
        'render_callback' => 'thememod_established_year',

function thememod_established_year() {
    echo get_theme_mod('established_year');

First I register the partial for the established year setting and assign a css selector to link with the page. I have a span tag with this class that wraps around the year.

My render callback is simple echoing the value from the database.

WordPress Customizer Validation with Selective Refresh

As soon as I make the date too old or too new the error notification appears and the value in the preview reverts to 1900, which was the last saved value.

The Future of the WordPress Customizer

The Customizer has seen lots of improvements over the past few versions. As I’m writing up this post 4.7 is nearing completion and it’s adding even more. Here is the slate:

  • Customize Changesets (transactions)
  • Create pages in menus
  • Improve sliding panel UI
  • Custom CSS

Changesets will be a big change. They will allow you to save a draft of your customizations and share those changes with another person before publishing. Also Custom CSS in the core Customizer will be a great addition for small theme-specific CSS. Many people already use plugins to add this functionality and Jetpack has had this as well. The main challenge that be the difference between a theme-specific and site-specific changes used to add styling.

I will write up more about these changes when 4.7 launches.

Missing Pieces

Having now done my talk and written this companion piece I found quite a few things that I should have included. I didn’t talk much about using Javascript to connect to the Customizer API. I also didn’t do much with advanced types like Image Uploads.

As I dig into the Customizer I plan to write more posts about all the features and tools available. I’ll also write about new features that get added to any future releases.

Until then, Happy Customizing.

My WordCamp Sacramento 2016 talk on

WordCamp Sacramento Speaker

My WordCamp Sacramento 2016 talk Rediscover Theme Settings With The Customizer is now available on! I had such a great time with my first talk, though I know  I’ll have a lot to improve on for the future. If you missed out on my talk here it is:

I’m still working on turning this talk into a larger blog post, but it’s getting a little big and I might break it up into a couple. I should have the first part up later this week.

WordPress Customizer Types

WordPress Customizer Types

Over the weekend I gave my first talk at WordCamp Sacramento 2016. My topic was on the WordPress Customizer and how to start leveraging it to add custom settings for your theme. From WordPress Customizer Types to all of the live previewing, sanitation, and validation. The talk went really well even if I went too fast and forgot to mention a few things. But I had some good questions during my q & a and had several attendees approach me and tell me they enjoyed the discussion. Here are my slides from the talk.

I even had one group that came up and said I had completely changed their mind on the Customizer. That alone made the talk a great success in my book!

I’m working on turning that talk into a full blog post but for now I had several people asking for examples of all of the controls you can add to the WordPress Customizer. I’ve started making gists for each type that includes the setting, control, sanitization. Validation is really specific to each setting and theme, so I’ll do a future blog post on examples of validation.

If you want to use any of these in your code the settings and controls need to be within a customize-register hook. The sanitization and validation functions could be outside the hook, or called in a separate file for better organization. Many of the sanitization functions I use are straight from the WordPress Theme Review Team.

Normal WordPress Customizer Types

I’ve included a sanitization function in each of these gists, but if you look closely some of them are the same function used for different Customizer types. For instance the select and radio controls both use the themeslug_sanitize_select function. These controls both add a choices argument and the sanitization is first grabbing all of the choices and then checking the input to see if the array key matches any of those in our choices.

If you add more than one to a project I recommend moving your sanitize functions to their own file or at least grouped together in one place of your customize.php file.




This date field is outputting the date as a string with a format of 10-25-2016. The sanitize function is going to make sure this is the same format, so if you want something different you’ll need to update the function.


Similar to the date field time has a format associated with it. This field is only looking for hours and minutes and in military time.




Radio Buttons




Advanced WordPress Customizer Types

Color Control

Image Control

Using the WP_Customize_Media_Control is different than you would think, because the filename of the image you choose is not saved to the database, only the ID of the image is saved. So the sanitize_callback I use is absint, to make sure the ID is a valid positive integer.

To aid the user if they choose an incorrect file we’ll use a validate_callback to check the file extension of the file versus a list of approved types. In this example if they don’t choose a file, or if they choose something outside the approved list they’ll get an error notification.

More to Come

These are several common types that you’ll deal with when adding to your Customizer. In the future I’ll add more and include how to make your own control types.

One Week Till WordCamp Sacramento 2016 (and my first talk)

WordCamp Sacramento 2016

WordCamp Sacramento 2016 starts next Saturday, October 22nd, and my talk, “Rediscover Theme Settings with the Customizer” will be not only my first at a WordCamp, but also my first ever.

WordCamp Sacramento 2016

I decided I wanted to do more to give back to the WordPress community so I submitted my proposal not really sure what to expect. When it got accepted I was really excited, and scared, and happy, and nervous. As with any new public speaking foray I went through all of the emotions but now that I’ve prepared my talk and my slides are almost ready I’m fully prepared and expect a great time.

I decided to talk about the Customizer after working with it on a few theme projects. I started researching all of the capabilities of the Customizer and also saw a lot of great features that are in the works for future releases. It wasn’t too hard to get going with it and I wanted to share my experiences and also help get people who might be familiar but not aware of the newest features.

Last year’s inaugural Camp was my first and now with two days of learning it’s going to be a busy weekend fun and learning

Here is the interview WordCamp Sacramento did with me after my proposal was accepted.

WordCamp Sacramento Speaker Q&A: Anthony Skelton


WordCamp Sacramento 2015

WordCamp Sacramento

This was the inaugural year of Wordcamp Sacramento.  This seemed fitting as it was also my first Wordcamp to attend. The program lineup had many interesting talks scheduled and I knew I wouldn’t have a dull moment.

I even volunteered to help out in the Happieness Bar for an hour during the day. My WordPress development has come a long way over the past couple of years. Volunteering allowed me to help others and be a part of the Sacramento community.

After picking up some new swag and attending the opening remarks it was off to the advanced track room.

0900 – Local Development with Vagrant & VVV

John Trujillo of Tytanium Ideas began the day talking about local development. He walked us trough the process of setting up a virtual machine using Vagrant. The big advantage than Jon stressed is the ability to match your local development to your server. Then you can use the version of software that your production environment is running. You can also share the setup so others in your team can quickly spin up the same local environment.

The magic of VVV

Varrying-Vagrant-Vagrants is a Vagrant environment that has been configured for WordPress Development. While Vagrant is for setting up any virtual server, VVV is built specifically to build WordPress Plugins/Themes/Apps. It includes a lot of tools out of the box

  • Ubuntu
  • nginx (apache version available)
  • 4 Standard WordPress Instals
  • WP-CLI
  • lots more!

John walked us through the process of getting all this setup on our own computer. Vagrant uses shared folders so you can create your WordPress files in your own directories and they work within the VM. You can either use phpMyAdmin, Sequl Pro (or eqv), or even SSH into your server with Vagrant  to access your VM’s database.

I’ve been using VVV for a few months so I had already gone through the process of installing and setting it up. Though most of this was review it was great to see another developer go through a similar process to setup a local development environment. John also touched on some other Vagrant projects focused on WordPress Development. The Mercury Vagrant (HGV) is built by WPEngine to match their environment. There is also Trellis which uses Ansible for provisioning a LEMP stack for WordPress.

1000 – Content Design – Getting the Most from your Content and Images

For the second talk I decided to slide over to the beginner track to see Dawn Pedersen’s talk on Content. I misread the schedule and didn’t realize that I would miss out on Vasken Hauri from 10up talk about everything Cache.

The talk began where most content begins, with the text. Writing and formatting text is important to deliver your message to the reader. Unlike a book or magazine, people rarely read a webpage word for word. We jump around and scan the page looking for things that are meaningful.

This means you should write your copy so it is scannable, and above all else, avoid the Wall of Text! Some other tips were:

  • Use the Inverted pyramid
  • Write Simply
  • Limit yourself to one idea per paragraph
  • Break texts into lists ( like this 😛 )
  • Use Headings and Subheadings
  • Highlight Keywords

The Inverted Pyramid

People will decide if they will keep reading based on the first sentence or two. So you need to get to the point first. It means they could read the first paragraph and have the broad understanding of your subject.

From here use broad strokes and then the important details. Try to flesh out your ideas in the later paragraphs. You also want to use good transitions to get from one idea to the next.

Write Simply

Just because you write your subject simply doesn’t make the topic simple. The key is to understand a complicated idea and express it simply. Dawn gave some great tips to incorporate into your writing.

  • Use vocabulary that is easy to follow
  • Avoid jargon and cleaver wordplay
  • Get to the point quickly
  • Sort words and phrases. Consise 2 to 3 sentence paragraphs
  • Use half of the word count as for printed text
  • Replace passive phrases with active phrases
  • Don’t center text! Ragged left edge is difficult to read
  • Re-read and make sure it makes sense
  • One idea per paragraph
  • Keywords and the beginning and end of paragraphs

Many of the other text formatting tips are pretty straight forward and make it easier for the reader to consume your writing.

More Content Tips

Writing on the web, especially a blog, we have a few more tricks for styling and presenting our text content. These range from changing line breaks to prevent widows, controlling excerpt content, and moving users through your site.

When you have a post title or a subheading you might end up with one word on a second line if the title is long. The lone word is called a widow and is not desirable from a design standpoint. A way around this is adding in &nbsp; to your title. This is a non-breaking-space and you can add a couple to push another word onto the next line. This is a workaround and isn’t the best coding wise, but helps the presentation.

On the main blog index you can show your entire posts, or you can define an excerpt. In your post you can either add a read more tag, or use a custom field to write your own excerpt.

Once you have people on your site, you want to keep them there. Linking within your article to other relevant content makes it easy for them to keep reading. You also get the benefit of Google rewarding you for self linking.


With faster internet connection speeds there are more and more images on web sites. WordPress makes it easy to work with and align images in your articles and featured images are great to start your post off with a bang. Here are some good tips for working with images.

  • Use Large images. Especially your featured image as Facebook will grab this for the shared link.
  • Begin with the best quality image you can manage
  • Optimize images before you upload to WordPress
  • Reduce it to the appropriate size that you will use.
  • Be careful with image floats and alignment
  • Interesting images should get their own line
  • Make sure to rename your image file names
  • Try using captions to further explain the image. It’s another way for eyes to scan the page
  • Use images that are relevant, interesting, and appealing

1300 – Coding Together: A Dev Workflow

Peter Chester from Modern Tribe spoke about his journey from solo developer to working with a large team. There are benefits to working by yourself.

  • Control over the project
  • Low Overhead
  • Stay Competitive
  • Be Efficient

But with all these benefits come the mighty negatives. The stress, multitasking, many hat wearing and lonely times. Working with a team can lead to many more benefits that not only help you, but your customers.

One of the big things that Peter talked about was the development workflow. He shared his solo workflow, and how it evolved as more people began to work on the project.

At Modern Tribe they use the git-flow branching model. The above workflow begins by creating a new feature. It has many steps in quality control and testing before finally being merged into the project.

Another topic that Peter discussed was what he called Conscious Coding. In this he means we all need to code for not only ourselves, but for the coders and designers who will work with the code in the future. You need to use clearly named Classes, variables, function titles. These along with succinct documentation bring everything together.

1400 – Way of the Future

During Jon Trujilio’s opening talk about VVV he mentioned other projects were also using Vagrant for local development. Jason Cosper from WP Engine gave his talk on an exciting competetor to VVV, Mercury Vagrant (HGV). It was built by WP Engine to maximise your production environments to their hosting, but you can use HGV no matter where you end up hosting. And HGV is all about the future.

So many of todays sites run on old versions of PHP. HHVM from Facebook looked to be the future for WordPress, but then came PHP7. As Jason says, PHP7 is PHP on steroids, and he gave some impressive benchmarks.

Developers need to use these new tools to build sites for the future. VVV is great, and an industry standard. But it still ships with PHP 5.5. The beauty of HGV is the ability to not only test your site with PHP5.5, but also PHP7 and HHVM at the same time. You drop your files in one folder and then use subdomains to test the same site with different processors. There are even links in your WordPress Admin bar to switch between 5.5, 7, and HHVM.

Everthing about the future of coding relies on speed, and HGV is a great tool to test your site and prepare it for the future.

1530 – Ad Revenue 101

After several advanced course classes I switched back to the beginner room to hear Ben Ilfeld’s talk on WordPress Ad Revenue. I’ve never dealt with ads in a website so there was a lot to learn.

Ben began with a lot of information about the history of ad technology and the modern Ad Ecosystem. Ad Networks make it easy to aggregate media sites for advertising. New technologies changed the landscape with Real Time Bidding and Ad Exchanges. The Ad Networks transformed into these Exchanges where bidding and auctions were happening on a massive scale.

With the Ad Exchange you can sell space yourself with no need for a sales person. There is a lot of data and some sophisticated algorithms about each potential ad shown. Because of these large scales the prices are unbelievably low.

What are the other options?

You can choose to sell space yourself. Having a website with a good niche market would allow you to own the direct relationship with the advertisers. Another option is joining the global market and focus on growing your traffic.

You could also do both! But this is likely only for bigger sites.

How to get started

DoubleClick for Publishers by Google. It’s free but can be complex. Also good for managing direct sold, ad networks and exchanges. It’s owned by Google, so you know it’s not going anywhere.

There are other plugins for WordPress that let you manage your ads. Ad Code Manager is easy for non-developers to configure a complex set of ad codes. The plugin still works, but isn’t in active development.

Broadstreet is another service that is independent and affordable. It’s great for managing direct sold with smaller advertisers and it has an up to date WordPress plugin.

Another option for integrating ads is with a related posts plugin. YARPP or Yet Another Related Posts Plugin lets you integrate sponsored links next to your related posts.

No easy beginning

Something I got from the talk was there is no silver bullet to sucuessful advertising. You’re going to start small and have to work your way up. As you increase the demand for your audience you can add more ad networks and extensions to grow your revenue.

1645 – Lightning Talks

The day ended with three lightning talks, about 15 mintues each, and were jam packed with information.

iThemes Security

There was a lot to talk about so John Locke jumped into it and never slowed down. Here are some of the key points and benefits to using iThemes security

  • Update WordPress Salts, makes everyone re-login to Wordress. Great way to get the bad guys out quick.
  • Change database prefix
  • Change the wp-content folder name
  • Schedule backups of your database. Have these backups emailed to you.
  • XML-RPC request – Allow, Block, or just block Pinkbacks
  • 404 Detection – blocks out after a lot of 404 hits when someone is trying to find a backdoor
  • Change admin username and the database row. Not row number 1.
  • Away Mode – Set when your Dashboard is available. The login screen will be unavailable.
  • Brute Force Protection – join the network of blocking IP’s who are guilty of Brute Force
  • File change protection
  • Hide the login Area
  • Disable the file editor

I’ve been using a different security plugin for awhile but after all the great tools that John described I’ll be switching to iThemes soon.


Alex Christensen gave an introductory talk about selling through your WordPress site. He covered a ton of basic questions that you need to answer before you sell your first item. I didn’t take many additional notes but his slides are avaiable here.

Near the end of the slides is a big table detailing the abilities of six of the major ecommerce options. It’s a great tool for making sure the plugin you pick is the best choice for what you need


Russell Aaron ended the WordCamp with a talk all about forms. One of the first big pieces of knowledge he dropped was that WordPress is full of contact forms. You use forms to fill out information and send it to another place. Sometimes this is to fill out a new blog post and send it to the database, or saving settings to a different table in the database.

Another idea he discussed was about filters. WordPress keeps developing filters to keep your site safe. They also progress WordPress to become more. You use filters to help keep your front side forms safe from the public and their malicious content.

After telling a story of some ridiculous problems he’s caused with bad plugin updates he reminded us this fact of widsom: Plugins are not bad because they’re called plugins, they’re bad when a drunk coder pushes bad code.

Wrapping Up

I had a great time at the Sacramento Wordcamp and I wish I had starting going to Wordcamps years ago. There is so much to learn about Wordpress from some very talented speakers. I also made a few connections that I hope to keep in touch with and see again at the local Sacramento WordPress Meetup. If you haven’t been to a Wordcamp yet, what are you waiting for?

My Steam Achievements Plugin is Officially Launched

Wordpress Steam Achievements Plugin

After realizing that my achievements plugin hosting request at was not the final step in the process I successfully went through the steps to push my plugin to the repository.

I kept checking back and searching for the plugin but it was taking forever to be added. I then did a little more research and saw that even though I had the plugin in a zip file they weren’t going to do the work for me and I had to upload it myself. I probably should have realized it sooner but got caught up in other things.

The process was actually quite easy. I followed a walkthrough from the Digging Into WordPress Blog and there are very few steps.

  • Create a folder inside your plugins main directory to house the local version of the repository
  • Checkout the svn from your approved directory
  • Copy the files into the local version folder.
    • Screenshots into the Assets folder
    • All other files into the Trunk folder
  • Check in the svn

I like that checking in the svn automatically connected and uploaded my changes to the repository. I was anticipating something similar to git where you add the files, then commit them, and then push. This seemed to skip a step. I was so happy the process was easy I instagrammed my success.

Pushing my first plugin to the WordPress repository.

A photo posted by Anthony Skelton (@mranthonyskelton) on

Now that the plugin is in the repository I’ve started plans for the next update. So far it only adds your TF2 achievements. Next up will be CSGO and Left For Dead 2. I’ll have to research from there what games are most popular and in need of something like this. DOTA2 probably needs its own plugin since the game is so big.

Here’s my project page that will have all of the updates and information

Intro to the WordPress JSON REST API

WordPress API

Last night I attended my local WordPress Meetup with the topic of the WordPress JSON REST API. I was really excited to attend because the whole idea of a REST API is something I know about, I just don’t really know what it does and what the purpose of it is. All that has changed.

Getting Some Closure

The discussion was led by Vasken Hauri of 10up. The subtitle for his talk was “Using the WP JSON API & Best Practices for Javascript and jQuery in WordPress.” He gave a great overview of how the API can be used and then launched into some code for best practices. There were a few moments I was very puzzled, then I realized that I knew what he was talking about, I was just used to seeing it in a different way.

My main experience in using a JSON API was my recent work on the Steam Achievements plugin I’ve been working on. Now I see that with the API plugin installed in your WordPress you can connect to the site to perform CRUD operations. JSON is great to work with because its a lot of data in a small package, and it’s a standard for giving and getting data across the internet. Using JSON to communicate to your WordPress site gives you a way to separate the data from the presentation.

This is best understood by a couple examples that were presented. This JSON REST API plugin was developed by the MOMA blog Inside / Out. Their site is presented as a Ruby on Rails front end, but use WordPress as their publishing platform. The use the JSON API in their Ruby Templates that pull the data from the WordPress Database.

Another great point that Vasken mentioned is the JSON end points will still work with cached pages. It will also be backwards compatible when WordPress adds the JSON API to WP Core, which will be happening in the next couple of updates.

There is a Chrome extension called Postman that lets you play around with all of the JSON REST API your site is outputting. You can even do it while running a site on a local server. I just installed it in Chrome and looking forward to seeing what I it can do.

Best Practices Going Forward

With the addition of the JSON REST API to Core its going to mean a lot more people are writing Javascript and Vasken wanted to give an overview of why its important to code in a way that wont screw things up in the future.

He began with some good examples of performance. Reminding us that it in PHP you want to avoid multiple calls to your database. Similarly in JS you want to avoid multiple calls to your DOM. Instead you should save the object that you call into a variable. However with all of these variables being made it can be a problem if you don’t plan your naming and run into name collision.

Prefixing your function names is a good option, but you can do one better in both PHP and in JS. Object Oriented PHP lets us avoid function name collisions with creating a class and instantiating it.

Whenever you have to globalize a variable make sure that it is unique. Don’t get lazy and give yourself problems in the future.

Javascript has a similar concept called Closures. Everything you can get with a PHP class you get with a Javascript closure.

With more Javascript being written to work with the JSON REST API we should be working within closures so we create functions that act on an instance but don’t go anywhere and muck things up.

Key Concepts

In closing Vasken gave us a few concepts to make sure we left with.

  • Write performant Javascript – Think about the limitations of your users and their devices. He recommended to test your Javascript and compare in different browsers/computers.
  • Consider the WordPress Ecosystem
  • Use Closures for your plugins whenever possible

I still have a lot to learn when it comes to Javascript. I’ve been reading David Flanagan’s Javascript: The Definitive Guide. It’s slow progress since I have so much else going on but I want to continue to expand to better jQuery and to a framework like Backbone or Angular as well.

There’s a lot on the horizon, but I’m ready to take it on.

Just Build Websites

computer practice wordpress

I often fall into a pattern when I’m learning new things. I get really excited and want to learn everything. Then I learn about a related topic, and shift all focus to the new thing. This makes me somewhat knowledgeable in a lot of things, but never really great at one thing. I’ve always heard the term “A jack of all trades is a master in none” and I always thought that I could overcome that stigma.

It’s not that easy.

Just telling myself that I can still be very proficient in lots of things and still be very successful only gets you so far. I’m not complaining about the life I’ve lived, because I’ve had a lot of good times. I think I’m looked at as someone who knows what they’re doing. And most of the time I do. But I have bigger goals and accomplishments I want to make for myself and this cyclical status quo wont get me there.

The past month I began to learn Ruby. I’ve been working with WordPress sites for a while and getting pretty good with my PHP but I had a crazy idea for an app that I wanted to develop and thought that Ruby on Rails would be the best platform for that. I did some research and didn’t see anyone who had done my idea yet so I thought I was in a good place. I found a couple Ruby books and began the Ruby on Rails track on Treehouse.

Probably a big factor in my wanting to learn everything comes from my sources of education. I’ve jumped around a lot of the big learning sites like Tuts+, Code School, and most recently Treehouse. I think you can get a lot of basic knowledge from these sites and they push you in the right direction, but you need to step back after you learned new skills and practice them. Since I was paying a monthly subscription I always wanted to make the best use of my money and keep learning more and more skills. I would jump from one course to the next. This made my quick jump into Ruby land possible. But instead I should have taken a step back and continued to develop and practice WordPress skills that I had just learned.

I had just finished the WordPress plugin Treehouse course before jumping ship so I had ideas for a few different plugins that I just abandoned. This morning when I went to look at them I recognized some things but I had forgotten a lot since I never made time to practice. This time I want to break my cycle.

I have a couple ideas for WordPress Plugins that I’m going to work on. I’m also going to work on developing themes from PSD files. I’ve found a few free PSD site layouts that I’m going to use to  design themes. They may not be the best sites, but they’ll give me good practice in building a quality theme from the ground up. After I’ve done several that I feel confidant about I want to develop a solid theme that I can release to the free theme repository and begin to give back to the community.


A Designers Guide To WordPress

designers guide

I’ve been attending the Sacramento WordPress Meetup Group for the past few months and I’ve enjoyed discussions talking about Genesis, Responsive Styling, and most recently how to design for WordPress. For this most recent talk we had a guest speaker from the Bay Area, James Hipkin, from Red8 Interactive.

Mr Hipkin mentioned a couple times during the discussion that he is not a designer, nor a developer. Instead he brought a unique perspective as the manager of a creative team. He interacts with the clients and has a first hand look at things that do and don’t work. The topics ranged from how to best start a project to designing responsively and responsibly. I wanted to touch on a few things that really stood out to me as a developer in his designers guide to wordpress.

Responsive vs. Adaptive

One of the first things covered were some basics of web design before jumping into WordPress specific topics. Mr Hipkin first talked about designing mobile first and mentioned one of their clients, Bev Mo, recently surpassed 50% mobile traffic on their site. He then talked about how he differentiates between a responsive and an adaptive site. I’ve never had a great answer for the difference but his explanation made a lot of sense.

Responsive sites adjust all the content of the site to fit the screen being displayed. Whereas Adaptive change the content that is available based on the device. A great example was a call now button that might show up on a mobile phone, but disappears once the screen size is beyond mobile devices. Another example was a slider that might turn into just a static image on mobile.

While the difference is slight I feel more confident in this discussion with future clients.

Static Content

Using WordPress I often want to make it so the client could go in and change any part of the site. I mean, that’s what makes WordPress so easy, the customizable back end that doesn’t scare off clients. However if speed is of upmost concern (and when isn’t it?) you want to limit the number of calls to the database. This means if you have content that doesn’t need to change, like their social links, phone number, or other static content you can build it into the html to minimize the amount of times the database is accessed. So the footer doesn’t necessary need every part to be widgets. You can build things into the template directly.

Control your Visual Editor

Mr Hipkin brought up a great point when talking about all the elements that need to be styled. He said clients often forget to specify what they want the styles of their visual editor to look like. There are a lot of controls on top of the content box and lots of ways the client can kill the site if things are not styled appropriately.

Footer Fettish

Ok well he didn’t mean to talk about the footer in this way. Mr Hipkin just said he wished more love was given to the footer as they are often forgotten by the client and designer and can hold a lot of secondary information. He said he wished there was a group for people who liked the footer as much and this was turned into a footer fettish by the audience. But potty humor aside it’s a great point to make your design with the footer in mind. It’s a great place to put terms and conditions, style guides, contact information, newsletter signups etc.

Closing Thoughts

James Hipkin is a great speaker and obviously very excited to talk about all things WordPress. He answered a lot of the audiences questions as he went through his talk and also took some time to show us examples of work they had completed. He also gave a lot of insight on how to work with clients and build your design business. I know Red Cart will be no where near what Red8 is any time soon but it’s a nice thing to shoot for.

You’ll never get anywhere if you never try.