2014/03/07 // 5 months ago

New Add-On: ERT FreeGeoIP

​As a result of needing to easily pull user location information into some javascript on a recent client project, I’ve developed a quick plugin that uses freegeoip.net’s ip lookup service api to fetch the country, state/region and city for a user when they view a template with the ert_freegeoip tag on it. Available for download on devot-ee, or here on my site.

---------->---------->---------->---------->---------->---------->---------->---------->---------->----------

2014/03/03 // about 6 months ago

​E.E. 2.8 - Relative Dates and OMFG Template Layouts are Awesome.

Ellislab has been rolling out feature packed updates to ExpressionEngine lately, and the most recent update to 2.8 is no exception. There were two features in particular that caught my eye, relative date formatting and template layouts.

Relative Date Formatting

Previously I’d used plugins such as Time Ago to accomplish the task of outputting a relative timestamp (ie, ‘2 minutes ago’ or ‘3 weeks ago’ etc), but with 2.8 we now have access to a new method for formatting a time relatively.

Usage is pretty simple. For outputting the date of an entry, we might do something like;

{entry_date format="%F %d%S, %Y"}

and that tag would get us March 3rd, 2014 (the absolute date of the entry) for this entry wheras;

{entry_date:relative} ago

would get us “1 day ago” or “1 week ago”, depending on when you’re seeing this entry relative to the date it was posted.

Super simple, and it makes more user friendly meta data that much easier to place into our templates. I’ve already added this feature into my own blogroll, though I’m still including the absolute date for people who don’t like to do math.

So relative date formatting is definitely useful, and there are a number of options for formatting and for limiting the time scale to be relative about. You can read more about this new method over on the ellislab blog about relative date formatting. But if relative date formatting is kinda useful, then Template Layouts are kinda an essential new feature for sites built into the future on ExpressionEngine.

Template Layouts

Gotta admit, template layouts have me excited, they are a rethinking on the standard embed/content model that we’ve all grown used to. The tldr; Template layouts enable us to define our major template components in one file, and apply content based on a sub view template. All while passing variables back to our layouts with a simple and efficient mechanism.

Embeds are great (and we can talk about stash and embeds vs. snippets etc another day). They give us the ability to keep the core parts of our layout and structure consistent without a crazy amount of maintenance, and they enable us to short circuit the parsing order in some situations to shoehorn in data where it’s otherwise not possible. For that reason I’d wager a guess that many of us are utilizing them throughout our work to handle the bulk of view construction. When I was making a new template, I would usually structure it like so…

{embed=“structure/html_open”}
{embed=“structure/site_header”}

// Content and Structure for this template

{embed=“structure/site_footer”}
{embed=“structure/html_close”}

Looks somewhat familiar I’m sure. I break up my functional code and the more design/front-end stuff into separate files (the `<html>` and `<head>` tags and content go in html_open template for instance, and the navigation goes into site_header). Those and the footer go on every template file and I’d sandwich the content between them.

That’s well and good, it helps me abstract out the common site elements from the specific needs of a particular template. But, it forces us to break up our code into discrete sub templates, which in addition to being harder to maintain also individually can require a slew of MySQL queries to resolve. There’s an extra query for each one of these embeds, and potentially more if any of them load dynamic information. I’ve had sites require each of those embeds to contain a call to the channel:entries tables because each needed information from the content page channels for instance.

2.8 brings us Template Layouts, and they can solve this embed chaos by letting us define in a single file, the master template for our content and call our template view content into it instead of the other way around. This means that you can have all the pieces needed to create the site structural elements in a single template. The possibilities for performance improvements here are considerable, as is the benefit of being able to see your entire wrapping templates in whole, which should make finding that errant unclosing tag that much easier. To recreate the effect of the example above using template layouts you’d do something like the following.

{layout="layouts/master_layout"}

// Content and Structure for this template

We’ve gone from four embeds to a single layout reference (layouts/master_layout). That layout template would look something like below. I’ve marked up where those earlier embeds have been combined to form the whole layout.

{!-- used to be inside of html_open --}
<!DOCTYPE html>
<head>
<title>evanrthompson.com</title>
</head>
<body>
{!-- /html_open --}
{!-- used to be inside of site_header --}
<div role=“navigation”>
...
</div>
<div>
{!-- /side_header --}
{layout:contents}
{!-- used to be inside of site_footer --}
</div>
<footer>
</footer>
{!-- /side_footer --}
{!-- used to be inside of html_close --}
</body>
</html>
{!-- /html_close --}

It’s the {layout:contents} tag that does our heavy lifting. Anything placed below the {layout=""} call in our content template will be inserted wherever this tag is placed in your layout file. What gets even crazier is that you can nest these layouts. Keep a global header and footer, nest your 2-column-left or 3-column-whatever layout within that, and then nest your content for each view you have inside those. Way cool.

I’m giving very limited examples of chaos here so just extend the logic out and imagine how this functionality could have simplified some of the real snarls you’ve built.

The big reason many of us use embeds within code (as opposed to snippets or global vars) is that they give us the ability to pass dynamic information onto those bits of our layout that would otherwise be out of reach. A super common example of this is passing an entry’s title to the <title> element. Here’s how I’ve been accomplishing that for many of my pages:

{exp:channel:entries
channel=“pages”
disable=“categories|category_fields|member_data|pagination|trackbacks”
dynamic=“on”
require_entry=“yes”
}
{embed=“structure/html_open” title=”{title}”}
{embed=“structure/site_header”}
{/exp:channel:entries}

// Content and Structure for this template

{embed=“structure/site_footer”}
{embed=“structure/html_close”}

Ok, that’s a pain in the ass. But here’s where template layouts really shine, when you’re trying to push dynamic content to your wrapper template you can accomplish that with the simple layout:set tag pair. Just supply a ‘name’ parameter, and wrap the content to be passed inside them like so:

{layout:set name="title"}{title}{/layout:set}

Then reference it in your layout with

{layout:name}

e.g. to place the ‘title’ from our content view into the template layout:

<head>
<title>{layout:title}</title>
</head>

With that, we can pretty much do away with using embeds to form our templates and thanks to the pair nature of {layout:set}, we can much more easily pass along blocks of text, or complex text that previously might’ve been difficult to shoehorn into the embed’s var=“yaddayadda” structure. Excitement!

There’s even more to the 2.8 update, these just happened to be what has my motor cranking at the moment. I can’t wait to see how these new methods can be bent to our collective wills.

Aloha.

Archives
Mar, 2014