Posts Tagged: WordPress

Passing PHP variables to Javascript with wp_localize_script()

I’ve been using jQuery Backstretch in projects for a long time now. I love it. It’s so simple to use, and works perfectly. To use it on your site, you just:

1. Download the file—regular version or minified version, doesn’t matter which—and put it in your theme files’ /assets folder or /js folder, or wherever you put your scripts

2. Enqueue the Backstretch file in functions.php, like so:


function waterstreet_scripts() {
 wp_enqueue_script( 'backstretch', get_template_directory_uri() . '/js/jquery.backstretch.min.js', array( 'jquery' ), '', true );
}
add_action( 'wp_enqueue_scripts', 'waterstreet_scripts' );

Have a look at the Codex if those parameters don’t make sense to you.

3. Now that Backstretch is properly included in our theme, we can write our own scripts.js file and set a background image for stretchin’. That file might look something like this:

jQuery(function($) {
   $.backstretch("http://waterstreetgm.org/wp-content/themes/waterstreet/assets/background.jpg");
});
 

Ok, so all that’s cool. We’ve added Backstretch and called it with our own scripts file and told it about the background image we want to use. But have you noticed the problem? I’ve hardcoded the path to the file. I develop locally, so that line in my local file will look lit this:

 $.backstretch("http://localhost:8888/waterstreetgm/wp-content/themes/waterstreet/assets/background.jpg");

It’s happened to me about 10,000 times now that I will send a client a first draft of a site and they’ll say — Hey! I though we were going to put an image in the background? So then, I’d need to go in and remove the link to my localhost site and add the the live site url—again, by hardcoding it. It should be easier than this. Good news is that it doesn’t need to be this way!

wp_localize_script() to the rescue!

To make a long story short, I just want to be able to use something like site_url(); in my Javascript file so I don’t have to hardcode the url every time—but, of course, I can’t. What I can do, however, is set site_url as a parameter in PHP that I can use in my Javascript via wp_localize_script().

Now, that enqueue file will look something like this:

function waterstreet_scripts() {
	wp_enqueue_script( 'backstretch', get_template_directory_uri() . '/js/jquery.backstretch.min.js', array( 'jquery' ), '', true );
}

/* Make site url available to JS scripts */

$site_parameters = array(
	'site_url' => get_site_url(),
	'theme_directory' => get_template_directory_uri()
	);
wp_localize_script( 'scripts', 'SiteParameters', $site_parameters );

add_action( 'wp_enqueue_scripts', 'waterstreet_scripts' );
 

And hence, instead of hardcoding the path to the file in the Backstretch file, I can now simply use the parameter I just setup:

 $.backstretch(SiteParameters.theme_directory+"/assets/background.jpg"); 

wp_localize_script() is extremely handy for this. Any time you need to reference a PHP variable in a Javascript, you can just go back and add it to the $site_parameters array. You will hardcode no more!

On Contributing to WordPress

WordPress 3.5 was the first release that I’ve had any meaningful involvement in as a contributor. Before this, I’d spent time lurking around in IRC and browsing around tickets in Trac, but with no real purpose or intention. With 3.5, I really wanted to try and see what I could contribute.

The result? Well, if you look real close in the screen below, you’ll see my name in the bright lights near the bottom. Seeing my name on this page was extremely exciting.

But then the guilt

Truthfully, although my name does magically appear on the credits page, I must confess that I did very close to nothing to help out with the development and release of WordPress 3.5. Very early on, I participated in some discussions on a new look for the Welcome screen, I very briefly popped in to talk about the “Page on front” workflow, I suggested that icons might be nice on the welcome panel, and I thought that a border might be nice under h2 tags in the Twenty Twelve theme. Like I said, in the scope of this thing, I contributed almost nothing.

Why didn’t I do more?

There are two main answers here:  A) I just didn’t. Simple as that. And, B) the technical reasons.

Before I say anything about B), I want to make it absolutely clear that I did not do all I could to overcome the technical hurdles I faced when trying to contribute. I didn’t read as much as I should have, I didn’t reach out enough when I ran into issues or got confused, I didn’t develop a deep enough understanding of Trac, I didn’t step up and claim ownership of issues I could actually help fix. I want to make that crystal clear that I personally did not do enough to overcome the issues I ran into. Ok, so onto B: the technical issues.

Technical Overhead

Contributing to WordPress comes with a lot of overhead. Knowing how to setup a local install of the latest version, keeping that up to date, creating patches, applying patches, and I haven’t even mentioned Trac yet. A lot of the issues I had have already been pointed out in the notes from the “Engaging/Retaining New Community Devs” at this year’s community summit, but I want to
specifically go through a few of the issues/questions I had here:

