Close and Go BackBack to Viget

A Whole New Wooooorld: Structure + ExpressionEngine

Doug Avery
Doug Avery , ON THE TOPIC OF Development
2/3
2010
35

Even with the EE 2.0 release in December, I think the best ExpressionEngine event in 2009 was the rise of Travis Schmeisser's Structure. While 2.0 lays the groundwork for a bright future, in the short run it's more of a step backwards because so few of EE's amazing community-built addons have been ported so far - even with new functionality, a 2.0 upgrade takes away far more than it gives at the moment.

In contrast, the Structure module immediately makes major improvements to your site's UI, construction, and template codebase, and it also plays nice with other addons, creating a faster, smarter EE experience. No software I installed last year saved me as much time and effort as Structure did, and Travis deserves all the credit for that (and he got quite a bit, including Devot:ee's Module Of The Year award)

So what is Structure, and what about it makes EE so much better?

Structure is a module that overrides EE's URL/template setup and creates its own hierarchy of pages and "Listing" pages, along with a new interface that's meant to handle most user needs. Why is this such a big deal?

  1. A page is the basic unit of most websites, but in EE, there's no great way to handle them. EE developers spend a lot of time trying to simulate a page structure using templates, categories, and weblogs - which tends to make bulky, finicky sites that can be hard to extend and update. Structure brings the page concept into EE beautifully, and adds breadcrumbs, navs, and a host of other traditionally hard-to-develop features.
  2. Entries are now linked to templates, and not vice versa. This might not seem like such a big deal unless you've made a big EE site without it - large EE sites rely on a large number of repetitive templates, which are especially difficult to handle. With Structure, you can run a big site with hundreds of top-level pages off a handful of templates - a huge time-saver.

