Fun

Dynamically Register New Sidebars in WordPress with Advanced Custom Fields

The Advanced Custom Fields plugin offers a plethora of possibilities for enhancing WordPress functionality. The following is an example of one such possibility.

In the process of building a new WordPress theme for a client, I wanted a way for administrators to dynamically create new widgetized sidebars and then select which sidebar to use on a per-page or post basis.

Notice: This project requires the repeater field available as a premium add-on in ACF 4.X or included with ACF Pro.

Lets start with the basic “register_sidebar” function in the functions.php file

/*
 *
 * Register Sidebars
 */

function sidebar_widgets_init() { //Register the default sidebar
 register_sidebar( array(
 'name' => 'Sidebar',
 'id' => 'default-sidebar',
 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
 'after_widget' => '</aside>',
 'before_title' => '<h1 class="widget-title">',
 'after_title' => '</h1>',
 ) );
 include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
 if (is_plugin_active('advanced-custom-fields/acf.php')){ //Check to see if ACF is installed
 if (get_field('sidebars','option')){
 while (has_sub_field('sidebars','option')){ //Loop through sidebar fields to generate custom sidebars
 $s_name = get_sub_field('sidebar_name','option');
 $s_id = str_replace(" ", "-", $s_name); // Replaces spaces in Sidebar Name to dash
 $s_id = strtolower($s_id); // Transforms edited Sidebar Name to lowercase
 register_sidebar( array(
 'name' => $s_name,
 'id' => $s_id,
 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
 'after_widget' => '</aside>',
 'before_title' => '<h1 class="widget-title">',
 'after_title' => '</h1>',
 ) );
 };
 };
 };
};

add_action( 'widgets_init', 'sidebar_widgets_init' );

What we’re doing here is initiating the standard Default Sidebar as well as looping through a repeater field that we will be setting up in our ACF Options.

To set up those options, create a new repeater field in our Options field group with the following settings…

Sidebar Options
Now we have the ability to dynamically register new sidebars in our options like this…

Add New Sidebars

Now that’s only half the battle! Now, we want users to be able to select which sidebar they’d like to use when create a new page or (optionally) a post.

We do this by first creating a new ACF field group called “Select Sidebar”. This group only has a single select field. In this case we’ll label it “Select A Field” and make sure it has a name of “select_a_filed”. Add field instructions if you wish and leave everything else default. Make sure to leave the Choices field empty. We will be populating this dynamically based off of the sidebars we register on out options page.

Add the following code to our functions.php file…

/*
 * ACF Sidebar Loader
 */

function my_acf_load_sidebar( $field )
{
 // reset choices
 $field['choices'] = array();
 $field['choices']['default-sidebar'] = 'Default Sidebar';
 $field['choices']['none'] = 'No Sidebar';
 // load repeater from the options page
 if(get_field('sidebars', 'option'))
 {
 // loop through the repeater and use the sub fields "value" and "label"
 while(has_sub_field('sidebars', 'option'))
 {

 $label = get_sub_field('sidebar_name');
 $value = str_replace(" ", "-", $label);
 $value = strtolower($value);

$field['choices'][ $value ] = $label;

}
 }

 // Important: return the field
 return $field;
}

add_filter('acf/load_field/name=select_a_sidebar', 'my_acf_load_sidebar');

This code populates our “Select A Sidebar” field using the add_filter function. It starts by creating two options by default. A “Default Sidebar” and a “None” option. These should be self explanitory, but just in case, the Default Sidebar is the standard WordPress sidebar available from the start. The “None” is exactly that. No sidebar will appear on the page.

Select A Sidebar Group

We’re almost done, but depending on your template, chances are you’ll need to make some modifications to the sidebar.php file.

This is what mine looks like…

/*
 * sidebar.php
 */

<div id="secondary" class="widget-area span4" role="complementary">
 <?php do_action( 'before_sidebar' ); ?>

 <?php
 $sidebar = get_field('select_a_sidebar');
 if($sidebar != 'none'){
 dynamic_sidebar($sidebar);
 };
 ?>

<?php do_action( 'after_sidebar' ); ?>
</div><!-- #secondary .widget-area -->

What we’re doing here is calling back to our “Select a Sidebar” field to see what the user has chossen for his sidebar. If “None” was selected, then no sidebar will be returned.

And that’s it! Now we have given our users a way to create new sidebar containers and select which conaiter they’d like to use on their pages on a per-page basis.

I hope this helped, and if you see a way to improve this process, I’m all ears.

Custom Stylesheet in WordPress with Advanced Custom Fields and the ACF Options Add-On

I absolutely love Advanced Custom Fields and us it for every WordPress based project I develope. This, in hand with the Custom Post Types UI plugin really help to flesh out WordPress as a much more complete content management system.

With the help of many other WordPress users and Google searches I have been using ACF and the Options add-on to generate custom stylesheets. That way, administrators can easily go into the WordPress Dashboard and modify the look of the site without having to dig into the CSS directly.