1. I use Git. Is that ok? Should I just learn svn already? Update: Scribu posted a great, concise how-to. Sounds like you’ll never need svn again.

2. Making patches. Helen very kindly walked me through the process of making a patch. Very soon after, however, with no practice, I’d forgotten the basic steps

3. Keeping my repo in sync. So, I clone WordPress from Github per Mark Jaquith’s instructions and start working on a ticket. As soon as touch a single line of code, my repo is out of step. What do I do now? I’m positive I’m not doing this right, but I don’t the right way to do it.

4. #Trac. How people can find and sort tickets to issues is just beyond me. I find Trac to be almost a complete mystery. How do I find open tickets? How can I get a list of tickets that I might be able to work on?

5. #wordpress-dev. The folks who inhabit #wordpress-dev on IRC are extremely knowledgeable and helpful. They’re also very busy and focused. This definitely isn’t the place for questions like “how do I make a patch” when we’re right in the middle of heavy development. But outside of there, I don’t really know where else to ask that question.

6. Foraging for resources. I wish there was one good, comprehensive guide to contributing that brought you through all the steps. Everything from cloning the repo, making changes and not ‘breaking’ the repo, searching Trac for a ticket, creating/applying a patch, etc, etc. There are a lot of great resources out there, but they’re scattered around and sometimes not easy to find.

A few ideas

I can’t just create a list of problems without suggesting some ideas to help fix them. Two things stand out for me as being potentially huge for new-comers like me:

1. Mentoring. The word mentoring is loaded, I know. It comes with connotations of a long, arduous and time-consuming process but it doesn’t need to be. My suggestion? Create a place where a mentor can help walk you through three tickets. That’s it. In the process of working through these three tickets, the mentor can teach the new person how to set up a local repo, create/apply patches, and give them the basics of Trac. I think three tickets would be more than enough to get someone started.

So…..the real question here is — where do we get these tickets?

2. Identifying/tagging ‘easy’ tickets. Early in the release development cycle, you see lots of “easy” tickets floating around Trac. I’ve seen some that require changing a single line of css! Tickets like this would make a perfect starting point for someone new. Here’s how it might work:  A ticket would be tagged as “easy” or “beginner” and a mentor would assign it to their new student. Tagging a ticket with “beginner” would mean that an experienced person should leave the ticket alone until a new person has had a crack at it.

This process would really get to the root of my issues pretty fast. Having three easily solvable issues assigned to me, with the support of an experienced mentor would be huge.

A brief afterword

As I hope I’ve already made perfectly clear, many of the issues I encountered in the past few months could have been solved by simply trying harder and persisting more. That said, there really is a lot to learn, and the biggest part for me was finding something small and “easy” to learn with. As you would expect, as soon as a simple ticket shows up, someone has a patch created in a few minutes. I really think that leaving some of these easier issues in reserve for new-comers, and actually assigning them, would be extremely helpful. While I recognize that this would slow down development, I think it would really be worthwhile, at least early in the cycle, to have new-comers get their feet wet with actual tickets.

Which template — an essential theme development function

So you’re developing a theme for a new project that you’re working on. It has lots of queries, a few different content types, a custom taxonomy or two, etc… It can often be difficult to determine what template is generating the page you’re looking at on the screen. Is this page using page.php, page-{slug}.php, single.php, taxonomy-{taxonomy}-{slug}.php ? You get the idea.

I use this function on every single site I develop, but don’t often see it being used out there in the wild. Just pop this function into your functions.php file and it will output the current template file being used to the bottom of your page:

/**
 * Print out the current template file to the footer.
 * Remove before launch. 
 *
 */

function waterstreetgm_which_template() {
	if ( is_super_admin() ) {
		global $template;
		echo '<strong>Template file:</strong>';
		print_r( $template );
	}
}
add_action( 'wp_footer', 'waterstreetgm_which_template' );

Bones and Underscores— a WordPress theme head-to-head

Update: I’ve finally finished the follow-up post. Read the update when you’re all done here!

I have a big week coming up. I’m starting two brand new projects and I’m pitting two top WordPress starter themes against each other in a battle royale:

Underscores

First up, we have Underscores from the Theme Team at Automattic. It is very clean and stripped down, and truly satisfies the ‘starter theme’ criteria. It comes with the barest of necessities, but leaves nothing out at the same time. For you old-schoolers out there, you might notice that a lot of Underscores looks very similar to Toolbox, it’s predecessor. In short: Toolbox was a good starting point for developing themes and Underscores is a great one. Let’s have some pros and cons:

Pros:

  • Underscores is familiar. This is really only important to me, but it still matters. I used Toolbox on a lot of projects, and still use my fork of it—Victoria Park—for lots of things today. I used Underscores a few times in the past few months and it really feels like an updated version of what I already like.
  • Underscores uses the get_template_part pattern for abstracting template files. I really like this way of thinking about templates.
  • Aesthetics matter and the website for the project is great.

Cons:

  • Doesn’t use LESS or SASS. This is such an easy issue to fix (rename style.css > style.less and have LiveReload watch the folder) that it hardly warrants a bullet point, but it’s an important distinction from the direction Bones has chosen to take.
  • The name. I’ve never really liked the name ‘_s‘, which is an extremely unimportant detail until you go to start a project and have to find and replace all instances of ‘_s’ with ‘my_project_name’. Again, it’s absolutely not a huge deal, but it was a bit of a pain. The pain is now pretty-well completely alleviated by the project’s website—you can now just enter the name of the project and all the finding and replacing will be cleverly done for you.
  • Not responsive. I know, I know. You shouldn’t let a project’s boilerplate dictate your media query breakpoints, etc etc…and its something you can (should?) easily add yourself, but I still wish there were a few breakpoints baked in.
  • Eric Meyer’s style reset. This one would have been so insignificant a few years ago, but really drives me crazy now. If you’ve ever inspected a single element in Chrome dev tools or Firebug, you’ll know why. Meyer’s style reset, fills your inspector window thusly every time you click on an element:

    This clutter will show up for every single element you inspect. It’s not a huge deal, and you can remove the style reset and roll your own, but I still wish it wasn’t there to begin with.
  • Too spartan out of the box. I’ve always found Toolbox and Underscores to be way too spartan from the outset:
    While I understand that this is meant to be just a starting point, I still don’t find it warm and cosy when I start a new project.

Bones

Bones is a hot new theme from Eddie Machado. It’s much more opinionated than Underscores and comes with a few more things under the hood. Before we weigh out the benefits, I need to disclaim up front that I’ve not yet used Bones for a project, so all of the opinions below are just wild speculation. But let’s do it anyway:

Pros:

  • Responsive. Bones has a responsive grid baked right in
  • Looks good from the get-go Bones isn’t spartan from the start. It has a basic layout ready for you, and overall feels a little better than Underscores does. Sure, you’re still going to undo all of these starting points (the pink headings, etc) but it still feels better to me to start with something out of the box:
  • Normalize.css. If you’ve never used Normalize.css from Nicolas Gallagher and Jonathan Neal it’s worth a look. It does the job of resetting quite well, without cluttering up your inspector window.
  • LESS/SASS from the start. Here’s where the opinionated part comes in. I love that Bones insists that you should be using a CSS pre-processor (and you should) and makes the two most common options available to you
  • Verbose documentation. Some might find this level of documentation to be overkill, but I think it’s going to be helpful to leave it in for at least the first few projects. Machado crams a lot of WordPress know-how into each and every line.

Cons

This is the part where the comparision goes off the rails a bit. Given that this is really a setup post and not a followup, and that I’ve not actually used Bones yet, I can only list a few cons that come to mind when poking through the project’s files and folders

  • Modernizr. I don’t use modernizer. At the moment, it feels like this will add unneeded overhead for me. I have no idea. I might use Modernizr for every project henceforth, but for now it feels like it might get in the way
  • No get_template_part. Bones doesn’t use the get_template_part pattern, instead loading a lot of functionality into index.php. This doesn’t mean that I can’t do things the way I like, but is still not ideal for me.
  • Bones is opinionated. I’m not actually sure yet if this is a pro or a con. Opinionated code is great for beginners and people who have the same ingrained opinions. It will be interesting to see if my Machado and I do things the same way. It will be very interesting to see if I come around to his way of thinking if we don’t!

So there we have it. Underscores and Bones in a tête-à-tête. Results to follow!

Tighter and leaner WordPress templates with get_template_part()

Update: This article is a little dated now. As of a few months ago, I’ve stopped using Victoria Park and now use a fork of Underscores from Automattic. I’d recommend starting there. That said, everything else in the article still applies!

I use Victoria Park, a very slightly modified fork of Automattic’s Toolbox, for all of my projects. But every now and then when starting something new, I’ll go shopping around for a theme that’s custom-built for the task at hand. If I’m making a portfolio site, or a knowledge base, for example, I’ll often look to see if there’s a ready-made solution out there, rather than starting from scratch.

A lot of the themes I find out there seem like they’re ready to just drop into place, but so far, at least for me, they’ve always been fool’s gold.