We had a few false starts with Structure - mostly because we were trying to bring it into existing EE sites (recommendation: don't) or use it to do the wrong things, but we eventually got the hang of it. A few pointers:

Make Great Structure Sites


Use Gypsy.
Gypsy allows for standardized field names/types across all your weblogs, which is the key to making a great "default" template that can handle most pages. It also makes custom meta tags and title tags a snap - since Structure always knows which page you're on, and Gypsy always knows what your field name is, you always have easy access to custom fields like these.

An example of site-wide fields made with Gypsy

Useful site-wide fields like this should be a snap to implement and use - custom per-page meta information used to be a huge pain, but it's no problem for a Structure/Gypsy setup.


Make it browseable first.
Using a default template and some subnavs, you can make a working site super-fast with Structure - this allows clients to make sure all the pages are where they imagined and understand what's still missing. Again, if you're using Gypsy and standardized field names like "general_body" and "general_intro", this should be a snap.

A view of the Structure interface

Using a template or two, it should be possible to create the whole sitemap in the Structure Interface, and make an early working site for clients or project managers.


Keep specific templates for 404, Search Results, and No Search Results.
This is especially true for the search templates, because they have an unpredictable query string in the URL that Structure doesn't work well with.

Embed, embed, embed.
Most of our page templates are actually just a few lines - embed header, embed content with parameters, embed footer. Embedding a "content" chunk like this allows you to easily pass parameters into weblog tags using advanced conditionals, so you can effectively use one or two weblog tags to run the entire site if you're clever about it. This setup might require more up-front planning, but it saves you a ton of debugging and tweaking time later, and keeps the code much dryer.

An example of our template structure

We have a number of "general" and "unique" templates, most of which point to one of three "content" embeds with a few special passed parameters.


Use Assets. The Assets bucket is Structure's orphanage for non-page entries - perfect for one-off chunks of content like a footer disclaimer.

Watch Out For...

BE YE WARNED: Structure overhauls URL and templates handling, which means that a lot of old tricks might not work without some extra work. Here are the most common issues we run into:
  • Like EE's url_title, Structure's page_slug determines the address a page appears at. Url_title and page_slug usually match, so it's easy to mix them up in your templates - but if they get out of sync, templates that use both can break. At Viget, we completely hide the URL Title field , using only {page_slug} and {page_uri} in templates.

  • To find the correct "parent" entry, {exp:comment} tags try to match the current URL to an entry url_title. But like I said, actual URL and url_title can get out of sync, so you might want to manually set an entry_id or url_title in your tag:

{exp:comment url_title="{url_title}" dynamic="off"}
  • Structure is a lot stricter about URLs than EE templates tend to be. While this is great for 404 handling, it makes some old-school EE ideas kind of tricky. For example, "blogentry/comments" will throw an error, because Structure looks for an explicit "comments" page. We like to redirect form submitters to "(currentURL)/thanks" for tracking purposes, but Structure doesn't understand that we want the last segment to be effectively ignored.

    We use NSM Safe Segments to work around this, which makes EE ignore segments of your choosing.

  • Related to the last point, Structure kills EE's default handling of blog categories. There are a couple of workarounds for this, but our favorite is a two-step process:

    1. Create your categories and note their url_titles
    2. Create new pages under your blog page for each category, with page_slugs that match the url_titles
    3. Link these pages to a template that uses Low Seg2Cat to convert the segment into a category ID, then drop that ID into a weblog tag.

  • The incredibly useful Cloner duplicates entries, but the process can mess with a Structure page's hierarchy and listing settings. Watch out!

Have a Structure setup or trick you'd like to share? Let me know in the comments!

Ben Sturrock said on 02/03 at 11:12 PM

Great article and enough to convince me to give it a go on one of my next projects. I’m great with CodeIgniter so I thought EE 2.0 with its new interface and some custom CI code would be the answer to all our problems, but it still lacks, well, structure.
Looking forward to the EE2.0-compatible release. In the meantime, the cost saving of buying EE1.6 than EE2.0 can fund the Structure licenses.

Travis Schmeisser said on 02/04 at 10:34 AM

Thanks for the great writeup! I’ve got to give credit to my partner in crime Jack McDade also. We’re blushing!

We’re working on the EE2 port and will have one more version before its release including a UI redesign to make it even easier to do common tasks and a few surprises.

Thanks again!

Leevi Graham said on 02/04 at 10:58 AM

Thanks for the shout-out and mentioning NSM Safe Segments!

I guess if Travis is porting Structure to EE 2.0 I better get moving on Safe Segments as well.

I see you used Gypsy for a meta title and description. You should also checkout another one of my addons: LG Better Meta. Drop me an email and I’ll send you over a copy. It integrates with Structure as well.

Dion said on 02/04 at 11:20 AM

How do you guys get the template group separators in place?

Philip Zaengle said on 02/04 at 11:32 AM

Great introduction to the Structure Module for folks who aren’t using it yet. There are a couple add-ons that make structure even better, like the Direct to Structure extension (http://devot-ee.com/add-ons/extensions/wi-direct-to-structure/) which redirects you back the the structure listing page after editing a entry.

There’s also an add-on that will redirect a user on login to the structure listing page, but I’m having trouble finding the URL.

Doug Avery said on 02/04 at 12:26 PM

@Ben yeah, I think Structure and Freeform are the two biggies we’re waiting on 2.0 compatibility for. Excited up the eventual upgrade, though!

@Travis thanks for the update! Structure will be a huge boost to 2.0, hopefully it’ll help start the big 2.0 addon rollout that needs to happen in the next year.

@Leevi we’ve used Better Meta a few times, although we usually don’t have time to take full advantage of it. It looks like you’ve made some great improvements since we last looked!

@Dion I have to confess, I just made a template group called “_________”. To the annoyance of others, I tend to add little stuff like this into projects just to improve readability.

@Philip Direct To Structure is GREAT. I haven’t used Structure Entries yet, but it also looks like a great addition.

Chad Crowell said on 02/04 at 12:28 PM

Philip you beat me to it - was just going to recommend our Direct to Structure extension.

Fantastic write up here.  Not every site is well served with Structure but once you use it on a site where it makes sense, it really changes the possibilities.

We actually did implement it on an existing site for a client using Pages.  They had about 60 “static” pages that were in and amongst the other 200 or os weblog entries in the Edit tab; it was very hard for the site admin to find what they needed and envision the site structure from the back end.  Structure made it worlds easier to see the site structure and get right to the page they wanted to edit.

Dion said on 02/04 at 02:52 PM

Thanks Doug,
It will improve readability indeed :-).

Brian said on 02/04 at 03:31 PM

Nice article on Structure. I still have yet to use structure. This just might convince me to give it a go. Thanks.

Mike said on 02/04 at 03:58 PM

Thanks for the great write-up! Sometimes I think the authors of EE’s third-party plugins don’t do a good enough job of telling what their plugins really do, and how they can help you. As a EE noob, I’m constantly hearing about plugins that are great, and I still don’t understand what the hell they do! :) We definitely need more articles like this.

