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.

Imagining a WordPress museum site

Easy access

One of the most likeable things about WordPress is its approachability. With only a little web knowledge and the ability to follow simple instructions it is a doddle to get a WordPress site up and running (aka the “famous 5 minute install“).

Once at that stage and with only a few clicks you can change the theme, add new plugins and start publishing your memoirs or selling widgets. There are already a lot of very impressive projects out there developing powerful open source plugins that help to customise WordPress for specialised purposes.

Minimal museum use

So it interests me that there is a dearth of museum or gallery sites that use it (other than as a blogging platform). My guess as to why that may be is that we have yet to see many useful plugins that give WordPress the necessary tools to display and search collections online.

I have found one or two isolated examples of museum sites built on WordPress but these use proprietary plugins or technology to add that functionality (or the search isn’t integrated at all). As good as these sites are I don’t see any wider take up.

I think the reason for this is that closed products don’t necessarily foster a wider user and developer base.

Tapping into the community

In the WordPress ecosystem popular plugins and themes attract large user bases and therefore have the momentum and enthusiasm required to maintain a development cycle. Someone builds just the right kind of product, it catches peoples imagination, they run with it and a community builds up around it.

Not all WordPress products are free but there are some good examples of powerful plugins that are. For instance, with a little in-depth knowledge anyone can play with BuddyPress (a Facebook style social network plugin) and see how it works and of course modify it to their needs. I recently came across Placester which is a real estate (estate agent) plugin. I can’t comment on it’s quality, but it certainly looks very slick with some very attractive and well-designed free templates. Essentially I could install it now if I wanted to and play around with it.

BuddyPress and Placester came under my radar because it seems to me these products have functionality that is not a million miles away from a typical online collections search. If you look at BuddyPress and replace the concept of a member profile page and re-imagine it as a collections object page there is an awful lot there that is transferrable conceptually (I doubt it would be viable to simply convert it though). The same goes if you swap property for object in Placester.

So, knowing what I know so far about WordPress this is what how I imagine my fantasy collections based plugin might work.

MuseumPress

For the want of a better title let’s call it MuseumPress. BTW the use of “Museum” is a peg to hang this on; ideally it should work just as well for art galleries, archives or record discographies if that is your need.

It must me free!

The core philosophy should be to develop the product and its extensions for free.

Well, the core framework at least and with a GPL license. Also a number of starter themes to get people up and running (including dummy content perhaps). That is not to say that nobody should develop paid plugins but monetisation can only happen if there is a large enough user base to make it viable.

Many museums use public money to develop web presences. This is OK but would it not be better if they were paying developers to create products with community input that can then be released for free?

In my opinion this would be a much more sustainable model and a better use of public funding. I have a bee in my bonnet about this – opportunities for sharing knowledge are lost by constantly insisting on building closed systems.

Multiuser activation

I envisage a plugin that needs WordPress Multiuser activation. OK this requires some messing about with wp-config.php (and server configuration), so there is a little newbie hummock to negotiate right there. This should be the most challenging (i.e. non UI enabled) aspect of the set up.

Collections data import

Once you are past this point you need to get your collections into the database. My guess is that this should be done via a CSV file. If I push my fantasy a little harder I imagine a scenario where you might want to configure your set up to add or remove fields to display information at the front end – perhaps based on the type of objects you want to display (and indeed cater for multiple object types). Customisation is key but there will be a core set of fields that will always be required (e.g. what is it, description and so on)

In this case perhaps you would set your object types first then WordPress will show you what table headings you need and then import your data. There needs to be some way to handle linking data too (categories, tags and so on).

Events and exhibitions

A robust “what’s on” element would be useful. If you could import a year’s worth of events via CSV that would save a lot of faffing around. Obviously you would be able to publish individual events by hand any way). At the front end it should be easy to intelligently display the information – old events expire, old exhibitions available as an archive and so on. Making the events element a part of the framework should allow easy linking of exhibitions and events with object data and vice a versa.

Media upload

Should not strip EXIF data from images. Object images need an explicit link to their object record to allow intelligent reuse (e.g. if you use an image in a blog post then a link to this might appear on the object page )

Plugability

The core framework would need to be able to allow plugins so it can be easily extended and additional features added only if required.

Plugins could:

  • Display live data from collections management databases (as an alternative to importing static bulk data)
  • Allow installation of Thesauri
  • Add maps
  • Add slideshows

Social element

Maybe not built in but if the plugin were compatible with BuddyPress then a social layer could easily be bolted on.

Metadata

It should be possible to incorporate any metadata schema that you require and have them appear in the <head> and so on. Microformats should be built in as standard.

API

To make it straightforward for app developers to work with your data

Widgetisation

It should be trivial to use widgets to display collections data anywhere on the site or sub sites. In some respects this is the biggest attraction for me. If you could reuse collections content anywhere on your site using action hooks and a bit of logic then this would be very powerful indeed. To be able to widgetise collections data so less savvy site admins can plonk it where they want would be even better.

Multi language support

WordPress standards for multi-language support should be built in for a global reach.

I could go on but that would be endorsing feature creep!

The point is that a pared down, well designed generic plugin that addresses core needs is an attractive idea to me and it surprises me that one doesn’t exist already.

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 &gt; Domains but I recommend going to the admin area for the new site and adding it via Tools &gt; 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!