Display a forthcoming event in WordPress with Pods

UPDATE: if you are going to try this tutorial out you might want to hold on a while.

There seems to be a bug in Pods preventing this solution from working (here’s the bug post on Github).

All is not lost, in the meantime you can add an additional parameter to the array that is described further down the page. This will work for the time being:

My first project using Pods includes a simple custom post type based events listing.

On the site I promote a single forthcoming event at the top of every page that will be replaced by a new one once that date has been passed.

This tutorial will run you through my solution.

Pods Framework

In case you haven’t come across it before Pods is a plugin that adds a highly flexible and powerful custom content creation and management layer to WordPress.

It not only allows you to easily create new content types but also extend any native WordPress content type (posts, media, taxonomies etc.) with additional custom meta fields.

Even if you don’t use it for anything else Pods has a great UI for creating and managing custom post types, as opposed to hard coding them in functions.php or as a plugin.

As you would expect Pods is easily installed via your WordPress dashboard in Plugins > Add new.

Pods documentation

For the purpose of this tutorial I’m going to assume basic knowledge of Pods framework, so I won’t be explaining how to use the admin back end. And I’m assuming you know about custom post types and custom meta too.

If you need to catch up check out the Pods Framework documentation and pay close attention to this guide on setting up a custom post type.

1: Set up your Event custom post type (CPT)

Create a new CPT in Pods called Events.

Add the following field to extend Events (I’m keeping this very simple for now):

  • Event date (event_date) -> Field type “Date”

Make sure you select the correct date format (e.g. 2013-10-03 – it is easier sorting dates that start year first) in Additional Field Options.

The default post title field will serve as the Event title.

The new Events custom post type should appear as an option on your dashboard menu beneath Comments.

Now add some new events and populate them with dummy data (make sure you have a range of dates for testing purposes, some before today’s and so on).

2: The problem

The problem at hand is fairly straightforward: how to display the next event only.

So, we need to filter for our custom post type (Events), arrange them in ascending event date order (as opposed to published date) and display the first one on the list.

If you have used WP_Query before then you would be right in thinking you can use this to display Pods data (it’s only custom meta that we have created after all).

Unfortunately in this case it isn’t suitable because WordPress doesn’t let you order dates captured in custom meta fields ( I worked through this problem here).

3: The solution

I place the following in header.php, which is where I intend to promote events. I guess you can put it more less where you want in your template files.

The Pods method is pretty concise.

Get today’s date, making sure that it is in the right format to match the Pods event date (more about the date() function):

Now set up parameters for filtering our CPT by event date, ensuring that it is published (‘limit’ is set to 4 here for testing purposes). The order is set to ascending by default:

By the way, my starting point for the above was found here: pods.io/docs/code/pods/find

The notation for ‘event_date.meta_value’ was found using the handy reference table at the bottom of that page.

Now we run our ‘find’ and open the loop to fetch each relevant event:

… and again, the reference for ‘fetch’ is here: pods.io/docs/code/pods/fetch

Then simply echo each field we’re interested in using ‘display’. The events are displayed in ascending order by default:

Of course if you only want one (or the next) event to be displayed go back and set ‘limit’ to 1 in your $params.

Now, all together:

4: Create a  single CPT template

You can quickly set up a custom events page template for our CPT. Copy single.php, save as single-event.php.

Now paste something like the following inside the Loop – up to you which side of  the_content() you paste it (you might choose to leave out the_content() altogether):

Obviously a simplified example but hopefully you can see how easily this can be extended to echo additional fields for any purpose (echo latitude and longitude for a custom Google map for instance).

I’ll post more detailed snippets when I’ve got a bit further forward with the site I’m working on.

Thanks to Josh Pollock ( Pods forum mod ) for helping out with this. There are many more tutorials on the Pods Framework site.

Keep a Bootstrap collapse menu item open using jquery.cookie.js

Imagine you have a list of collapsible menu items set up using Twitter Bootstrap and all are marked up to default to closed. Clicking each menu heading opens up a  list of links to other pages.

If you visit one of these pages and subsequently hit the back button you will return to a closed menu and have to reopen the list to browse for more options.

In certain circumstances this might break up the user flow somewhat. How do you keep the menu list open during the session?

This solution using the jquery cookie plugin does this very simply.

So, install jquery cookie on your server and add this snippet to your HTML:

Ultimate super basic introduction to LESS

LESS is really easy to get into but if you want a super fast point of entry before diving into the syntax why not stick to what you know and try it out using plain old CSS first?

1: Get a LESS compiler