Philip Zaengle said on 02/04 at 04:08 PM

@Mike,
Really? you don’t read through every line of code before installing a add-on? I do. :) But I totally agree, a lot of add-on devs get a little bit of #lazyweb going on toward the end of the development process. Often documentation is the last thing we want to do, but we need to get better at!

Jack McDade said on 02/04 at 06:05 PM

Thanks for the great writeup! Travis and I have put a lot of time and love into this module. The entire codebase has almost been rewritten since 1.0 at this point, increasing stability and adding many new features and parameters. It’s great to get recognized for that effort with the community response (e.g. Module of the Year anyone?). I use it myself in EVERY EE project I build, which tends to inspire some more features as well.

Travis is a fantastic partner-in-crime, keeping up with every little detail needed and functionality tweak, as well as all the support requests and “hey does it do this?” questions that come in. I hope to be the other half of this module for a long time to come. Just wait for 2.1 guys, we hope it knocks your socks off!

Mark Bowen said on 02/04 at 07:06 PM

Just a quick question if I may regarding the categories part?

You said to create pages underneath the main page for each category and then use the extension to convert these into category ids?

I’m taking it that you have to actually create some categories for that weblog as well though and perhaps name them the same as the url segment?

Best wishes,

Mark

Adam Khan said on 02/04 at 07:20 PM

I remain unconvinced even by this well-written article on this very pretty site. Structure still seems to me like something you’d use if you don’t like ExpressionEngine, or even CMS’s in general.

So to me, it’s Structure that represents the step backwards, to thinking in terms of pages again rather than content.

[Hesitates to press Submit]

Travis Schmeisser said on 02/04 at 07:26 PM

Yo Adam -

I agree content is more important and not just focusing on pages. We don’t really aim to change that part of EE and since it’s built on top of it, we make use of the amazing custom field system. Along with great extensions that add onto that, it helps you focus on the content and making it simple to input.

One of the main points (besides building quicker) of Structure is to remember your clients DO think in terms of pages and ultimately that’s who needs the simple interface and we’re all building in a CMS for.

Doug Avery said on 02/04 at 07:32 PM

@Mark - yeah, you need to actually have real categories that match the URL. Thanks for pointing this out - I’ll update to reflect this.

@Adam - Thanks for adding your thoughts. I think the trouble with breaking away from the page mentality is that pages are still a valid mental model on the web - the concept of a page represents unique content at a unique location that can be found, re-found, bookmarked, and linked, and like it or not, it’s still how we find and think about information online.

Good CMSes work to solve and simplify common user needs, and in the web business, developers and clients still need to create “pages” on their site. ExpressionEngine’s handling of pure content is fantastic, but it requires almost every EE developer to jump through hoops in order to get their site working in step with the “page” concept. Structure is a fantastic compromise - it keeps EE’s content flexibility and endless buckets of unique entries, but gives them a framework that allows you to quickly and simply build what you want - which is, 90% of the time, a site that has “pages.”

Mark Bowen said on 02/04 at 08:13 PM

@Doug - Thanks for the clear up on that. Thought it might be that but just wanted to check before throwing myself in on something ;-)

Hambo said on 02/04 at 11:20 PM

It’s interesting how you have created the general and unique template groups. I’ve always created new template groups to reflect the site structure but of course Structure can abstract all this away.

I’m assuming that general templates are like static pages with simple content while unique are things like a contact us page or faq?

I’d be interested in seeing more detail about the _structure, _content and _function folders and what they do for you. I’m always open to learning from others methods!

Doug Avery said on 02/04 at 11:55 PM

