Variable Width Pages For Your Theme

Starting with WordPress version 3, WordPress Theme Developers can now set a global variable called $content_width to inform WordPress of the desired width of the page. This values is used when displaying full-width images and for videos.

But what if you have different widths for different pages? You need a way of indicating to the WordPress system of the page width that can change depending on the theme page being used. So here’s a small code sample that can detect different page templates and change the $content_width accordingly.

// set content width depending on page template
function dj_set_content_width()
{
  global $post;
  $sTemplate = 'default';
  if (isset($post) && isset($post->ID))
    $sTemplate = get_post_meta($post->ID, '_wp_page_template', TRUE);
  switch ($sTemplate)
  {
  case 'default':
  default:
    $nWidth = 584;             // default width (taken from twentyeleven theme
    break;
  case 'showcase.php':
    $nWidth = 480;
    break;
  case 'sidebar-page.php':
    $nWidth = 500;
    break;
  }
  // use additional conditions to set page width
  if (is_attachment())
    $nWidth = 584;            // use this width for attachment pages
  global $content_width;
  $content_width = $nWidth;   // set width to calculated value
}

add_action('wp_head', 'dj_set_content_width', 1);

The hook is on the ‘wp_head’ event, as this is the point in time that WordPress needs to know the width of the page. It does this at a priority of 1, so that other functions operating on the same hook will have the modified value already set.

The function determines the page width by looking at the selected page template, according to the _wp_page_template meta data value that WordPress uses to store which page template is used when displaying the page. The is the mechanism used by “standard” themes, such as Twentyeleven.

If you’re using a different theme framework, your page template may be stored in a different way. For example, the Genesis Framework uses the meta value _genesis_layout. If you’re using that framework, you will need to obtain the different value and modify the switch-case appropriately, checking for values like ‘content-sidebar-sidebar’.

As indicated on Line 22, you can also use additional theme test functions to enable different width on specific pages. Other test functions such as the is_author(), is_front_page(), is_404(), etc. can be added to the list.

With a little careful thinking and planning, you can achieve a theme that is very flexible in its ability to display images and videos and accommodate theme settings. You’ll run into some issues if you’re using a theme or framework that uses non-standard settings, but those are not too difficult to work through. Just be careful to fall back to a default width setting in the case that your page does not have this meta data set already.

, ,

No Comments

Add Search Form to Navigation Menu

Here’s a small piece of code that will add a search form to a theme’s navigation menu.

function dj_nav_search_box($sItems, $args)
{
    ob_start();
    get_search_form();
    $searchform = ob_get_clean();

    $sItems .= '<li>' . $searchform . '</li>';

    return ($sItems);
}
add_filter('wp_nav_menu_items','dj_nav_search_box', 10, 2);

How does it work?

It works by adding a filter, ‘wp_nav_menu_items’. This filter allows modification of the navigation menus that are displayed and is run after the menus are constructed but before they are output.

Lines 3-5 use output buffering to capture the contents of the theme’s search form. On Line 7, the search form is added to the menu contents by adding it to the menu within <li> tags.

The only thing that’s left to do is styling. I noticed on one of my themes that I needed to set the text color to white because the text of the search form was showing as black text on a black background is the navigation menu. So adding a CSS class of #navmenu .screen-reader-text { color: white; } does the trick. Of course, your theme is probably different, so your class names would have to change.

,

No Comments

Local WordPress Development

I find myself often telling other developers that the best way to do web development is to set up a local hosting environment. This allows you to create a duplicate of your web server’s environment on your own local computer.

To do this requires a few moving parts, including a Web Server (Apache is the most common web server on Linux platforms) with PHP support, and a database server (MySQL). Assuming you already have these parts installed and working, I will outline a few steps on how to configure a local development environment for WordPress (or any other PHP application) development.

Another alternative is to use a tool like XAMPP, which is an all-in-one Apache, MySQL, PHP solution. It’s great if you don’t want to deal with all the configuration intricacies and also provides tools for many of the steps discussed here. But if you’re like me and like knowing how all the pieces work, setting up your own Apache/MySQL servers is a good exercise.

First, I set up a host name. I like to use a host name that is very close to the host name of the ultimate install domain. So if your target domain is mywebsite.com, you can set up a local test domain as mywebsite.loc. I like to use “loc” for the top level domain. The reason for this is if I need to transfer the database from your local environment to the live host server, the TLD being the same length makes this a little bit easier. (More on that later.) Adding an entry to your hosts file will create the test domain on your local machine. It will look something like this:

127.0.0.1 mywebsite.loc

The next step is configuring Apache to recognize a virtual host for your newly created domain. On Windows, you can add something like the following to your httpd.conf file. On Linux, you can add a new file in your sites-available directory with the following:

# vv changes for local install
#  NameVirtualHost mywebsite.loc
<VirtualHost localhost:80>
  ServerName mywebsite.loc
#  ServerAlias mywebsite.loc
  DocumentRoot "{{install directory}}"
  <Directory "{{install directory}}">
    AllowOverride All
    Options Indexes FollowSymLinks
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>
# ^^ end of changes for local install

The {{install directory}} is where your PHP and other files will be located. It will of course be in different directories on Windows and Linux, but the directory can be almost anywhere.

Once the changes are made to your Apache configuration, you need to restart Apache for the changes to take effect.

After restarting Apache, you can copy your WordPress files (or whatever other PHP application you’re working on) to your {{install directory}}. Once the files are in place, you can use your MySQL tool to create a database for WordPress. This can be done from the command line with the following two commands:

CREATE DATABASE wordpress;
GRANT ALL ON wordpress.* TO username@localhost IDENTIFIED BY 'password';

Now you should be able to point your browser to http://mywebsite.loc and go through the normal WordPress installation steps. After you’ve done your work, tested your code and you’re ready to move to the live site, you can export the database to a text file. If you then change any references to mywebsite.loc to refer to mywebsite.com. Now you can import the modified SQL file into your database on the live site without the need for any other changes.

, ,

No Comments

Change “Enter Title Here” Prompt for Custom Post Types

Custom Post Types have numerous title configurations that you can set when you create them. However, the in-field title that is displayed before you enter the post’s title is not one of them. Have no fear, there is a filter that can be used to modify this. This is what the in-field title looks like without any modifications:

Press Release Title

To change this, you can use the following code:

function dj_filter_title_text($title)
{
    $scr = get_current_screen();
    if ('press-release' == $scr->post_type)
        $title = 'Enter Title of Press Release';
    return ($title);

add_filter('enter_title_here', 'dj_filter_title_text');

This example assumes you’re building a Custom Post Type for press releases. Line 3 gets the screen object that is use to detect which post type is being used. Line 4 tests the screen for your Custom Post Type. In this case, we’re checking it against the ‘press-release’ post type. We only want to change the title for the post type that we’re targeting, so this test is necessary.

The last line adds our filter function, dj_filter_title_text() to the functions that will be called for the ‘enter_title_here’ filter.

That’s all there is to it.

This filter is available in WordPress version 3.1 and above.

,

No Comments

Custom User Data

There are often times when you need to collect custom user information on your WordPress site. Here’s a quick run-down on how to set this up:

There are four WordPress actions used for this and they are separated into two groups.

The first set of actions hook in to WordPress when it presents the user fields for viewing and editing. The hooks are: ‘show_user_profile’ and ‘edit_user_profile’. These can both be hooked up to the same callback function that outputs the HTML with the user fields.

The second set of action hooks are used when WordPress is saving the data fields displayed by the first callback. These hooks are: ‘personal_options_update’ and ‘edit_user_profile_update’. Like the first set, these can both be hooked up to the same callback function.

Here is some sample code that provides both callback functions and hooks in to all four actions:

define('DJ_TEXTDOMAIN', 'your_textdomain');

function dj_addCustomUserProfileData($user)
{
?>
    <h3><?php _e('Additional Profile Information', DJ_TEXTDOMAIN); ?></h3>
    <table class="form-table">
    <tr>
      <th>
        <label for="user_address"><?php _e('Address', DJ_TEXTDOMAIN); ?></label>
      </th>
      <td>
        <input type="text" name="user_address" id="user_address"
          value="<?php echo esc_attr(get_the_author_meta('address', $user->ID)); ?>"
          class="regular-text" /><br />
        <span class="description"><?php _e('Please enter your address.', DJ_TEXTDOMAIN); ?></span>
      </td>
    </tr>
    </table>
<?php
}

function dj_saveCustomUserProfileData($user_id)
{
    if (!current_user_can('edit_user', $user_id))
        return (FALSE);
    // do validation, if needed
    if (isset($_POST['user_address']))
        update_usermeta($user_id, 'address', $_POST['user_address']);
}

add_action('show_user_profile', 'dj_addCustomUserProfileData');
add_action('edit_user_profile', 'dj_addCustomUserProfileData');
add_action('personal_options_update', 'dj_saveCustomUserProfileData');
add_action('edit_user_profile_update', 'dj_saveCustomUserProfileData');

You can add the above code any way you like, as either a plugin or added to your functions.php file. The code will display the appropriate edit fields for the user data you want to collect.

The code here is simple, but it gives a good example of how to implement your own system to collect custom user data and associate it with a user.

, ,

No Comments