Using something other than your tried-and-tested base theme is a bit like cooking in someone else’s kitchen. Sure, things will get cooked, and the meal will most likely turn out just fine, but it won’t be the same. You won’t find the same frying pans you’re used to, the stove will be different, the cutting board too small, the knives not sharp, etc. Cooking in someone else’s kitchen just won’t feel natural to you, and neither will using someone else’s WordPress theme.

Pots, pans and knifes, all your own

I’ve directed lots of people to Toolbox and its successor _s. I’m still using Toolbox at the moment, but plan to take _s for a spin on my next project. The two are very similar and _s looks on the surface to add nice, minimal enhancements to an already good theme.

Even if you don’t fully adopt these themes as your own starting point, I will recommend (encourage? implore?) that you follow Automattic’s lead in these few important ways:

1. No more loop.php

For too long, loop.php was a melting-pot for a huge pile of logic and conditionals that made modifying it a chore. Ten lines of code that say, “if the user is logged in, and not in the admin area, and not looking at a blog post, and not didn’t have a sandwich for lunch, then show them this content”, make things hard to read and modify. There’s a better way to naturally abstract that logic away. WordPress already knows about and expects files like single.php, page.php, front-page.php, etc, so references to them don’t need to be coded into a loop.php file. There’s no need for conditionals like is_single(), or is_front(), for example, because these already have their own template files. Any code you put in front-page.php or single.php will be picked up automatically, no need for conditionals.

2. Start with a good index.php file.

index.php is usually your first port of call. This is where you want your loop. Like so:

<?php /* Start the Loop */ ?>
<?php while ( have_posts() ) : the_post(); ?>

	<?php
		get_template_part( 'content', get_post_format() );
	?>

<?php endwhile; ?>

Looks simple enough, but there’s a small bit of magic in there. For a good description of this magic, please see item 3, below.

3. get_template_part()—the heart of your theme.

Though not a huge, or terribly powerful function, get_template_part() has become a core part of all of my themes. get_template_part() is more than a function, it’s a way of thinking about structuring your themes. Instead of including the markup for your blog posts, asides, or galleries directly inside index.php (or formerly loop.php), leading to huge, unreadable files, you include their contents in a separate file: content-{post-type}.php. An example will clear things up.

Imagine trying to have different markup in a standard blog post and an aside, where you remove the title, tags, and category:

To achieve this, an old loop file might look like this (I’ll write this in English instead of PHP, for understandability):

while ( have_posts() ) : the_post();

if post-type = 'aside'
	<article>
		.....content...
	</article>
	<footer> The date, the tags, etc </footer>

if post-type = 'blog post'
	<article>
		<h2>Post title</h2>
		.....content...
	</article>
	<footer> The date, the tags, etc </footer>

if post-type = 'gallery'
	<article>
		<h2>Post title</h2>
		.....content.....
		.....the gallery.....
	</article>
	<footer> The date, the tags, etc </footer>

While your shiny, new index file will be much simplified. Containing just this tiny loop:

while ( have_posts() ) : the_post();

get_template_part( 'content', get_post_format() );

Using this example, WordPress will still loop through all of your posts, but it will examine each one to see what post format it has (aside, image, article, gallery, link, etc). Each time, it will go looking for a corresponding content file:

content.php
content-aside.php
content-article.php
content-gallery.php
content-image.php

Now, all of your template code is neatly abstracted into individual files. You know, for example, that you don’t want to have titles on aside posts, so to get rid of them, just delete the post title from content-aside.php.

The obvious next question you might have is, what if I don’t have a template file for each post type I have? The beauty of this method, is that you don’t need one. If you want asides to look just like blog posts, then don’t have a content-aside.php file. WordPress will simply look for it, not find it, and serve the plain content.php instead. The only file you need is content.php—you’ll only need the others if/when you want that post type to look different.

This all probably sounds a bit like we’re splitting hairs. What’s the difference between having one really long file and having a bunch of really small files? It might not make much difference to you at all, but it makes a big difference to me. As I keep adding more and more post types, including more and more custom post types (outside the standard ones: aside, gallery, links, etc), using this get_template_part() pattern becomes really useful. Instead of scrolling through potentially hundreds of lines of template code, you now just need determine the post type and find its corresponding content-{post-type}.php file.

To sum up

Have a look at _s to see how this is done, or have a look at Victoria Park to see how I do it. My rule of thumb is, whenever I’m doing something like adding/removing a post tile, or post tags/categories, or the date, or otherwise changing a post’s markup in any way, I make sure I’m doing it in a content-{post-format}.php file instead of in index.php or loop.php. Note, of course, that this works just as well for custom post types as for the different post formats. Just put your custom post type content in: content-{my-custom-post-type}.php

This is an excellent habit to get into and will lead to much more readable, maintainable and sharable themes.