That’s just another personal convention - since Structure gets rid of the old “templates must follow site structure” idea, you can use a few templates for a large number of pages. These are usually in general, and they’re usually something like “default”, “listing” (for blog-like listing page) and a few others that can handle multiple pages on a site. I use “unique” for templates that only get one or two uses - stuff like like the Contact page, for example.

The underscore naming convention pushes templates down in Structure’s template selector, so you don’t have to scroll through “_content” and “_structure” templates to get to the page templates you want. Not a big deal, just a little timesaver.

The other three or four folders are just broken up because I use so many embeds and like putting things into folders. I break stuff up like so:

_structure is for essential page pieces like footer and header, _function is for more complicated, repeating bits like the search form, and _content is for primary weblog tags and their contents (like a “basic” content template with one body field, a “default” one with several standard fields, and a “listing” one that shows a group weblog entries). Why put this into an embed? A few reasons:

a) A lot of pages have similar content structure - they have headers, content, a photo, and some related entries. Rather than making totally new templates to reflect each of these differences, we can use one block of code to do a lot of this work and just control the differences with some conditionals and weblog tag params.

b) Weblog tags are finicky - you can’t put advanced conditionals into the tag itself, which you might want to do if, say, your News and Events pages use the same layout, but sort in different directions. However, you can go crazy with conditionals inside the {embed} tag, so weblog tags become very easy to manipulate when embedded.

c) Using a chain of embeds like this removes the need for {if segment...} conditionals. {if segment} sort of stinks with Structure anyway - you want your pages to work anywhere inside the hierarchy, not just two levels down from About! Instead of using {if segment} to control template features, I pass in custom variables like “sidebar=true” to the embedded tag. This makes templates that are URL-agnostic and can be moved around and stretched to much greater effect.

Example: A default template might look like this:

{embed="_structure/header"}
{embed="_content/default"}
{embed="_structure/footer"}

But a unique/staff template might look like this:

{embed="_structure/header" headerclass="theTeam"}
{embed="_content/default" biopicture="true" sidebar="false"}
{embed="_function/contact_short" contactwho="staff"}
{embed="_structure/footer"}

Some templates are obviously longer, but the goal is the same - a page’s chosen template controls how its embedded children act through a pretty simple system of embedded vars.

We’re still pretty new to this method, so it’s definitely undergoing changes, but it’s been pretty fun so far. It’s an interesting way to run an EE site with way less code, which usually means faster production and more flexibility.

Hambo said on 02/05 at 12:41 AM

Great writeup there Doug and similar to what I do with _section being specific to… you guessed it, sections of the site!

It’s a great buzz when you settle on a convention and create a default db and jumpstart your project from there. I think I just found a nicer what of doing things. I’ll start experimenting :)

David Horn said on 02/05 at 05:24 AM

Great post - thank you.  I’ve tooled around with EE a little bit in the past but have been put off by it’s way of associating templates with content ... Structure & Gypsy look like just the job for me.  Thanks again.

Brendan said on 02/05 at 09:28 AM

Two things that bothers me about structure is that essentially you’re giving clients control to choose incorrect templates from the template drop-down - and that you have every template listed in that drop-down, that is a recipe for disaster in my opinion. Perhaps I’m missing something here - I’ve only used structure for a short while and abandoned it on a recent project because I was worried about it - and didn’t have time investigate it thoroughly.

The other things is that sometimes I don’t want clients to be able to add pages below the home page or some other page like contact or stop at a certain level of sub-sections. I don’t like the idea of giving clients complete control over every inch of the structure of the site, as they end up making silly mistakes.

Perhaps I’m missing something here, hopefully I am. Because I do feel the basic idea of structure is perfect and have had many clients and people I’ve worked with asking for the site to be laid out on one page. I have created member only sitemaps with edit buttons which would link back into the ee entry to mimic this functionality.

Doug Avery said on 02/05 at 10:17 AM

@Brendan, Structure actually has a lot of controls in place for this - by group, you can turn off the ability to add pages or select templates, which I think addresses most of your concerns. I agree with you about clients creating top-level pages, but we’ve also had cases where clients *needed* to create landing pages like this for marketing purposes, and without Structure, we had a difficult time of it.

Adam Khan said on 02/05 at 07:28 PM