First you’ll need a free LESS compiler. LESS.app  is good to go until 2015 for OSX ( after that it turns into a pumpkin ). If you’re into all that Windows business then WinLess does the same trick. If you’re a Linux head you can probably do all this in binary with a divining rod or whatever it is you do.

2: knock up a couple of files

You can set up a dummy web page if you like but let’s just get on with a quick bit of LESSing about shall we?

Create yourself four files, for example:

  • header.less
  • content.less
  • footer.less
  • style.less

The compiler just needs .less as an extension ( don’t worry you’re still going to be writing some CSS )

By the way, I do hope you’re saving all of these in the same folder.

3: Style according to taste

In each of your .less files just add some random classes and a few settings. It doesn’t matter what as long as it’s valid CSS ( if you’re doing this with a dummy HTML page why not style that? ).

For example in header.less:

in content.less:

and lastly in footer.less:

What about style.less? Read on…

4: Start your LESS compiler

Fire up your LESS compiler and add your folder to your watched LESS files ( “Add Folder” in WinLess, “+” in LESS.app ).

Ideally only the style.less file should have a check mark by it. Want to minify? Check that too, why not?

OK, are you ready to do some magic?

If you are a seasoned CSS warrior you’ll know that if these were .css files you could @import all of them in one further style sheet.

This is great and all you say but blah blah server calls, hosting bandwidth yada yada. I know. Just be quiet a minute and look what happens next.

Add the following to style.less ( it’s OK, I’ll wait ):

Save it.

Now take a peak in your folder and see what auntie LESS has baked you, that’s right, a fresh little style.css file ( did you see the puff of purple smoke too? Just me? ).

Lets have a look at what’s inside ( or this is what you’ll see if you went for the minified option ):

Woah! Yeah?

You feeling that?

Now think back to that web site you’ve got with a bajillion imported, uncompressed css files and multiple style links in the head.

Yep, the whole lot in one tidy CSS file and all minified if you so desire.

Now that’s before you’ve even looked at LESS variables, mixins and all that other heady stuff.

If you think you can handle it then this tutorial over at tutsplus would be my first port of call for a well explained and pretty comprehensive overview of LESS.

I think you’re ready 😉

Creating a clickable Google map of blog posts using WP_Query in WordPress

Last year I completed a WordPress site that presents a collection of photographs taken for the Worktown Mass Observation project.

The site uses a custom post type for each photograph. One problem I had to get my head around was how to display all of these photographs on a clickable Google map.

Luckily I found this excellent tutorial by Marty Spellerberg which served as my jumping off point.

Ease of use

Marty’s method uses custom meta fields to pull in the data.  As there are about 800 photographs in the collection I wanted to make it easy for site editors to add the map data.

My workaround involved using Ben Huson’s WP Geo plugin which adds a handy drag and drop Google map to your post editor. Lattitude and longitude coordinates on the Worktown site are pulled from that.

On the front end it wasn’t going to be practical to display 800 or so map positions at once so I needed to adapt Marty’s solution to incorporate the Google MarkerClusterer library to tidy up the map and to make it load quicker for visitors.

The MarkerClusterer visually groups map pointers into a single clickable area. Clicking these automatically zooms the map into an area with a smaller cluster of pointers.

The code

If you check out Marty Spellerberg’s post first, then have a look at the Google MarkerClusterer documentation the following might make a bit of sense 🙂

The following would go in your map page template:

And in your .js file:

And the rest of this junk needs to go in your header (note you also need to have MarkerClusterer.js on your site too):

Generating nested category lists in WordPress templates using get_terms

I wanted to create an index style page of site links organised by child category nested below each parent category.

The desired layout suggests a nested loop so first we need to list our parent categories:

Note the commented line where
'parent' => 0
ensures that only the top level category is selected.

If this is pasted into a page template then you should now see a list of your parent categories.

Now a look at the loop that will go inside this one:

Now put it all together:

 

Just a couple of caveats with this.

When assigning a category to a post you must check the sub category and the associated parent category or they won’t be displayed.

This snippet only works with one level of subcategory.

Mapping domains in WordPress Multi User with Nginx

It turns out that adding domain mapping support to WordPress MU using Nginx isn’t too hard (caveat ahoy: assuming that you have WordPress Multi User set up already and general familiarity with Nginx that is!).

This is how I got it to work with some additional tweaks to help save a little time when mapping more domains.

You will require:

  • One VPS set up with your chosen flavour of Linux, Nginx and PHP
  • A working WordPress MU installation
  • A domain that you want to map to a sub site in MU

Changing domain provider settings