To make sure I didn’t forget how I accomplished this in the futre, and to have a guide for doing so in upcoming projects, I decided to write out this small guide.

A couple things of note:

  • This guide is based off of the most current version of ACF (4.1.1) as of May 6th, 2013 and is best used with the premium Options add-on for ACF.
  • I use a sub-directory called “layouts” for all of my css file (excluding the WordPress required style.css). I would recommend the same approach as it helps to keep your files structured and easy to find later. Especially if you tend to use a lot of different stylecheets (Bootstrap, Font-Awesome, ie-hacks, etc.).

Lets start off by adding a new folder called “inc” to our theme directory. Create a new file in here called custom-styles.php.

The contents of your new file will look a lot like standard CSS but you will have the ability to add all sorts of custom php and ACF field data. For example…

/* Typography
--------------------------*/
body {
 color:<?php the_field('default_text_color','option');?>;
 font-size:<?php the_field('default_font_size','option');?>px;
 font-family:<?php the_field('default_text_font_family','option');?>;
 line-height:<?php the_field('default_text_line_height','option');?>;
}

h1,h2,h3,h4,h5,h6 {
 color:<?php the_field('default_headline_color','option');?>;
 font-family:<?php the_field('defaut_header_font_family','option');?>;
}

a {color:<?php the_field('default_link_color','option');?>;}
a:hover{color:<?php the_field('default_linkhover_color','option');?>;}
a:active{color:<?php the_field('default_linkactive_color','option');?>;}
a:focus{color:<?php the_field('default_linkfocus_color','option');?>;}
a:visited{color:<?php the_field('default_linkvisited_color','option');?>;}

This is just a small example of the code possible and is based off of fields I have created for my Options page with ACF. The fields created, and how you choose to use them are all up to you!

Next, we’ll be adding the following code to our functions.php file. this code will parse out our custom-style.php file and write a brand new custom-style.css file in our layouts directory.

function generate_options_css() {
    $ss_dir = get_stylesheet_directory();
    ob_start(); // Capture all output into buffer
    require($ss_dir . '/inc/custom-styles.php'); // Grab the custom-style.php file
    $css = ob_get_clean(); // Store output in a variable, then flush the buffer
    file_put_contents($ss_dir . '/layouts/custom-styles.css', $css, LOCK_EX); // Save it as a css file
}
add_action( 'acf/save_post', 'generate_options_css', 20 ); //Parse the output and write the CSS file on post save (thanks Esmail Ebrahimi)

The code above can be modified to read from and store the files in various directories and with different filetypes.

Finally, we’ll enqueue the style so it appears in our page header and links to the brand new CSS file. Add this to your enqueue function in the functions.php file. This should probably be added as the last enqueued style in the function. This way, our new CSS file will be read last and have the ability to override any existing styles. (I should note that this portion is really dependent on your theme. How you add stylesheets to your theme is ultimately up to you, but it is highly recommended that you use the enqueue_style function in your functions.php.)

wp_enqueue_style( 'custom-styles', get_template_directory_uri() . '/layouts/custom-styles.css' );

To sum up, we are reading a custom-style.php file that can contain dynamic php elements. When a page is requested, the functions.php file fires off and parses this file outputing a brand new custom-style.css.

Obviously, we’re not limited to only generating css files. This could be used to generate any filetype your require. I’m also not a master level PHP coder and if anyone has any recommendations on how to better implement this strategy, please let me know.

Bag End – The Nature Academy Competition Entry

Bag End

Bag End - Click for High Resolution Image

Throughout the course of Andrew Price’s “The Nature Academy” Blender 3D training, images of the Shire continually popped into my head. It’s lush green imagery is evocative of nature in every way. When the competition was announced, I knew immediately what my subject would be.

There are more than 60 hours in this project, not including render times, and it was easily the most complex render I have ever attempted. The final scene consists of 412,297,837 vertices, 798,977,249 faces, and 10,036,000 strands. The final render time was slightly over two hours and 45 minutes. I chose to render the project out at 4k resolution at 3996x2160px.

Multiple render layes with individually set atmospheric falloff composite nodes were used to simulate depth. The trees in the distance are made up of a volumetric material as opposed to real geometry or billboarded images.

I would have liked to include shadows along the edges of the grass. The grass is currently rendered with “Strand Rendering” which cuts render time. With this option disabled, I was unable to complete the lighting calculations after more than 50+ hours of dedicated processing time. Perhaps a solution would be to apply yet another particle system only along to the edges and median of the pathway, which would have the strand rendering disabled.

I would have also liked to include real volumetric clouds. I have been unable to find a suitable graphic for the sky. At least not one that conveys the amount of distance I would have liked. Volumetric clouds could have helped in this aspect, but I believe the increased render times for this would have been intolerable.

“No artist is ever satisfied”, but when the deadline approaches, you just have to stick a pin in it. I hope I picked the right moment to pin this one.

I’d like to thank the guys in the IRC #blender channel as well as the ##NatureAcademy channel, especially DeanWronowski for the good competition, and Olson for being “just plain awesome”!