Travis and Doug, I appreciate your replies. Doug, I agree that the visitor to a site thinks in terms of pages, but in my mental model of an EE site, which I try to inculcate into clients, pages are the final layer in the process, the result of previous inner layers, ie, fields->weblogs->templates->pages, and that there are long-term benefits in keeping these layers cleanly separated.

There are always parts of a site where weblogs seem to be forcing something round into a square box, such as the About areas, which are pretty static. But for me, once the client has mastered using the standard publish/edit screen, I’m of a mind that it’s easier for them to continue using that screen, which they’ve now mastered, even for areas of the site for which it’s not ideal, than to learn another parallel method of managing content.

Maybe all that is cover for Brendan’s point above—I don’t want clients messin’ with their own site and breaking the information architecture conventions, and it’s more diplomatic to say that the system won’t let them do that rather than that their hired web gun has decided not to let them.

Mark Bowen said on 02/05 at 07:32 PM

Using your categories trick how do you then get any kind of active class on the category sub-page?

Doug Avery said on 02/05 at 08:01 PM

@Mark, since you’re making pages to represent the categories, you should get active classes the normal way using something like the Structure subnav tag - you’ll still be on the category’s “page”.

@Adam, interesting points. One note is that when we give clients Structure sites, we don’t see it as a “parallel” structure - we tweak some CSS to highlight the Structure tab in the nav, and play down Publish and Edit. I agree with you that training someone on both methods is less than ideal.

I think your last point might be a phantom fear - you’re not worried Structure will distribute too much power to users, but you’re worried that those users will demand that power and that you’ll be forced to give it to them. I’d say that if your clients are demanding to manually reorganize the site, you’ve got a problem regardless of your CMS solution - a problem that designers and developers need to solve with clients, not content management.

Don’t ignore solutions because they have features that could potentially screw up a site - EE is just full of those, and it’s our job to corral clients - either through education or feature disabling - into using the appropriate tools for the job.

Richard said on 02/06 at 03:23 AM

Thanks to everyone for this very enlightening conversation.

Doug’s more modular approach to templating is as far as I’ve ever seen the embed approach being taken (for an entire site; I do use the technique in specific circumstances).

I don’t think it would work for very complex sites though, but your run-of-the-mill blog + static pages site would benefit from that approach. I’m also concerned about server load with all those embeds on high-traffic sites, as the embed itself has to be fully parsed by the templating engine (I think it is 7 queries for template settings etc before the actual template code gets parsed.)

We’re also going through a similar standardisation process and playing quite a bit with PHP includes and path.php. We have a directory of common widgets that we use in a /lib folder, and simply include all the files in path.php, assigning them variable names along the way. Then we use those variables in our template code. It’s like a file-based FreshVars. Low’s Variables are also very exciting for speeding up development.

Adam’s points are important. With such search-dominance (we routinely get 70% traffic via Google), browsing via a nav bar though a hierarchy is overrated. I’m currently concentrating on contextual navigation rather (breadcrumbs, related entries, search). But you need geeky clients to see that point of view!

Hambo said on 02/06 at 05:51 AM

It all depends on what kind of site you’re running, page based or content based?

News sites probably wouldn’t benefit a great deal as they deal with content organised as (dare I say) a blog whereas some sites are based on a hierarchical page basis and Structure comes into it’s own.

There are obviously hybrids and you must assess the requirement of Structure’s features for yourself in these instances.

Look it’s just basically organising your entries into a specific order and takes away the need for entry_id and other cumbersome and limiting template requirements.

Mark Bowen said on 02/06 at 06:56 AM

@Doug - Sorry what I meant was that if you have say this setup :

Current Openings - Static Information Page
--------Administration
--------Management
--------Clerical

This would mean ‘Current Openings’ is just a quick informational page which tells you about the categories. Administration, Management and Clerical would then be sub-pages which would relate to the categories.

Clicking on one of these ‘categories’ would take you to a page that lists all entries in that category. This part I have set and working, however now when I click on one of the positions to go to a single entry type template it no longer has information in Structure to say that (for instance) Management is the active page.