Before you even touch your site you need to change the nameserver and IP settings to point to your new domain to a web server that hosts MU. Allow up to 24 hours for the DNS settings to propagate.

A good domain provider allows you to do all this via a dashboard. I use LCN which has a really easy to use admin back end (LCN are very good too btw).

Add the domain to your VPS’s DNS settings

Your VPS provider should have a domain management area where you can add a domain zone for new URLs.

My Linode VPS host adds default settings automatically which seems to work for me (e.g. www and mail prefixes are created in the A/AAA records).

Create a new site

Of course you can’t map a domain if you don’t have a site to point it to, so you need to create a new sub site from within MU.

I have my WordPress MU install set up to create sites as subdomains (e.g. newsite.mainsite.com). I don’t know if this is critical but I thought it might be worth mentioning.

Obviously you can map your domain to pre-existing sub sites too.

If you haven’t done so already you will need to install the WordPress MU Domain Mapping plugin which is the special sauce that helps to tie all of this together.

Map the domain using the domain mapping plugin

Once you have the new site up and running you need to map the new domain in your site admin.

You can do this from the Dashboard at the Network Admin end via Settings > Domains but I recommend going to the admin area for the new site and adding it via Tools > Domain Mapping.

This allows you to set the subdomain as primary so you can at least access the new site while you wait for the domain to propagate. You will need to go back and set the mapped domain as primary once  it has propagated and all the configurations have been made.

Nginx configuration

Nginx is a lightweight and quick web server. Apache is perhaps more common for most WordPress set ups. Nginx is sometimes used in conjunction with Apache to serve up static files. If that is your set up then this tutorial isn’t for you. See the_guv’s notes below about how to do this if you are using Nginx as a reverse proxy with Apache.

A typical Nginx set up will have several config files pulled in as includes by the main nginx.conf.

Nginx will request your vhost file via a symlink in a directory called sites-enabled. The main vhost file is kept in the sites-available directory.

Here’s the path for my set up: /usr/local/nginx where sub directories labelled conf, sites-enabled and so on are kept. If you don’t find Nginx there then it will most likely be in etc/nginx

My nginx.conf looks like this.

Note the includes (highlighted).

Skipping include mime.types we’ll concentrate on:

include /usr/local/nginx/sites-enabled/*

Note the wild card “*”. This tells Nginx to return any symlink in the directory that matches the requested domain.

sites-enabled contains all the symlinks that point to corresponding vhost files in sites-available

Create a new configuration file

Open your console and login as root user (note: a secure server set up will not allow you to log in directly as root. If yours does then you need to do something about it!).

Create a new folder within your Nginx directory and call it domains then create a new file inside this directory and call it multi_domains (all will become clear! You could of course give this directory and file names that are meaningful to you):

mkdir domainstouch domains/multi_domains

Open the new file for editing:

nano usr/local/nginx/domains/multi_domains

And add your new domain:

Important: make sure that there are no gaps before or after this line. The “.” at the start of the domain makes sure that both http://www.newsite.com and http://newsite.com are available.

Now save your newly edited file.

Delete the symlink in sites-enabled

You are going to edit your vhost file so delete the vhost file symlink in sites-enabled that corresponds to the main domain for your multisite (e.g. mainsite.com – using my earlier example):

rm sites-enabled/mainsite.com

Edit your vhost file in sites-available

Now open the original multisite vhost file  in the sites-available directory.

The vhost file mainsite.com looks like something like this:

Note the line:

In the example I linked to at the very start of this tutorial the recommendation is to simply add your domain as a new line below this one e.g.:

Now this is fine but presumably you will want to map other domains to your multisite later on. This means deleting the symlink, editing the vhost file, setting up a new symlink then restarting Nginx.

Not hard but now you have your domain in an external file you can remove a couple of steps. Instead edit your vhost like this:

Now save the edited vhost file and set up a new symlink:

ln -s /usr/local/nginx/sites-available/mainsite.com /usr/local/nginx/sites-enabled/mainsite.com

Now restart Nginx:
/etc/init.d/nginx stop/etc/init.d/nginx start

If your domain has already propagated you should be able to visit your sub site at newsite.com. If not wait it out and try again later.

If you made newsite.mainsite.com primary when you added the new domain in your WordPress dashboard then you will need to go back and make the new domain primary instead.

Adding additional domains to your configuration

Now you have a shortcut. In future all you have to do is add new domains to multi_domains e.g.:

And that’s it – no need to delete the symlink, edit the vhost and create a new symlink. Just restart Nginx:
/etc/init.d/nginx stop/etc/init.d/nginx start

Happy multisite hosting!