Also the breadcrumb is then missing the information required to get back a single page meaning that the user has to either click back on the (now not highlighted) ‘category’ again or click their back button.

Mark

Doug Avery said on 02/06 at 05:26 PM

@Richard, interesting point about queries - we use a lot of caching, but I haven’t looked much into how this helps with embeds, and how many queries are being made on pages. Should definitely look at this more.

I’ve been tempted to go the PHP includes route as well, I’d love to read more about your setup.

@Mark - ah, okay - we use the category technique I outlined for a more blog-like setup. Current Openings would be a listing of all openings, Management would be a listing of all openings with the management category - but since categories have a many-to-one relationship with entries, we don’t worry about showing a “selected” state on the category nav when a user views an individual entry. Entries appear at the same segment a category page would.

The next version of Structure might have a solution for your problem, but I would personally suggest using a one-to-one object to organize these entries instead - like a weblog. If each one of these pages was a listing for a unique weblog, you’d be getting all the features you wanted, AND you clients could add new Management listings more simply (without needing to use the Categories) tab. Just a thought. Another option might be wrapping the breadcrumbs and nav in a way that allows you to use {categories} around them, giving you access to the cat name and url, but I haven’t tried this.

brad said on 02/08 at 11:51 AM

I agree that Structure can decrease the shock a client may feel when they first get into EE’s backend, although I do think it is much more intuitive than other CMS choices.

However, as a developer who is experienced with both the default EE and Structure’s UI; during content entry I find it much quicker to use the native EE functionality for populating weblog’s (and even sometimes static pages). I wonder if as clients get use to the interface they may trend away from Structure and towards native EE functionality?

Hambo said on 02/08 at 07:38 PM

@brad

It makes little difference when using native EE functionality or Structure to add pages, it’s just that if you want to add a sub page, you need to remember to assign a parent.

Weblog entries on the other hand are entered faster from the Publish tab. The Structure tab just makes things more logical.

Stephen McIver said on 03/17 at 01:08 PM

Hi there,

First of all, great article! I’ve been working in a similar method of working with the Pages module so it great to see someone else doing this and pushing it even further, and with the Structure module too.

Just a quick question - have you used Structure with Stand Alone Entry/Edit Forms before?  I’m finding that every time I edit an entry, it’s changing the Template specified in the Structure tab from the one I’ve set as the Default template for that weblog, to the first one in my template list.

This means that after saving, I’m getting a 404 error when I try and view the page for that entry.  To fix this, I have to manually edit the entry within the Control Panel by changing the Template back to the one I was using. Strange issue, but their website says it’s SAEF compatible since version 2.04 so I was just keen to know if you or anyone else had ran into this issue and overcame it.

I’ll drop the Structure guys an email too.

Thanks,

Stephen

Jack McDade said on 03/17 at 01:30 PM

@Stephen, What version of Structure are you using? We fixed everything for SAEFs in most cases in 2.0.4, but had an addition fix in (i believe) 2.0.7 for one last case where we found a bug. Make sure you have the latest version and give it another go, otherwise email support [at] buildwithstructure.com with your details and we’ll get a fix in ASAP.

Glad to see so many people excited about the module, even greater things coming soon!

Jack

Stephen McIver said on 03/17 at 01:36 PM

Hi Jack,

Thanks for the response - I was just typing out my email to you when the email notification of your reply came in my Inbox! :)

I’m using version 2.0.8 so will drop you a quick email.

Thanks,

Stephen

Commenting is not available in this weblog entry.

We're The Designers

at Viget Labs. We write about design news, trends, techniques, buildout, inspiration, CSS, and our projects.

What's a-twitter?

Follow us @VigetInspire for updates of the goings-on here or @Viget for more from all of the Viget crew. #thatisall

Recent Comments

We use it a lot at Hashrocket now. It’s made life a lot easier when coding large-scale applications.

The hardest part of SASS is going back to coding regular CSS after you’ve been in it...

Subscribe to Comments RSS RSS

Contact Us

Have any questions, comments, ideas, or secrets to share? Let us know.


What is the third letter in apple?

Sorry, you need to have Javascript enabled to use this form. (Don't blame us, blame the spammers!) If you'd like to contact us, please visit our Contact page.