Symphony Start to Finish

Published on January 2017 | Categories: Documents | Downloads: 59 | Comments: 0 | Views: 430
of 139
Download PDF   Embed   Report

Comments

Content

Symphony Start to Finish
Back in 2010, Craig Zheng made a deal with Wrox to write a book about Symphony CMS. Unfortunately, the Symphony
book project was cancelled.

Project Cancelled
After nine months and ten chapters, Wrox decided to cancel this book project in June 2011. Symphony Start to
Finish was to be the first comprehensive guide to building websites and web applications with Symphony. It was
meant to cover the next major version of the platform, but after Symphony lost its only full-time developer, progress
on that version was delayed significantly, and in the end Wrox was unable to accommodate the extended timeline.

What Now?
The considerable work put into the manuscript will be incorporated into Symphony's free online documentation.
Thank you for generously donating your book to the community, Craig.
The Symphony book was made available for free on GitHub. Keep in mind that the manuscript is not finished and was a
work-in-progress that refers to Symphony 3.0 (which never was released beyond the beta, which was really an alpha)
and Crane (there were plans, which were scrapped, to rename Symphony to avoid confusion with the Symfony PHP
framework). There is still a lot of valuable information to be gleaned from Craig's work, and now it's up to the community to
rework it to align this content with the latest Symphony release. Feel free to fork, update and send pull requests.

Chapters
Chapter 1. Why You Need Symphony
Chapter 2. Symphony in Action
Chapter 3. Getting Started
Chapter 4. Symphony Anatomy
Chapter 5. Content
Chapter 6. Front-end
Chapter 7. Data Flow
Chapter 8. Templating
Chapter 9. System Management
Chapter 10. Planning Symphony Projects
Chapter 11. Adaptive Techniques
Chapter 8 is a particularly good read for anyone who is just getting started with XSLT.

Chapter 1: Why You Need Symphony
What’s in this Chapter
The challenges of content management on today’s web
Prioritizing functions over features in web development
The Symphony approach
What Symphony can do for you
Confession: I actually don’t know why you need Symphony. I don’t even know who you are, or why you’ve got this book in
your hands. Maybe your boss or your client is asking you to use Symphony for a project. Maybe someone’s built you a
Symphony-powered website and you’ve got to learn how to run it. Maybe you’re a freelancer or a hobbyist standing in a
bookstore and wondering if Symphony could be a helpful addition to your toolbox. Or maybe you’re an agency lead or
project manager evaluating Symphony alongside other content management systems like Drupal or ExpressionEngine,
or even frameworks like Django or Ruby on Rails or that homonymic doppelgänger of ours, Symfony.
Whoever you are, what I do know is that you’re probably involved in building or running websites or web applications,
and there’s a good chance you’re wondering if, or how, Symphony can help you do it better.
There are tons of reasons to use Symphony. Well, maybe not literally tons, unless you etch each reason into the side of a
cast iron bathtub. But if you work within an organization or corporation, for example, you’ll appreciate Symphony’s ability
to conform to your own internal structures and workflows. If you run an agency, you’ll love being able to use the same
system for every project, reducing build times, training costs, and other kinds of overhead. If you’re a designer, you’ll
salivate over the control and flexibility afforded by Symphony’s standards-based templating layer.
Whoever you are, though, I think one of the most compelling reasons to use Symphony, one that really sets it apart, is
actually not that easy to quantify or explain. It has to do with how the web is evolving, why you need to be thinking several
steps ahead, and how Symphony’s unique philosophy and development approach make it a smarter choice with each
passing day.

The Challenges of a Changing Web
Maybe managing content on the web was never simple.
Or maybe my memory’s just hazy because the web wasn’t yet my profession and I didn’t fully understand it. I do seem to
recall a time, though, when websites were essentially just made up of pages, and whether you ran a multinational
corporation or a high school poetry club, the only real difference was how many pages you had… the pages themselves,
the basic units of content, were more or less the same. You’d simply compose them and then post them for the world to
see, like flyers in a shop window.
Granted, I’m no internet historian. But in my experience, managing content on the web today is a radically different kind of
endeavor than it was eight or ten years ago. The web has changed, evolved, and so too has the content that comprises it.
Whether you’re a freelance web developer, an agency, a hobbyist, or a corporate employee, what you need from a
content management system today—and what you’ll need from it tomorrow—is changing just as quickly.

The Evolution of the Web
The web has come a long, long way since the days of serving mostly static pages. Along with the rapid evolution and
increased capabilities of the web’s technologies have come significant shifts in the way we use the web in our everyday
lives. Lots of attention has been paid, for example, to the shift from merely consuming information on the web to
producing, repurposing, and interacting with content. It’s part of the broader phenomenon that has been labeled “Web
2.0.” But for all the hype behind the term, Web 2.0 is a signpost, not a destination, and our uses of the web have
continued to evolve.
Today, we expect the web to be much more than simply “interactive,” we expect it to be intelligently so. When we post a
video on Youtube, for example, we expect the web to do more than just display it. We expect it to be searchable,
embeddable. We expect people to be able to comment on it, share it, add it to playlists, transcribe it, remix it, and so on.
We expect the web to understand the content itself and how we want to use it.
Websites, on the whole, seem to have evolved along a similar path. As we seek more interactive web experiences, our
websites have gone from being mere collections of pages—each corresponding to a static file on a server—to being
dynamic, data-driven applications in their own right. It is not uncommon nowadays for even small websites to have rich
interfaces for browsing and interacting with their content.
And websites themselves are only part of the puzzle. Today’s web is a landscape of multilayered ecosystems that go
beyond websites, domains, or even protocols. Terms like “blogosphere” and “social web” come to mind—ecosystems that
have to do with the nature of content rather than its origin or location. In fact, it’s even beginning to appear as though the
web is outgrowing the browser itself. We now experience it as a platform that powers desktop applications, mobile
applications, APIs, and much more, in addition to websites. We’re no longer talking about a virtual realm that we visit from
time to time while sitting in front of our computers. The web is seeping into our lives, insinuating itself into other forms of
media, entering public spaces, and taking over our phones, televisions, and other devices.

The Evolution of Web Content
These fundamental changes—in the way the web is architected and in the ways we use it—are reflected in the changing
nature of web content itself. For starters, the things we publish and share on the web are increasingly granular. The web
is no longer made up just of flat pages, but of discrete objects like blog posts, videos, reviews, status updates, location
check-ins, and the like. And because they’re inherently meaningful (rather unlike pages), these sorts of granular content
have become the building blocks of intelligent interactions on the web.
Just think about how search has been transformed over the last few years. Where before search engines like Google and
Yahoo simply crawled huge indexes of pages and spit back matching documents, they can now deliver content-aware
search results that are far more useful. Type in a couple of airport codes and get flights and ticket prices. Enter the name
of a household appliance and see matching products from stores all over the web. And it gets even more granular than
that, with the spread of markup-enhancing formats for identifying discrete bits of information like phone numbers,
addresses, ratings, and more. The more intelligent the web becomes, the more useful it is to break content down into

these finer and finer bits. In fact, many observers see in this trend the web’s next signpost. “Web 3.0,” they say, will be a
semantic web in which ever more meaningful data is infused into the content itself.
And the more granular and meaningful content is, the more portable, too. As the web extends itself beyond websites and
even beyond browsers, content is increasingly likely to be used and consumed outside of the context in which it was
created. Web content today is not just disaggregated, it’s truly diasporic. On the one hand, we’re publishing more content
in more places—Facebook activity, Flickr photos, Gowalla or Foursquare check-ins, Last.fm playlists, and innumerable
comments, “likes,” votes, and so on. On the other hand, we’re also seeing our content disseminated far beyond our own
reach and the reach of our traditional websites. Our Twitter updates are being pulled into all sorts of applications and
devices, and are even being printed in books and on t-shirts. Our blog posts are being read everywhere from feed
readers to Kindles. Our podcasts are being loaded onto mp3 players, and our videos are streaming directly to television
sets. Wherever you look, you can see that web content is powering much more than websites these days.

The Changing Role of the CMS
Naturally, the tools we use to manage that content are evolving as well. Content management systems themselves were
born in the era of the page-based web. Their job was to enable you to quickly and easily update your website’s pages
and publish them. In fact, you can see traces of these origins in many CMS user interfaces today, their appearance and
behavior still mimicking those of desktop file browsers. As the web has evolved, though, we’re asking our CMSs to do
much more than update and publish static pages.
We’re asking them to manage all kinds of new content. One very obvious example is the blog post, and several new
content management systems have actually been built (and continue to be built) for this very purpose. But our web
content needs are many and varied, and are expanding rapidly every day. Creative agencies are managing things like
portfolios, inquiries, and testimonials. Corporations are managing staff profiles, annual reports, press releases.
Publications have got authors, issues, articles, and even artwork. And these are just three fairly simplistic examples. Then
you’ve got online stores, NGOs, political groups, universities, doctor’s offices, governmental bodies, sports teams, book
publishers—the list goes on and on (and on)—all with their own unique content needs. And we individuals may have the
most diverse needs of all. We’re managing everything from writing and photography to family trees to recipes and
reading lists and travel itineraries and beyond. And even when we use purpose-built tools or services to manage our
most specialized content, we’re still very often asking our CMSs to work with it in some way.
We’re also asking them to do more than publish our content onto static websites. We’re asking them to power
interactions. Even the simplest websites these days are often browsable and searchable; they’ve got content archives,
category views, and RSS feeds. They accept comments, votes, and ratings. We want our CMSs to be able to facilitate a
sort of conversation with our users, to guide them along specific journeys, to allow them to create and manage their own
pieces of content, and to remember them and what they’ve done.
Finally, we’re asking CMSs to integrate with the myriad other tools and services that we use on the web. We want them to
post tweets when we add content, or to pull from the streams of activity we’re generating around the web when we listen
to music, share photos, bookmark websites, and so forth. We want them to allow us to interact with web feeds and APIs. In
short, we want them to think beyond themselves. We want them to help us manage our content on the web as it is
becoming, not the web as it was.

Content Management Challenges
Obviously, even for the most ingeniously-engineered and forward-thinking content management systems, the challenges
are many.
To begin with, if the web’s content is becoming increasingly granular, CMSs need to be able to handle all kinds of new,
unique content. And the reality is that we can’t always predict what that content is going to be, or what shape it will have. It
isn’t enough anymore to have some sort of one-size-fits-all container (e.g. the “page”) into which to dump various kinds of
content. Today, CMSs need to be able to elegantly manage carefully-designed objects with very specific characteristics
that they cannot assume or predict beforehand.
What’s more, CMSs need to allow us to build interactions around our content. They increasingly need to be able to power
full-fledged web applications rather than just static websites. But again, much of this isn’t predictable. If you can’t know

what kinds of content you’re going to be dealing with, you can’t know how people will want to use it and interact with it,
especially since we find new ways to use things all the time.
Another challenge is that CMSs can’t always foresee where they’ll need to be able to extend their reach. Websites
themselves are now just one vector in an online presence. Our CMSs have to account for the fact that we increasingly
want to post, share, and disseminate our content all over the web—on websites that it doesn’t necessarily know about, in
formats it may not have heard of, and on devices that might not even exist yet! In short, the web changes fast, and the
tools we use to manage content on the web need to keep pace even when they can’t yet see over the next horizon.

Functions Versus Features
In this tumultuous landscape, it’s important to know that we’re using tools that will adapt with us as new challenges arise.
We don’t want to have to hack or customize a CMS to meet our changing needs. We don’t want to have to bend or break
our plans because our tools are limited. And we don’t want to have to completely rebuild every few years because our
strategies have evolved. What we want, essentially, is a CMS that’s future-proof.
But this isn’t always an easy thing to gauge, especially since we often don’t know what our needs are going to be a year
or two down the line. We want flexibility, yes, but lots of CMSs call themselves “flexible” and “extensible.” Lots claim to be
using tomorrow’s technologies today. How do we know if a system is engineered and developed in a way that makes it
ready for whatever the web throws at it? How do we know if it’s a system we can trust?
One question to ask is, “How are they solving problems right now?” Any CMS worth your consideration is evolving all the
time. Their developers are constantly making decisions—about priorities, about approaches, about what sacrifices
they’re willing to make—and the sum of these decisions is what I would call a development ethos. Every software project
has one, whether it’s made explicit or not. It’s what guides a project’s developers as they set about making improvements
and solving new problems. Understanding a CMS’s development ethos is your best bet for predicting if and how they’ll
evolve and adapt to the challenges of a changing web.
Of course, every CMS is unique, with its own history, its own reasons for being, its own talented group of developers. But
because all CMSs are built for roughly the same purpose—managing content and content-driven sites on the web—it’s
possible to identify broad similarities in approach. In my experience, regardless of their particular focus, their unique
history, their size, or their popularity, the vast majority of content management systems have a development approach
that I’d call “feature-focused.”

A Feature-focused Approach to Content Management
Feature-focused CMSs are conceived and architected primarily as collections of content management features. Of
course, “features" is one of those slippery words that can really mean almost anything, so I’ll elaborate. The “features” I
have in mind arise out of the need to manage particular kinds of content in particular ways, and have two defining
characteristics:
they solve a specific content problem
they provide a complete, fully-integrated solution to that problem
Take a moment to think about the various kinds of content management needs that have emerged in the last five or ten
years, beginning with things like forums and polls and continuing through to blogs, wikis, comments, tagging, and so on.
A feature-focused CMS engineers solutions to each of these problems directly, and whether they’re included in the core
platform or as pluggable extensions, the system is more or less a collection of these sorts of features. It has a forum, a
calendar, a blog, a wiki. It has a polls feature, a tags feature, a menu feature. It addresses every content need head-on by
providing a feature that solves exactly that need.
These features are designed to be fully-integrated solutions, meaning that everything—from how its content gets
captured, to the interactions it supports, to the way it is displayed on the front end—all of that is baked right in. The user
rarely has to do more than activate the feature and specify a few preferences.
Take an image gallery feature, for example. There are lots of things to consider when implementing an image gallery.
When you upload an image into the system, what kinds of information can be attached to it? A caption? A source? A
smaller “thumbnail" version? How will they be managed and organized? By tag or category, or grouped into collections

or albums? And are they displayed on the front end in a dedicated image gallery area, included in other pages as
slideshows, or somewhere else?
A feature-focused system answers all of these questions for you. It defines how the content is captured, managed, and
displayed. It might even go so far as to provide the markup, stylesheets, and JavaScript for the front end. The priority is on
delivering fully articulated features that require minimal work and decision-making from end users, something that can be
really convenient, but only as long as these features are implemented in a way that closely matches your needs.

Limitations of a Feature-focused Approach
But when you’re thinking long-term, and you’re aware of the shifting sands that underlie the web, this feature-focused
approach starts to look a little worrisome.
For starters, these kinds of features are crafted to address specific content needs. But as we’ve seen, web content is
continuing to evolve in ways that are not easy to predict. Every time your needs change, every time your boss or client
catches wind of a new “must-have” trend, you’ll be left either cramming new square content into an old round hole, or
waiting for someone to implement the new feature you so badly need.
What’s more, even if the feature is implemented, you can’t necessarily trust it. Features in the sense outlined above are
basically monolithic, engineered from top to bottom to work in a very particular way. You’re constrained, in other words,
by the decisions and assumptions made by the people who built the feature. So what happens, then, when your boss or
your client has a change of heart, and wants the blog to act more like a magazine? What happens when you realize that
you don’t like “tagging” and want to use a more traditional category structure instead? What happens when you want to
manage image galleries, but want to use your own markup?
Features can seem “powerful” and “easy to use” precisely because they don’t require you to make your own decisions,
but then guess what? You can’t make your own decisions. Someone else has made a whole bunch of assumptions on
your behalf, assumptions you now have to live with. And the more complex a feature is, the more assumptions it’s had to
make.
Anyone who’s ever built a website using a system like this knows the feeling of running into walls, of wishing they had a
bit more control, of cursing the sun, moon, and stars because making even mundane changes feels like trying to move
mountains with a teaspoon.
And if you’re a developer, you know there are other drawbacks too. When your solution to emerging content needs is to
build new features, it doesn’t take long for the system to begin to bloat. It starts taking up more and more space, its code
becomes harder and harder to maintain. The user interface starts to clutter and crowd because every new feature needs
to have a place. This is not the kind of system you want to rely on in the long term, because it’s the kind of system that
spreads thin and starts to fray at the edges. Old features are neglected in favor of new ones. New ones roll out too quickly
and become error-prone. And the developers, as hard-working as they are, just have too much ground to cover.
At the end of the day, feature-focused CMSs aren’t “bad.” Their developers aren’t any less capable or well-meaning than
any others. And often, when your requirements are just right, they’re actually good, useful tools. But they’re constraining.
They make it painfully difficult to be creative and innovative, and to try new ideas. They may be fairly good at delivering
what you need today, but tomorrow, you’re on your own.

Prioritizing Functions over Features
There’s another way of doing things though. A different kind of development ethos. Given a content problem, this
approach doesn’t address it head-on. Instead, it pulls the problem apart, trying to figure out what it’s made of. It begins
with the idea that every large, specific need is actually a collection of smaller, more general needs. Integrating a Twitter
feed into your site, for example, is a large, specific need. But what it consists of, really, is the need to pull in content from
an external source and to allow that content to be templated within in your system. Solve these smaller problems and
you’ve solved the bigger one. And many, many other big ones.
I think of this approach as being focused on functions rather than features. It’s concerned with what simple things the
system itself can do rather than what complex, prefabricated solutions it has. It wants to make it easy for you to solve your

problems rather than trying to solve them for you.
Take our image gallery example from earlier. A function-focused system wouldn’t be concerned with engineering a
complete, ready-to-go gallery feature. It would be breaking the problem down into smaller pieces: the need to manage a
new kind of content, the need to define what data gets captured by that content type, the need to create structures for
grouping or otherwise organizing it, the need to display that content on the front end. It would make sure the system had
all of these fundamental capabilities, so that in the end its users could create any type of gallery they wanted.
Focusing on functions means engineering a system that is inherently capable. It means being preoccupied with the
basics—functions that help people create and manage their own kinds of content, build their own interactions, architect
their own front ends. When new needs and challenges arise, this approach asks what core capabilities are missing or
need improvement. This way, rather than piling on tons of complex, narrowly-defined features, it selectively adds broader
functionalities that make the system as a whole more powerful while at the same time keeping it lightweight and flexible
too.
As I noted above, there’s probably not a CMS in existence that doesn’t call itself “flexible.” But focusing on functions
cultivates a level of flexibility that few other systems can offer—the flexibility to make every decision for yourself, to be
creative when solving problems, to experiment. Rather than constraining you, this kind of system is obsessed with doing
the exact opposite—giving you all the tools you need in order to do whatever you like.
This means you can add all sorts of new content as the web evolves. It means you can keep dreaming up new kinds of
interactions, new paradigms for how a website can look and act and feel. It means, in short, that your CMS is indeed
future-proof.

The Symphony Way
Symphony is one of these rare CMSs. It sets itself apart by having a coherent development philosophy that is resolutely
focused on the system’s core functions and capabilities rather than on specific content features.
As a platform, it is more principle-driven than most. Its development team, along with its wider community of developers
and contributors, tries to adhere steadfastly to a set of core tenets like simplicity, modularity, and transparency (among
others). And the system is carefully designed to allow users themselves to be principled and to follow best practices.
There are three particular aspects of the Symphony approach that I want to point out here because I think they make
Symphony especially well-equipped to deal with the demands of a rapidly evolving web. Odd as it may sound, all three
have to do with a sort of... calculated humility—an understanding of what we don’t (or can’t) know, and a willingness to
recognize when someone else knows better than we do. Taken together, I think these three concepts demonstrate why
Symphony might be the most flexible, future-ready content management system there is.

Make no Assumptions
The more assumptions you make, the more likely it is that you’re going to be wrong. And when it comes to things that are
supposed to be useful—like software—the more they’re wrong about how we want to use them or what we’re trying to
achieve, the less useful they turn out to be. This is especially true on the web, where nearly everything is a moving target
and, let’s face it, we’re already likely enough to be wrong as it is.
For example, not everyone wants to put all their content into articles or blog posts, or into a complex hierarchy of pages.
Not everyone wants to organize or display their content in the same way, or sort it in the same order, or deliver it in the
same format.
And even when users do want something predictable like a blog post or an article, not everyone wants it to be made up of
the same pieces. Sometimes it’ll be the usual: a title, a body, a date, an author, and so on. Sometimes it won’t. Some
people will want to include things like subtitles, epigraphs, or postscripts. Some will want to include a writing prompt they
used, or meta information like what they’re listening to or where the post was written. There will even be people who want
to art-direct each post individually, giving it its own stylesheet and assets.
The point is, we humans are a creative bunch, and there’s really no telling what we’re going to cook up. Symphony
understands this, understands that every assumption it makes would be an anchor weighing you down. So it tries not to

make any at all.
Of course, there are some givens. It’s a web content management system, after all, so it trusts that you want to manage
content on the web (go figure). But beyond that, Symphony tries not to predetermine much of anything, including:
the kinds of content you can manage, or how they’ll be made up
how your content can be organized
how and where the content can be fetched and used
whether—and if so, how—that content is presented via a front end
what that front end looks like or how it behaves

Provide the Tools, Trust the User
This “make no assumptions” approach means that Symphony doesn’t act as though it knows better than you. Whether
you’re an employee working under very strict content requirements and workflow demands, a project manager who
knows exactly what you need to accomplish, or a designer or developer with very precise methods to your craft, few
things are as frustrating as tying to use a system that insists you do things its way rather than your own.
Symphony is comprised of a bunch of modular components, each providing a basic, core functionality. One of these, for
example, allows you to build new content structures. Another allows you to query your content, or to fetch it using detailed
criteria. These components are like building blocks from which you can craft your own content solutions. You could say,
for instance, “I want to manage real estate listings. Each listing will have an address, a price, a set of photos, and a flag to
indicate whether it’s on the market. Then on my home page I want to grab the most recent ten listings that are on the
market, with the most recent at the top. And here’s how I want to mark them up…”
Each and every part of that solution would be completely configurable. So you could go back and say, “Actually, I need to
add some stuff to my listings: lot size, square footage, number of bedrooms, amenities, etc. I also want to fetch 25 listings
for the home page now instead of 10, and I want the user to be able to choose how they’re sorted.” The power lies in
making each building block basic, modular, and independent, so that they can be continually reconfigured and remixed
to yield unique solutions that accomplish exactly what you want, every time.
Providing you with these kinds of tools, and trusting you to be able to find ways to solve your problems, means that
Symphony is always ready to cope with new challenges. It also means that, rather than playing catch-up with web trends,
Symphony's just as likely to be leading them, because it leaves room for imagination and empowers smart, creative
people to do what they’re best at.

Rely on Open Standards
When smart, creative people do what they’re best at (and they’re not all Symphony users, believe it or not), they make the
web a better place. They invent useful technologies, establish best practices, and continually expand the boundaries of
what’s possible. Symphony happily stands on the shoulders of these giants, as they say, by enthusiastically adopting and
advocating open web standards.
Perhaps the most important and obvious example is Symphony’s use of XML as its native data-handling language. XML
is a widely-used data format officially recommended by the world’s web standards body, the W3C. Every XHTML page
there is, every RSS and Atom feed, and nearly every API on the web—all are XML. The oceans of open source and
commercial documentation written in DocBook? XML. Millions of other business documents, scholarly articles, and
government datasets? XML. Newer word processor files like ODF and DOCX? XML. The million-plus ebooks that Google,
Apple, and others have stocked up in EPUB and other formats? Those are XML too.
Symphony’s fundamental components are designed from the start to handle XML, because when the system passes data
around, that’s the format it itself uses. What that means is the entire smorgasbord of content that I just listed above, and
every other XML-based format, can be immediately recognized and handled by Symphony. Natively.
In order to template all of this content, Symphony turns to another XML-based W3C standard: XSLT. XSLT is a powerful
templating language that can transform source XML into nearly any format imaginable. This means that in addition to
outputting (X)HTML pages, it can output RSS-or-Atom-flavored XML, SVG, and even non-XML formats like CSS and

JavaScript, CSV, PDF and more. Again, natively. And unlike most other CMSs, Symphony’s template language is a fully
open standard, not some proprietary jumble of made-up tags. Instead of memorizing some specialty language and halfcoding your templates in a procedural programming language like PHP, with Symphony you use a powerful, consistent,
rule-based language that is just as useful outside of Symphony as it is within.
Embracing XML and XSLT means that Symphony already, natively, plugs right into all the dynamic, diasporic content that
is at the heart of the evolving web. You don’t need any fancy plugins or parsers or converters. You don’t need anyone to
build a “feature" for all those feeds and APIs you want to interact with. All you need is Symphony.

How Symphony Can Help You
So now that you’ve got a sense of what it is that makes Symphony truly unique, how do you know if it’s right for you and
your next grand endeavor? After all, every project has its own unique requirements and constraints, and as flexible and
powerful as Symphony is, no system is right for every situation. The (admittedly presumptuous) title of this chapter is “Why
You Need Symphony,” but there might be times when you don’t need Symphony. For instance:
When a more narrowly-focused niche system does exactly what you need, and offers useful specialized features out
of the box
When you or your team haven’t yet got the time to learn the ins and outs of a new system (even when there’s a handy
book available)
When the demands will be rigorous enough that it makes more sense to build a carefully-tuned system from scratch
in a more performant language like Python or Ruby (Symphony’s written in PHP)
When you prefer to work with another database system (currently, Symphony only supports MySQL)
When you’re an alien life form sifting through the remnants of human civilization 2,000 years from now, and you
found this book under the leg of a wobbly table (in which case, you should know that it was a tradition among we
humans to put only our most cherished books under the legs of our tables. Honest.)
That said, in the vast majority of situations Symphony is likely to be one of the most capable and elegant tools you’ll find.
Here are just a few of the many things Symphony can do for you:

Power Any Kind of Website
There are CMSs that are great for building enormous, complex, high-demand websites, but for smaller projects these
same systems turn out to be bulky, bloated, and unwieldy. Then there are CMSs that gracefully handle small sites with
limited content and dynamism, but break down when those sites need to adapt or expand. Few systems can do both well,
but because of Symphony’s modular architecture and unique development philosophy, it is one of those rare CMSs that
can run a megasite as cleanly and elegantly as it can a tiny one.
Symphony’s been used to build everything from personal blogs and portfolio sites to social networks to high-delivery
websites that host thousands of videos, receive bandwidth-choking traffic, and process millions of interactions. What’s
more, a Symphony site is easy to scale as needed, it can go from small to big and back again, because the system is
made up of swappable, removable building blocks. With Symphony, agile, iterative development is a breeze.
Symphony can even power full-fledged web applications. Just as there’s a basic Symphony component for fetching your
content and channeling it to your user-facing front end, there’s also a component for accepting input from your users and
channeling that back into the system. Combined with the tremendous amount of flexibility you have when architecting a
front end in Symphony (more on that in Chapter 6), these make it possible to create all kinds of advanced interfaces and
interactions.
The reason Symphony is so versatile is that it’s actually a hybrid of sorts between a web development framework and a
CMS, combining the raw capabilities of the former with the ease-of-use and conveniences of the latter. In fact, many
agencies and freelancers, once they’ve gotten a taste of Symphony, actually make it their exclusive development
platform. It’s just that flexible. There isn’t a project that comes their way—however large or small, however simple or
complex—that they don’t think Symphony can handle. And they’re probably right.

Give You Back Your Data

Your data is increasingly spread out all over the web. Maybe you’re posting status updates on Twitter. Maybe you’re
uploading photos to Flickr or Facebook or Picasa. Maybe you use a bookmarking service like Delicious, or take notes
with a tool like Evernote. You use these tools because they’re great at what they do, and because they are embedded in
broader social ecosystems. But it’s still your data, and because these sites (and basically all others) have feeds or XML
APIs, Symphony can put it back in your hands. You can fetch it dynamically and aggregate it for display, or you can
actually import the data right into your own site. Either way, Symphony can help you begin to reclaim all of the content
you’re generating around the web every day.
In corporate or organizational environments, Symphony can also make your life a lot easier by facilitating communication
among other disparate applications. In this sort of environment, it’s fairly likely that your company or client has alreadyexisting systems for managing their information. Maybe it’s an intranet. Maybe it’s a CRM application, or a custom
database. As long as it’s got a simple web services layer or API, Symphony can talk to it, helping you improve the flow of
data throughout your organization and avoid situations where the same content is fragmented or duplicated across
multiple systems.
I worked on a project, for instance, where most of the content that was going to drive the website was already being
managed in an internal CRM. Rather than having to build a custom front-end to the system, or having to keep duplicate
versions of all that content, we were able to use Symphony to grab data directly out of the CRM. This meant that
employees could go on managing their information just as they had before, and anything that was suitable for display on
the website could get pulled out and templated by Symphony.
And this works both ways. Because Symphony has a granular data model, and because XSLT can output almost
anything, your data will never be trapped. If you decide a few years down the line to use another tool, or to move your
data into some external archive, you can just have Symphony fetch your content and transform it into whatever format you
need. In fact, in Part 4 of this book, we’ll do exactly that, using Symphony to build a simple application API.

Put You in the Driver’s Seat
Whoever you are, using Symphony will give you all the control you could ever ask for—over strategies, over workflows,
over site architectures and user journeys, over markup, and just about everything else you worry about from day to day.
Here are some examples of how using Symphony can put you in the driver’s seat:
You’re a developer. You’re good at designing systems and architecting websites. You know what you want, and you
know what you’re doing. Symphony stays out of your way, letting you craft exactly the tool you need and nothing more—
no cruft, no fluff, no headaches. Symphony will support whatever agile, iterative workflow you prefer. Its file-based project
architecture means your entire build can be easily version-controlled. And if you find yourself building lots of websites
with similar requirements, you can just create the scaffold once and Symphony will let you package it up as your own
installable flavor of the CMS (we call them ensembles). Neat, huh?
You’re a designer. Your markup and your CSS are sacred. You’re trying to craft beautiful web experiences and the last
thing you want to do is deal with some system’s sloppy output. Well, guess what? Not a single byte of code gets output by
Symphony unless you write it. Top to bottom, you’re the master of this domain. And you’ve got at your disposal all of the
tricks that XSLT has up its sleeve too—you can organize and reuse snippets of code, enforce rules for sanitizing usercreated content, make your designs dynamic and responsive to user input, and much more. The system can even do onthe-fly image manipulation, meaning you can ensure pixel-perfect images in your designs, even when they’re useradded.
You run an agency. You command large specialized teams and manage several, maybe dozens, of projects. With
Symphony, you’ll have one system that can meet virtually all of your needs. This means you can train your staff once,
quote more reliably, build faster, deploy easier, and maintain with less effort. Because Symphony’s so modular, and all of
a project’s key structures can be easily version-controlled, you don’t have to be stuck in a linear development path where
each team waits for the one before. All kinds of work can be happening simultaneously, and iteratively, saving you loads
of time. And should you ever need it, there’s round-the-clock commercial support available too.
You’re an editor or producer. You care about your work and the integrity of your content. If your company or
organization’s website is powered by Symphony, you can define everything from exactly how your content is captured
and stored to the editorial and moderation workflows it will go through. From a system as simple as an approval flag to

one as complex as a multi-tiered review and editorial process, Symphony can be set up to accommodate your exact
needs.
You’re a systems administrator. Maybe you work for a government agency or a university. You have to deploy and
support a lot of websites, but their requirements can vary drastically. For maintenance and documentation purposes, you
want the convenience of using a single CMS. For performance and usability purposes, you want the benefits of custombuilt systems. With Symphony, you get both. You get a CMS where each build is essentially a custom CMS.
You’re a highway bandit. You block roads with large, impassable objects and then descend from the woods to steal from
those who land in your clever trap. You actually don’t need Symphony to put you in the driver’s seat—you have your own
means of getting there. In fact, you’re probably in a driver’s seat right now, in a car that you stole from the very nice
person to whom this book once belonged. Shame on you.

Summary: Crafting the Future of the Web
Every day, the web is evolving, growing, changing shape. Every day it’s reinventing itself.
If you’re reading this book, chances are that you’re somehow part of this process. And if you are, you know how difficult
it’s become to keep pace with the web as it evolves. Its content is changing, the way we use it is changing, and every time
we turn around there are new needs, new demands, new challenges.
The tools we use to craft the web are evolving too, or at least they should be. But when so much about the future of the
web is unpredictable, we want more from our tools than just change. We want reliability. We want to know that they’ll be
able to handle whatever comes their way. We want tools that we can trust.
In the world of content management systems, one of the most prevalent strategies for keeping up with the web’s shifting
currents is to pack the system with features that address all the needs of the day. But this approach is shortsighted, and
these systems often end up being unnecessarily restrictive and cumbersome. Users are forced to adapt to the way the
features are built, and when they want to do something innovative or creative, usually have to wait for the system’s
features to catch up.
Symphony, on the other hand, focuses on function, on providing you with the basic tools you need to creatively solve your
own content problems. This results in a system that’s inherently more powerful, and yet still nimble in the face of new
demands and changing needs. With Symphony, you get a CMS that doesn’t make any assumptions about what you need
to do or how you want to do it. You get a CMS that’s modular, that allows you to craft exactly the tool you need, in exactly
the way you want. You get a CMS that leverages the web’s most powerful open standards, putting ever more possibilities
at your fingertips.
If you need to build or manage a website, and you want a CMS that’s smart, elegant, and future-proof, you need
Symphony.
You need Symphony today because it’s versatile enough to gracefully power any kind of website or web application.
Because it can help you manage your content more efficiently than ever before. You need Symphony today because no
matter who you are, it will help you do what you do better, faster, and smarter. Because it will empower you to try new
approaches, to think boldly and creatively. You need Symphony today because it’s powerful enough and flexible enough
to allow you to adapt to whatever the evolving web has in store.
In short, you need Symphony today because you need Symphony tomorrow.

Chapter 2: Symphony in Action
What’s in this Chapter
A tour of Symphony-powered websites
Whether or not you found any of these arguments persuasive (and I’ll assume you did because I wore a sweet salesmanstyle fake mustache while I was writing them), the truth is that you’ve got work to do, and you’re going to need a lot more
than arguments to convince you that Symphony should be part of that work. Tools have to do more than sound good.
They have to do the job. And at this point you’re likely wondering if Symphony can help you solve your problems in
practice, and not just in theory.
The purpose of this chapter is to try and answer that question—not with lots of theory or marketing-speak, but by showing
you concrete examples of Symphony in action in various contexts. They won’t be overly detailed, because you still
haven’t been thoroughly introduced to the system. And they’re not anywhere near exhaustive as far as Symphony’s
capabilities are concerned. The goal here is just to give you a more concrete idea of the kinds of things you’ll be able to
achieve if you decide to turn to Symphony for your next project.
We’ll be looking at a small sampling of websites that I’ve chosen simply for their variety, and because I know them well or
have easy access to their developers. There are literally hundreds of other wonderful, unique examples in the Symphony
showcase (http://symphony-cms.com/explore/showcase/), and I encourage you to check them out, too.

Personal Website: The Interactive Manufactory of Jonas
Downey
Figure 2-1

[0201.png]

Overview
URL: http://jonasdowney.com
Developer: Jonas Downey
Jonas Downey is a clever dude, and one visit to his website should be enough to convince you of that if you’re not
inclined to take my word for it. In addition to being a talented writer and web developer, Jonas does some really amazing
work with data visualization and computation, and he whips up all sorts of fascinating conceptual and artistic
experiments. He also blogs, tweets, takes photos, listens to music, and bookmarks interesting sites. His website, or
“Interactive Manufactory,” is designed to be a virtual home for all these endeavors, a hub both for his day-to-day life and
for his creative work. Like most websites of its kind, it is meant to be a reflection of its owner—his work, his interests, his
personality, his tastes. The site sports Jonas’ own homespun design, built using HTML5 and CSS3. It features a
compelling visual portfolio, a bio page, a contact form, and many of the other things you’d expect from a personal
website. It also aggregates the scattered digital impressions Jonas makes on the web each day, from Twitter updates and
Last.fm albums to Flickr photos and Delicious bookmarks.

Points of Interest
With his data spread out across so many third-party services (including his own external blog), Jonas wanted a way to
pull it all together. But he wanted to do more with the data than just display it. He wanted to be able to work with it,
manipulate it. So instead of just having Symphony grab and template the data dynamically (which it could easily do),
Jonas used a Symphony extension to import the XML data he collects from each source right into his own site’s content
structure.
This means he can go on using these other services and all the tools they offer, but he also gets to keep his own archives
of tweets and bookmarks, for instance. It also means that, because he’s got the content stored locally, he’s able to mix
and mash it and put it to interesting uses. The most obvious of these is that he takes the bits and pieces that he gathers
and uses them, along with his own daily notes and reflections, to render some pretty neat visualizations of his activity
over time (Figure 2-2).

Figure 2-2

[0202.png]

Developer’s Thoughts
“Truly, this site would never have happened without Symphony. For several years I had envisioned aggregating my
various personal data into a cohesive site, but the available tools were complex and functionally lackluster.
“With Symphony, the XML data loading capability was the feature that sold me on day one. I no longer had to worry about
how to get my content into my content management system, which is really what they're supposed to do, isn't it? Once
sold, I quickly discovered all the other great features of the system; in particular I loved the elegant interface, the complete
control over markup and output, XSLT for templating, and abstracted database queries via Data Sources. As an extra
bonus, any time I got stuck on something, the community was super helpful.
“It was definitely hard work learning everything, but it was ultimately a complete joy to build with Symphony. And now I'm
already in the process of using Symphony for an even bigger data visualization site.”
Jonas Downey

Web/Mobile App: Clorox MyStain
Figure 2-3

[0203.png]

Overview
URL: http://clorox2.com/mystain/
Developer: Vine Street Interactive
I’m notorious for staining just about every shirt I’ve ever worn. Ask my wife. And usually I can’t be bothered to think about
how to get those stains out—to me they’re just soup-dumpling-flavored badges of honor. But Clorox’s nifty (Symphonypowered) myStain app might very well change that.
Available as both a web app and a set of mobile apps, Clorox’s myStain provides entertaining and timely tips for wouldbe stain fighters, whether they’re at home with their full arsenal of laundering products or out and about with little more
than a bottle of water and a packet of salt. Users can browse through a stain library, vote on stain-fighting solutions and
share them with their hapless friends via email or social media, or take a spin with the app’s slot-machine-style stain
scenario generator (which is a nice way to feel like you’re winning something even when the crotch of your best-fitting
pants has been smeared with sloppy joe).

Points of Interest
The myStain project leverages Symphony to orchestrate the flow of content to and from four different environments—an
XHTML website, a Flash-based web app, an iPhone app, and an Android app. Symphony’s flexible XSLT templating
layer allows the app to output its content in whatever format each environment requires. It provides XHTML for the
website, generic XML for the Flash app, an Apple Plist for the iPhone app, and JSON for the Android app. This means of
course although users can access the app’s content in several contexts on several devices, producers only have to
manage their stain tips in one place. And the data flow goes two ways: Symphony also receives user-submitted votes
from all of the different app environments.
The broader website in which the myStain app content appears is actually not Symphony-powered. It’s managed by
Clorox’s own proprietary CMS. But again, because of the openness and flexibility of XSLT, the Symphony-powered
portions are able to elegantly integrate with the company’s existing architecture.

Developer’s Thoughts
“The primary criterion for myStain's content management was a system that played well with others. When the project
started, we knew the site would be talking to an iPhone app and a Flash component in addition to serving vanilla XHTML.
Since both of these client apps could easily consume XML, I knew Symphony would be a good fit.
“Most of our workload on this project was the development of the mobile apps rather than the data service that would feed
them, so we needed to be able to get content web services running quickly, even before the information architecture (IA)
was completely locked in. Before I coded anything, Symphony's extremely straightforward content- and event-modeling
interface had most of the content service up way ahead of schedule, which is always a nice way to start a big project.
“As development progressed, requirement changes came in for both the IA as well as what the mobile app developers
wanted. Symphony's use of XSLT was really important in this situation. Since XSLT is built to handle XML, the iPhone
developer had free reign to code for any Plist structure he wanted. Late in the project, when the client added an Android
version to the plan, we chose JSON as the transport format for the Android app. Since XSLT is an open standard, any
generic XSLT solution can be used in Symphony. I easily found a template online that helped me output the necessary
JSON.
“To integrate Symphony’s output with the Clorox content system, we needed to use simple php include function calls to
render the header, footer, and other components of the page not under Symphony control. PHP in the view layer is a
relatively un-Symphony thing to do, but fortunately I had previously written an extension (EXSL Function Manager) to

help with just such a requirement. This extension converts PHP functions into EXSLT functions, keeping our XSLT
templates nice and clean while incorporating the needed external markup.”
Andrew Shooner, Developer, Vine Street Interactive

Publication Website: Public Culture
Figure 2-4

[0204.png]

Overview
URL: http://publicculture.org
Developer: Craig Zheng
I think I remember hearing that most people who build and manage websites for a living spend their copious free time
catching up with the latest scholarly discourse on topics like globalization, capitalism, cosmopolitanism, and modernity.
As such, you’re probably already intimately familiar with the journal Public Culture.
The journal’s website is a showcase of sorts for its content and for related news, events, and resources. Users can
explore Public Culture’s recent archives, browse its contributors, and see artwork and photography that has appeared in
the journal. The site also features lots of detailed information about the journal (mastheads, submission guidelines, and
the like) along with news and events listings, a visual “Books Received” stream (powered by Readernaut), a host of web
feeds, and more.

Points of Interest
As a journal, Public Culture is dealing with loads of content that is inherently meaningful. Issues have numbers, publish
dates, and covers. Articles belong to issues, and have page numbers, authors, sometimes artwork. The journal’s
contributors can have bios, academic disciplines, affiliations, and can be linked to articles, artwork, news items, events,
and so on. Symphony’s open content structure allows all of this data to be stored in bits that are most meaningful in their
particular context. For example, capturing page numbers means it can use those to build links to citation tools on the front
end.
The website features some interesting third-party integrations as well. Its search function is powered by Google’s Custom
Search Engine (CSE)—meaning it takes advantage of the search giant’s powerful indexing and algorithms, but receives
search results as XML that can be templated natively within the site. It’s a seamless experience for users, and Google
takes care of all the heavy lifting.
There is also some integration with CampaignMonitor (CM), a service the journal uses to send email newsletters. If
you’ve ever had to design an HTML newsletter, you know what a hellish process that can be. But because of
CampaignMonitor’s HTML import tool and Symphony’s flexible front end, the site simply uses an alternate template to
render newsletters for import into CM. What that means is that the journal’s staff never has to think about formatting HTML
emails. They just write a newsletter once in Symphony, and it is made available both within the website itself and as a
standalone HTML email (Figure 2-5).

Figure 2-5

[0205.png]

Developer’s Thoughts
Public Culture is actually the reason I found Symphony. I was a graduate student in anthropology at the time, and working
as a manuscript editor for the journal. I had a bit of experience with web development, though, and so when the journal
needed a new website, I volunteered my amateurish services.
I built the first version of the site using another (very popular) CMS. All throughout the development process, I grew
increasingly frustrated as I ran into inefficiencies and constraints over and over again. One of the reasons I’d chosen the
system is that it allowed me to define the content types I needed (journal issues, articles, authors, and so on), but the
further I got the more I realized that the system itself was still remarkably inflexible. I couldn’t even sort authors by last
name! And the more I learned about web development and web standards, the more I realized that this system really was
doing a lot of things poorly.

I started searching for alternatives and found Symphony just as we were launching the first version of the site. The
difference between the systems was so stark that I began rebuilding it almost immediately. Symphony was a breath of
fresh air, giving me the freedom to craft the site exactly as I wished I could’ve the first time around. I had total control. I
defined the content that would drive the site, bit by bit, and Symphony allowed me to bring it all to life however I wanted. I
could create interfaces to browse issues by volume or authors by the first letter of their last name, and enable browsing
via the many rich relationships embedded in the content. I was able to implement a very systematic and structured design
system. And no matter what new problems or requirements arose along the way, Symphony always gave me a way to
solve them, easily and elegantly.

Business Website: Original Travel
Figure 2-6

[0206.png]

Overview
URL: http://originaltravel.co.uk
Developer: Airlock
Original Travel is an award-winning travel company in the UK that provides custom, luxury vacations and tours all around
the world. If, like me, you’ve been holed up inside working feverishly for extended periods of time, be warned that visiting
this rich, visually stunning website is going to make you very, very sad.
The site allows potential clients to explore the hundreds of different trip possibilities on offer—browsing by destination,
type of trip, time of year, etc. Every step of the way, visitors are provided with local travel tips and detailed information
about hotels and activities. Dedicated trip specialists for each region contribute to a company travel journal. The site also
features a shop (with checkout), and once a customer has booked a trip they can login and view their itinerary and other
documents online.

Points of Interest
Original Travel’s website is all about places (places I can’t be, incidentally), and so it’s fitting that one of its most
distinctive features is a robust integration with Google Maps. When destinations and journal entries are entered into the
system, a map location field (provided by a Symphony extension) allows content editors to set their location simply by
placing a pin in a map. The data saved by that field is actually a pair of longitude and latitude coordinates—the useful
bits, in other words. On the front end, visitors are then able to browse destinations using an interactive map, onto which
all of the different sets of coordinates in the system have been plotted.

Figure 2-7

[0207.png]

Original Travel also makes heavy use of Symphony’s dynamic image manipulation capabilities. The site’s many
gorgeous photos of tropical beaches and European villas that torture me so relentlessly can each appear in multiple
contexts, and for each context the design has different size requirements. These range from full-width (974x368) to promo
size (306x172) to thumbnail (160x90). Does that mean that for every image (and there are lots), editors have to create
several versions? No. They upload an image once and only once, and everything just works. How? The designer has
crafted the site’s templates to specify what size images belong in which contexts, using a specially-crafted URL in the
image element’s src attribute. Symphony takes care of the rest, dynamically resizing, cropping, or otherwise editing the
original and then caching and serving the resulting image.

Figure 2-8

[0208.png]

Developer’s Thoughts
“Symphony allowed us to quickly build our data model directly from the wireframe blueprints, in a matter of days rather
than weeks. We modeled continents, counties, trips, hotels, activities, seasons, journal articles, testimonials and many
more (52 in total). We were able to let the client add start adding their content to these sections before the designers had
even finished designing the site! And because sections are easy to modify, we could react to evolving content
requirements as data entry progressed. This meant that by the time we came to build the frontend, we already had more
than half of the final content to style with. You don't get much more agile than that.”
Nick Dunn, Head of User Experience, Airlock

Social Network: Whisky Connosr
Figure 2-9

[0209.png]

Overview
URL: http://connosr.com
Developer: Jean-Luc Thiebaut
Everyone’s got a passion, and for some people that passion just happens to be hard liquor. Whisky Connosr is a social
networking community built especially for enthusiasts of that coppery, distilled beverage.
The site has many of the features you’d expect to find in a social network—member registration, profiles, “buddies,”
activity streams. And there are tie-ins to existing networks as well. Member profiles, for instance, can incorporate Twitter
streams, and bottles of whisky can be “liked” via Facebook. But most of what makes this community work is totally unique
and hinges on its subject matter. Members can “follow” particular whiskies, review and rate specific bottles, and add
bottles to their personal whisky cabinet or wishlist on the site. On top of that, there is an active discussion board (“The
Whisky Wall”), a blog, an events section, and an impressive online whisky magazine called Connosr Distilled.

Points of Interest
Connoisseurs of any kind tend to be obsessed with details, and this enthusiasts’ social network revolves around several
quite specialized kinds of web content. Every bottle of whisky, for example, comes from a specific distillery, has a
particular water source and bottler, an age, an alcohol-by-volume ratio, and so on. Whisky reviews point to specific
bottles, and capture unique characteristics like the whisky’s color and the reviewer’s overall rating of the bottle (Figure 29).

Figure 2-10

[0210.png]

This is a social network, though, and participation above all is the driving force. The site makes heavy use of Symphony’s
ability to power unique interactions and user journeys by allowing all kinds of content to be submitted to the system from
the front end. From the discussions on The Whisky Wall to the site’s thousand-plus reviews and its member profiles and
whisky cabinets, Symphony is helping the site’s developers fuel avid participation among its thousands of members.

Developer’s Thoughts
[Waiting for developer quote]

Summary
In this chapter, we’ve toured a handful of Symphony-powered websites and web applications in the hopes of
demonstrating the breadth of the system’s capabilities. We looked in particular at five different types of Symphony
projects: a personal site, a web/mobile app, a publication site, a business site, and a social network. There are many
other worthy candidates we might have explored—like the high-demand media and contest sites that have been
developed for clients like BBC and Channel 4, or a software community like the Symphony website itself—but we’ll save
some of these examples for other parts of the book.
In the meantime, you’re probably itching to just roll up your sleeves already and start exploring the system. Let’s go get
you started.

Chapter 3: Getting Started
It doesn’t take very much to get Symphony up and running. In fact, if you’re already comfortable with basic server-related
tasks, five minutes should be about all you need (not including time spent reading this chapter, of course). All you have to
do is prepare the server (by uploading Symphony and creating a database) and then run the installer. That's it.
Of course, this process might involve a little lead time depending on how much you already know about servers and
databases and the like. Whatever your knowledge level, though, this chapter will get you up to speed quickly and then
walk you through the setup and installation process step-by-step. If you get stuck anywhere along the way, I’ll also let you
know where you can look for help.
Because I don't know how much you know, we’ll take a sort of “choose your own adventure” approach here. If you’re a
total beginner, just read the entire chapter straight through. We’ll start by stepping back to make sure you’ve got a basic
understanding of how Symphony works before getting into some of the more technical installation details. If you’ve
worked with web software before but are still a little green when it comes to things like server and database
configurations, then skip ahead to “Knowing What You Need” and read on from there—we’ll help you get set up. Finally,
those of you who know everything there is to know about servers and databases and even version control can just skim
the “Requirements Summary” and then jump ahead to “Preparing the Installation.”
Alright, so do you know where you’re going? Good. I’ll meet you there—just need to grab another cup of coffee first...

Getting the Lay of the Land
If you're still fairly new to the world of web software, there are a handful of concepts you should be familiar with before we
move on. This section will give you a crash course, and even if you don't fully grasp all the details right away, you'll at
least have a better idea of what's going on during the installation process.

How Symphony Works
Symphony, as you know, is a web application—a piece of software that runs on a web server. When someone visits a
URL that points to a Symphony-powered site, the web server receives their request and passes it to Symphony. Based on
how it's been set up, Symphony figures out what it's supposed to do with that request and, when it's finished, sends a
response back to the user (Figure 3-1).

Figure 3-1

[0301.png]

More often than not, these requests involve content. Either someone wants to get content from your site (like a visitor
trying to read your article), or someone wants to post content to your site (like your ex leaving a snarky comment about
your eating habits). In either of those cases, while processing the request, Symphony communicates with an underlying
database, in which all its content is stored.
So, essentially, Symphony is sitting on a server and handling various kinds of interactions between content stored on the
server and people who want to use that content. There's a lot more to it than this, of course, but we've got a dozen or so
chapters to cover the details more thoroughly. For now, it's enough just to have this rough overview of how Symphony
works. Now let's review some of the other concepts we've introduced in case they're new to you.

Web Servers
A web server, put very simply, is a computer equipped with software that allows it to respond to web requests. This can be
any kind of computer, from the laptop you have at home to the sleek, powerful machines that commercial web hosting
companies use. Of course, when you've got a website that you actually want to share with the world, you'll use the latter.
But most developers actually work with a combination of the two—they set up a local server (server software running on
their own computer) to build and test their sites, and then push to a remotely hosted server when their work is ready to
see the light of day.
Note
I highly recommend setting up a web server locally on your own computer, both for the purposes of this book and
for web development work in general. You'll be able to work faster and troubleshoot more easily. Later in this
chapter, after we discuss Symphony's server requirements, I'll provide some pointers on getting this set up.

Server Environments
Web server software is designed to handle requests and responses, but the applications that run on these servers have
to do all kinds of other stuff too—they need to run code, store and retrieve data, and so on. So a server has to be
configured to provide web applications with access to all kinds of other things, from programming language libraries to
software packages to databases. The sum of all this—the web server software and everything it provides access to—is
referred to as the server environment. Like animals and their habitats, web applications require specific kinds of
environments in order to function.
Note

Know Thy Server Environment
There are a lot of variables in a server environment: what software packages and libraries are available, what
operating system is powering the machine, what versions of these things you're using and how each has been

configured... Taken together, these variables can account for significant differences from one server environment to
the next. Knowing the details of your server environment can save you a lot of time while troubleshooting, because
often it's in these differences that your problems will lie.

Databases
For most web applications, Symphony included, databases are a necessary part of the server environment. They provide
an organized and efficient way to store and retrieve massive amounts of complex data. Database software usually runs
alongside web server software, allowing web applications to connect and query their databases as needed.

Summary
I hope that reviewing these key concepts will make it easier for you to follow along with the rest of this chapter. If you find
any of the above unclear or confusing, though, it's probably a good idea to do a little more basic research on your own
before continuing. I'll do my best to fill in the gaps, but if you're going to be working with Symphony, you'll want to have a
pretty good handle on this stuff beforehand.
Note
For more information on servers, databases, and other web technologies, try:
How Web Servers Work: http://computer.howstuffworks.com/web-server.htm
Google Code University: http://code.google.com/edu
W3 Schools Tutorials: www.w3schools.com/
Nettuts Plus Basix: http://net.tutsplus.com/tag/basix/
Once you feel comfortable enough to begin getting into server environment details, read on.

Knowing What You Need
It doesn't take very much to run Symphony, and most commercial hosts easily meet the system's requirements.

Server Requirements
The first thing you'll need, of course, is a web server. Symphony requires Apache or Litespeed (though it's worth noting
that people have had success run-ning Symphony on other kinds of servers as well, like NGINX and even Micro-soft's
IIS). Whatever server software you use, it'll need to be able to rewrite URLs, so Apache's mod_rewrite (or whatever your
server's equivalent is) will have to be enabled.
Symphony is written in PHP, so your server environment will need to have PHP 5.2 or above installed in order to run it. In
addition, your build of PHP will have to have XML and XSLT support enabled because, as we've seen, Symphony leans
on these technologies heavily. Both extensions are already included with PHP, but while the LibXML extension is
enabled by default, the XSL extension needs to be enabled explicitly. Again, most commercial hosts have this turned on,
but if you're setting up a local server, you'll have to remember to activate the XSL extension yourself.
Finally, Symphony stores its content in a MySQL database. MySQL is one of the most widely used database systems
available and you'd be hard-pressed to find a web host that doesn't support it. You'll want to have a recent version,
ideally, but Symphony can work with versions as far back as MySQL 4.1.
That's all it takes. I’m not kidding.

Helpful PHP Extensions
Although this is all that's required to run Symphony, there are a few additional PHP extensions that are helpful to have
enabled.
One of Symphony's core extensions, which we mentioned in Chapter 1, enables you to zip up a Symphony build into an
installable package, like your own custom CMS. In order to take advantage of this functionality, though, PHP's Zip
extension needs to be enabled on your server. This is fairly common, but if you're setting up your own environment, you'll
need to remember to enable it yourself.
Another core extension, one we've also mentioned, enables the system to process and manipulate images on-the-fly,
which can save designers lots of time and headaches. This functionality requires that the GD library is installed and
enabled. Again, this shouldn't be difficult to find on commercial hosts, but make sure you enable it if you’re setting up your
own server.
Note

Enabling PHP Extensions
When you're using a commercial host and a required or recommended PHP ex-tension is not enabled, a simple
support request is often enough to get them to enable it for you. The extensions used by Symphony are common
enough that, if your web host is not willing to switch them on, you're probably better off hosting your site elsewhere.
When you're setting up your own server, you'll have to take care of stuff like this yourself. Most Linux distributions make
this easy—you just install the extension in your software package manager. To enable the XSL extension on Ubuntu, for
example, you just install the php5-xsl package in the software center (or run sudo apt-get install php5-xsl) and you're all
set. For Windows, you can actually download a PHP installer from http://php.net that allows you to select your extensions
during setup. Mac users aren't as lucky, I’m afraid, but as we'll see later in this chapter, there are some helpful tools for
setting up server environments on OS X and Windows that make all of this a bit easier.

Requirements Summary
An Apache or Litespeed web server, with mod_rewrite module or equivalent
PHP 5.2 or above, with the LibXML and XSL extensions enabled

MySQL 4.1 or above
Note

Setting up your own server
Walking you through the process of setting up and configuring a server is well beyond the scope of this modest
book, but if you're going to take my advice and set up a development server on your own computer, I want to get
you pointed in the right direction.
Linux users should be able to use their package manager to install Apache 2, MySQL 5, and PHP 5 and its extensions
(along with phpMyAdmin or whatever other tools you need). You’ll have to do a little bit of configuration, but it's fairly easy
to find tutorials for every major Linux distribution on how to configure a LAMP (Linux, Apache, MySQL, PHP) stack.
Mac users can try to use OS X's built-in server, but you'll have to install MySQL yourself, and you'll have to do some heavy
lifting to enable certain PHP extensions. For these reasons, an easier route might be to install a full-stack solution like
MAMP (http://mamp.info), or to use Macports (http://macports.org) to set up your server environment.
Windows users can download dedicated installers for each element of their server stack—Apache, MySQL, and PHP.
You might actually find it easier, though, to just use full-stack tools like Wampserver (http://wampserver.com) or XAMPP
(http://apachefriends.org/en/xampp.html).
Whatever route you choose, somewhere along the way you'll have to set up a root MySQL user. Be sure to note the
username and password, because you'll need them later in the installation process.

Preparing the Installation
Once you're sure you've got all the requirements met, you need to make a few decisions about how and where you're
going to install.

Decisions, Decisions
Local Versus Hosted
The first thing you need to decide is where you're going to install Symphony. For production sites, of course, you'll use a
web host. But for development and testing, and certainly for the purposes of this book, I recommend you take the extra
time to set up a local server environment on your own computer (if you don't already have one). It'll make things much
easier for you in the long run. I provided some pointers in the last section to get you started.
If you do choose to install on a remote server, there are a few things you should be aware of.
If you need to transfer files from your computer to the server, you’ll need an FTP client. Thankfully, there are lots of free
FTP clients available for all the major operating systems—the cross-platform Filezilla, Cyberduck on Mac, SmartFTP on
Windows, gFTP on Linux, and many others. If you need to execute commands using the command line, you’ll need
secure shell (SSH) access to your server, which isn’t always available in shared hosting environments.

Package Versus Git
The second decision you need to make is how to get Symphony, and how to get it onto your server.
If you’ve used other web-based software before, you're probably accustomed to package-based installations. This
method simply entails loading the contents of a software package onto your server (usually with an FTP client if you’re
uploading to a remote server). The benefits of package-based installations are that they're usually easier for beginners
and they don’t introduce any additional server requirements. Unfortunately, installing via package also means you’ll have
to re-download and replace package files whenever you update Symphony.
Your other option is to use Git. Git is a popular version control system that is used to manage Symphony’s codebase.
Using Git to install Symphony only takes a few commands, and has the added benefit of keeping your installation linked
to the official repository (which makes updating Symphony a breeze). To use this method, though, your server needs to
have Git enabled, and you need command line access (usually via SSH on remote servers). If you’re comfortable with Git,
or at least willing to learn, using it to manage your Symphony installation can be very helpful in the long-run. If in doubt,
though, or if you're not sure whether your server has Git installed, just go ahead with a package-based installation for
now.

Clean System Versus Starter Package
Finally, whenever you install Symphony you have the option to start with a completely clean system—with no content or
front-end setup at all—or to use one of several pre-configured starter packages. For the purposes of this book, you'll need
to go with the former, a completely clean install, so you can see what it's like to build out a Symphony site bit-by-bit. But
when you're working on your own projects, starter packages can be a helpful way to bootstrap the development process.

Getting Symphony onto Your Server
Now that you’ve decided on an installation method, let’s get Symphony onto your server. Follow the set of instructions
that corresponds to the installation method you’ve chosen. The first two are for performing a package-based install—one
for those who’d like to use a file browser or FTP client, and one for those who’d like to use the command line. The third
set is for those who’ve opted to perform a Git-based install.

Using a .Zip Package and a File Browser/FTP Client
1. Grab the current release package from http://symphony-cms.com/download/releases/current/ and save it to a local

directory.
2. Extract the package.
3. Optional. When starting with a completely clean system (which we will be for this book), you should delete the
workspace/ directory.
4. Move the contents of the extracted directory to the desired location on your server. Note that you don’t want to
include the package directory itself (the one named

symphony-n.n.n

where

n.n.n

is the version number); you only

want to include its contents. In other words, you want the index.php file right in the directory where you want to run
Symphony.
5. Use your file browser or FTP client to temporarily set permissions on the root directory (the one you just installed to)
and the

symphony/

directory to

777

directory to

777

(read, write, and execute for all). Then set permissions on the

workspace/

and tell your client to apply the changes recursively (to all subfolders). Don't worry, we’ll undo this

step and tighten up permissions after installing.

Using a .Zip Package and the Command Line
1. cd into the directory where you’d like to install Symphony (usually the server’s web root).
2. Execute one of the following commands, depending on whether your server supports wget or curl:

wget http://symphony-cms.com/download/releases/current && unzip symphony-n.n.n.zip && rm symphony-n.n.n.zip && mv symphony-n.n.n/* . && rm
curl -L http://symphony-cms.com/download/releases/current > symphony.zip && unzip symphony.zip && rm symphony.zip && mv symphony-n.n.n/*

Where

n.n.n

is the version of Symphony you're installing.

3. Optional. When starting with a completely clean system (which we are for this book), you should delete the
workspace/ directory:

rm -R workspace

4. Set temporary permissions for the install script:

chmod 777 symphony .
chmod -R 777 workspace

Don't worry. We’ll undo this step and tighten up permissions after installing.

Using Git
1. cd into parent directory of the directory where you’d like to install Symphony (for example, if you’re installing into your
server’s root at public/html, you want to cd into public/).
2. If the directory you want to install into exists, you have two options: A) Make sure you’ve safely backed up its contents
and emptied it, and then remove the directory (in the example above, you’d execute the command rmdir html). B) If
there are contents inside it that you cannot delete, you can clone the repository into a subdirectory, and then move all
the files and directories (including the hidden .git directory) back up into the main directory.
3. Clone the Symphony Git repository using the following command:
git clone git://github.com/symphonycms/symphony-3.git directory
Where directory is the name of the directory into which you’d like to install Symphony. For example, if you’re
installing to your server’s web root at public/html, you’ll want to use html in the above command.
4. cd into your installation directory:
cd directory

Where directory is the name of the directory into which you just cloned the repo
5. Grab the default extensions:
git submodule init git submodule update
6. Optional. If you’ve decided to include a starter package rather than start with a clean system, clone the package into
your workspace directory:
git clone git://package-git-url workspace
Where package-git-url is the location of the starter package’s Git repository
7. Set temporary permissions for the install script:
chmod 777 symphony . chmod -R 777 workspace
Don't worry. We’ll undo this step and tighten up permissions after installing.
Note

Examining your server environment
At this stage, if you have any doubts or questions about your server environment, you can use the Symphony
installer’s ?info function to see the output of phpinfo() (a PHP function that displays details about your server
environment and configurations). You can access this by visiting http://yourdomain.com/install?info in your
browser.
If you have any trouble during the installation itself, it’d be a good idea to note the output of this function so you can
include your server details when asking for help.

Creating a Database
Creating a database for Symphony to use is a fairly simple step, but in order to proceed you’ll need to know your MySQL
username and password. If you're installing on a local server, you will have created these yourself. If you're installing on a
web host, they may have been assigned by your hosting provider, or you may have created them using your server’s
control panel.
You'll probably have several different options for creating a MySQL data-base, including phpMyAdmin, the command line
MySQL client, and web host control panels. The latter are usually fairly straightforward and well-documented, so I'll just
cover the former two here.

Using phpMyAdmin
1. Log into your phpMyAdmin interface.
2. You’ll see a field on the home page labeled “Create new database.” En-ter a database name (note this for the next
step), and from the “Collation” dropdown, select

utf8_unicode_ci

.

3. Click the “Create” button.

Using the Command Line MySQL Client
1. Connect to the MySQL client:
mysql -u username -p
Replace username with your MySQL username. You’ll be prompted for your MySQL password. Enter it.
2. In the MySQL prompt (mysql>), type:

CREATE DATABASE db_name CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Be sure to replace

db_name

with a suitable database name, like symphony. You should see a message telling you

that the query was executed. Type EXIT.

Running the Installer
All the files are in place, your database is ready, and all that remains is to run the installer. This step is simple. Point your
browser to the Symphony install script (http://yourdomain.com/install/). You’ll be presented with a nice graphical installer.
Completing it should be fairly straightforward, but if there’s anything you’re unsure about, see the section-by-section
breakdown below.

Your Website
Figure 3-2

[0302.png]

Website Name: Enter a name for your website.

Your Server
Figure 3-3

[0303.png]

Root Path: This should be automatically detected and pre-filled for you.
File Permissions: Select the desired permissions settings for files created by the system.
Directory Permissions: Select the desired permissions settings for directories created by the system.

Your Locale
Figure 3-4

[0304.png]

Region: Select the region of the world your website is based in.
Date Format: Select a date format to be used in the admin interface.
Time Format: Select a time format to be used in the admin interface.

Your Database
Figure 3-5

[0305.png]

Database: Enter the name of the database you created earlier.
Username: Enter your MySQL username.
Password: Enter your MySQL password.
Host: Enter the MySQL host name, if applicable. Otherwise, leave the default value (localhost).
Port: Enter the MySQL port, if applicable. Otherwise, leave the default value (3306).
Table Prefix: Enter the desired table prefix, if applicable. Otherwise, leave the default value (sym_).
Use compatibility mode: Tick this box if your host doesn’t allow character sets and collations to be specified for
tables. Otherwise, leave unticked.

Your First User
Figure 3-6

[0306.png]

Username: Enter the username you’d like to use to access Symphony’s admin interface.
Password (and Confirm Password): Enter the password you’d like to use to access Symphony’s admin interface.
First Name: Enter your given name.
Last Name: Enter your family name or surname.

Email Address: Enter your email address.

Install Symphony
Figure 3-7

[0307.png]

Click the button!
Congratulations, you’ve just installed Symphony! Before you jump out of your chair for a celebratory dance, we’ve got a
little cleaning up to do:
First, delete the install script (install.php). If you’re using a file browser or an FTP client to manage your files, just select
the file and delete it. If you used the command line, cd to the root of your Symphony installation and do:

rm install.php

Second, be sure to tighten up the folder permissions you adjusted during setup. Exact settings will depend on your server
environment, but the permissions on your root directory and your symphony/ directory should be fairly restrictive (try
something like 755). Then set manifest/ and workspace/ to 775 (make the workspace/ permissions recursive, so they
apply to its subdirectories as well).

xchmod 755 symphony .
chmod -R 775 manifest
chmod -R 775 workspace

Now you can dance (try not to embarrass yourself).

What to do when you need help
Everybody makes mistakes—some of us more than others. If my guidance in this chapter has somehow led you astray, or
I've forgotten to account for your specific server environment or some other peculiar circumstance, don't fret. When it
comes to getting the answers you need, this little tome is just the tip of a very large (and welcoming) iceberg. First and
foremost, you'll want to consult the errata for this book (URL?). If I've made any glaring errors or omissions, you'll find
them listed there (alongside some text exonerating me and telling you who's really to blame). You'll also want to
familiarize yourself with Symphony's official documentation (http://symphony-cms.com/learn/). The docs address many
specific or advanced scenarios that are beyond the scope of this book. And when you've got a problem or question that
you can't find the answer to, there are always real live people willing to help.

Reaching out to the Symphony community
By far the fastest and most reliable way to seek help is on the Symphony forum (http://symphony-cms.com/discuss/).
There are lots of folks around who know the ins and outs of Symphony as well as I do (or better), and the forum is where
you'll find them. Bear in mind that there's a good chance your question has already been asked and answered before, so
try do a thorough search before posting. But when you do have something you need help with, ask away. I don't think
you'll find a more friendly or helpful group of people anywhere. Many Symphonists are also on Twitter, and if you can
connect with the community there using the #symphonycms hashtag.

Reaching out to the Symphony team
As amazing as our community is, there may be times when you need to contact the Symphony team directly—for instance
when you're interested in commercial-level support, or when you want to offer us all-expenses-paid trips to places like
Bali and Saint-Tropez. In these sorts of scenarios, the best way to reach us is via the contact form on the Symphony
website (http://symphony-cms.com/get-support/contact/). You can also email us directly ([email protected]) or
give us a shout on Twitter (@symphonycms). However you reach out, we'll do our best to get back to you as quickly as
possible.

Summary: Rolling up your sleeves
In this chapter, we've reviewed what it takes to get Symphony up and running, and we've walked through the setup and
installation process step-by-step. We've also taken a moment to talk about what you should do if you run into any
problems.
With all that out of the way, and with Symphony purring along happily on your server, it's time to log in to your admin
interface (http://yourdomain.com/symphony/) and have a look around. The real fun is about to begin…

Chapter 4: Symphony Anatomy
What’s In This Chapter
Functional overview of the system
Tour of the admin interface
Symphony file structure
Differences between Symphony 2 and 3
Now that you’ve got Symphony installed, you face a familiar, ages-old dilemma. Do you continue reading along
studiously? Or do you roll up your sleeves and venture off to explore this new territory on your own, armed with nothing
but your wits, your keyboard, and what I can only assume is a childlike sense of wonderment? After all, you’ve just logged
in to Symphony’s back end, and as you can see in Figure 4-1, the cleanliness, the simple elegance, it’s all… strangely
alluring.

Figure 4-1

[f0401.png]

So if the urge to poke around a bit is too much for you to bear, feel free to do so. I’ll wait here.
Whether you decided to explore on your own or not, it won’t be long before you realize that you can save yourself a lot of
time if you get to know the lay of the land first. This may seem like a tedious step, but then again it’s always better to have
a map in your pocket than not, right? Well this chapter is that map, your bird’s-eye view on all things Symphony.
We’ll begin with a cursory glance at the admin interface, or back end, just to give you an initial point of reference—
something to anchor your mind as we batter it with new ideas and information. Then we’ll set about exploring the system
from three angles:
1. For starters, we'll review what the system looks like functionally—the working elements that allow you to define,
manage, and deliver content.
2. Then, we'll dive in visually to explore Symphony's admin interface in detail.
3. Finally, we'll have a look at how Symphony is represented physically on your server—the directories and files that
comprise it and what they do.
These three overviews should provide you with a strong foundation for the rest of the book—whether you’re a total noob
or an experienced web developer, a designer or a programmer, a visual thinker or a conceptual one, or none of these
things.

Dipping Your Toes In
Symphony’s back end is deceptively simple. Gone are the days (I hope) when we assumed that the most powerful
interfaces had to be the most complex. When you look at Symphony, know this: there’s a whole lot of power in that
minimalist package.
Let’s quickly run through what you see when you log in. The dark header at the top displays your website’s name, the
name of the currently logged-in user (which is you, unless you’re impersonating someone else and learning valuable
web development skills on their behalf, which would be weird), and a logout button.
Beneath the header is a gray navigation menu. This is how you’ll move around Symphony’s back end to manage your
website and its content. Figure 4-2 shows a fully-expanded sample menu:

Figure 4-2

[f0402.png]

The left side of the navigation menu is where you manage all the content that will power your website—be it blog posts,
portfolio items, products… whatever. Because Symphony allows you to define those content types yourself, this part of
the menu will vary from site to site. That’s why I referred to the image above as a sample menu. The right side of the
navigation menu is where you manage all the elements that structure your website and its behavior (its “blueprints,” if you
will), and anything else related to administering the system. The two submenus you see here—Blueprints and System—
form the backbone of Symphony’s admin interface. Everything about your website, from the shape of its content and
interactions to its URL schema and design, will be defined and determined here. Let’s quickly walk through those
submenus now. If you’re looking at the Symphony admin interface in your browser as you read this, hover over the
Blueprints item. Otherwise, you can refer back to Figure 4-2. Either way, you see the following submenu items under
Blueprints:
Views are used to build out your website’s front end. They determine where visitors can go to access your website,
and what they’ll see when they get there.
Sections are used to define and outline the types of content you’ll be managing.
Data Sources are used to filter and channel content to your front end.
Events are used to capture and save input submitted from the front end.
Utilities are used to manage reusable bits of template code.
Now, hover over the System menu item (or glance at the System submenu in Figure 4-2). It contains the following items:
Users are accounts that have access to the admin interface.
Settings allows you to adjust various system settings, such as date and language preferences.
Extensions can add important functionality to your system, and can be enabled, disabled, and uninstalled here.
Don’t worry if all of this is a bit of a blur at the moment. What’s important is that your mind has something visual to anchor
it as we move on to discuss all of these new concepts in greater detail.

The Form of Symphony’s Function
The first thing you need to know about Symphony is how it works. Just as we study areas of the human anatomy based
on what they do—circulate blood, digest food, control breathing—likewise Symphony’s anatomy is more easily
understood when broken down into functional groupings.
What would those look like? Well, in the very broadest sense, creating and managing websites with Symphony boils
down to three basic functions:
1. Defining and managing various kinds of web content
2. Setting up interfaces that enable visitors to interact with your site
3. Crafting a system of templates to present things to your visitors
You can think of these as functional “layers.” At the core of your website is a content layer, where all of your data is
catalogued and stored. If you were publishing blog posts on your website, for example, they’d be defined and stored in
the content layer. An interaction layer sits above that, responding to visitors' requests and delivering whatever it is that
they're looking for. So if your visitor tries to view a single blog post, or to browse through your blog archive, those things
would be handled by the interaction layer. Finally, on the surface, a presentation layer takes the data generated by the
interaction and formats it for display or consumption.
Note
Programmers might recognize this as a reflection of the classic Model-View-Controller (MVC) paradigm. Widely
regarded as a best practice in programming, MVC emphasizes separation between an application's data logic (the
model layer), its presentation logic (the view layer), and its interaction logic (the controller layer), resulting in more
flexible code that is easier to extend and maintain. Symphony is designed to allow its users to take advantage of
this design pattern and reap these same benefits when building websites.
This structure of distinct functional layers is what makes Symphony so incredibly flexible, because each “layer” is actually
comprised of a set of independent, fully-configurable components, as shown in Figure 4-3. These modular building
blocks can be molded and assembled in an infinite number of ways, making it possible to craft highly specialized and
efficient systems.

Figure 4-3

[f0403.png]

Let’s take a look at how Symphony’s internal structure maps onto these broader, functional layers:
The content layer consists of sections and fields. Together, these enable you to define very precisely what kinds of
content you'll be managing and how you'll capture and store it.
The interaction layer consists of views, data sources, and events. These allow you to specify what requests your site
will respond to (i.e. its URL schema), what it will do with them, and what data it will send back.
The presentation layer consists of view templates and utilities. These are used to format the data your site delivers
to the user.
Whenever a visitor lands on your website, these three layers work together in harmony:
1. A view responds to the visitor's request, kicking into action any data sources and events that are attached to it.
2. The data sources then fetch content from your sections (or from elsewhere, for example an RSS feed), and send it
back to the view.
3. The view then uses its template (and any attached utilities) to format the data and display it.
You can see a flowchart of this process in Figure 4-4:

Figure 4-4

[f0404.png]

Now let’s take a quick look at each of these layers and their components in turn.

The Content Layer
In Symphony, you define the content you’d like to manage using sections and fields. Sections are like containers for your
content, and fields determine their shape. Figure 4-5 shows the basic structure of Symphony’s content layer.

Figure 4-5

[f0405.png]

As you can see, every section is comprised of one or more fields, and each individual piece of content (each entry in a
section) is made up of data corresponding to those fields.
Let’s say you’re using Symphony to launch a web-based magazine. You’d start by asking yourself, “What kinds of content
do I need to be able to create and manage?” Things like issues, articles, and authors might come to mind. These would
be your sections. Then, for each of these, you’d ask, “What do these things look like? What pieces of data do they
contain?” For something like issues, your answer might be: each issue will have a title, an issue number, a description, a
cover image… These would be your fields. Having defined that structure, every new issue you created—or, in Symphony
terms, each new entry in the issues section—would be made up of these same fields.
Note
If you've ever worked with databases, sections would be analogous to tables, fields to columns, and each entry
would be a row. For object-oriented programmers, sections would be like classes and fields like class properties,
and each entry would be an object instance.
As we’ve mentioned several times, Symphony gives you a completely blank slate when it comes to your content layer; it
doesn't make any assumptions at all. Even if you download a copy of Symphony that has some default sections set up,
there’s nothing stopping you from deleting all of them and starting fresh. With sections and fields, you can create and
manage any kind of content you like—from articles and blog posts to… yarns and zoo animals.
There’s a bit more to all of this, of course. For example, you’ll often need to create relationships among your sections (e.g.
giving your magazine articles an author and placing them in a particular issue). You’ll also need to change the structure
of your sections from time to time, even after they’ve been created and populated with entries. And there are many
different types of fields, each with its own configuration options and its own ways of storing and retrieving data. But we’ll
get into all that in Chapter 5. First, let’s talk about what Symphony allows you to do with your content once you’ve got
some.

The Interaction Layer
There’s a whole lot that can happen in your website’s interaction layer. Let’s say, using our magazine example from
above, that you want to provide your visitors with archives of your past issues and articles. What URL do they visit? What
content will they see? How is it sorted and organized? How can it be browsed? All of this is determined in the interaction
layer.
Symphony provides several finely tuned components to handle these sorts of tasks, as you can see in Figure 4-6:

Figure 4-6

[f0406.png]

It starts on the front end, with views. In Symphony, you use views to build an interface that will respond to visitors’ URL
requests (whether they come from a web browser or via some other sort of client application like a feed reader). In other
words, views are the answer to the question, “Where do I want my visitors to be able to go, and what do I want to show
them when they get there?”
Each view is configured to respond to a certain request (or set of requests), at which point it executes any data sources
and events that are attached to it (more on that in a moment). The data sources (and sometimes events) will return a

bunch of content, which the view will then template for display in the browser (or for consumption in some other format).
So the view is a middleman of sorts, like a waiter taking and delivering orders in a restaurant. Data sources, in that
scenario, would be the dishes. They may have a very technical-sounding name, but they are exactly what you’d think:
sources of data for a view. Data sources can grab content from all sorts of places (your sections, other websites, your
system’s user info), and can have any number of conditions, filters, and other directives specified. Every data source, in
other words, has its own unique recipe for delivering content to your front end.
Note
If you’ve ever worked with databases, you’ll probably find it helpful to think of data sources as being akin to
queries. You’re just asking Symphony to fetch you a set of data from a particular source that meets certain
requirements, and to limit and sort the results as requested.
This may sound a bit overwhelming, especially if you’re accustomed to using systems that make these kinds of decisions
for you, but hopefully by now you’re beginning to see some of the tremendous potential inherent in this structure.
Because Symphony doesn’t make assumptions about how you want your visitors to interact with your content, you’re free
to set up your views and data sources to do anything you’d like. Want your visitors to be able to go to
http://yoursite.com/archive and see a reverse-chronological list of your magazine’s issues, grouped by year? No problem.
Rather have them grouped thematically and then sorted by issue? You can do that too. Want to serve an RSS feed at that
URL instead? Again, easy as pie.
Events are the flip side of the interactive coin. If data sources enable content to be fetched and displayed on the front end,
events allow data submitted from the front end to be saved into your sections. If your magazine permitted comments to be
submitted by visitors, for instance, an event would do the job. Member-driven Symphony websites like Connosr.com and
the Symphony website itself rely heavily on events because users can submit everything from forum posts and reviews to
extension packages, all from the front end.
As you might suspect, there’s a lot more to all of this, and at the moment you’ve probably got more questions than you
know what to do with. Don’t worry. We’ll have an in-depth look at views in Chapter 6, and then at all the different kinds of
data sources and events—and the options available for each—in Chapter 7. For now, if you’ve got a rough sense of how
the interaction layer works in Symphony, you’re in good shape.

The Presentation Layer
The presentation layer, by comparison, is fairly straightforward, as you can see in Figure 4-7:

Figure 4-7

[f0407.png]

Every view in Symphony has a corresponding view template. Because the data that’s delivered to your views is raw XML,
what the view template needs to do is transform that XML into a format that your visitors can use. Most often, it’s turned
into (X)HTML for display in a browser, but your view templates can actually produce almost any format at all—RSS or
Atom-flavored XML, plain text, comma-separated values (CSV), PDFs… even JavaScript or CSS.
View templates can accomplish this sorcery because they’re written in XSLT (Extensible Stylesheet Language
Transformations), which you’ll recall is a templating language developed precisely for the purpose of transforming XML.
Fortuitous, no? Rather than inventing some system of arcane pseudo-tags, Symphony’s presentation layer allows you to
leverage a widely-used, powerful, open standard.
Among the many, many benefits of XSLT is that it makes it easy for you to organize and reuse code. Programmers know
how important it can be to pull out snippets of code that perform common tasks and to reuse them. And designers know
how important it is to produce markup that’s consistent and easy to maintain. Utilities are independent XSLT stylesheets
that can be dynamically included by view templates and thus reused, remixed, and recycled anywhere on your website.
Perhaps the most common use of utilities is the creation of a master layout stylesheet, responsible for outputting all the
markup that will be used universally throughout your front end—header, navigation, and footer, for example. Another
common usage is for utilities to contain snippets of template code that can be used over and over in many different

contexts. Let’s say, for instance, that you wanted your magazine website to make heavy use of Microformats.1 You could
create a Microformats utility that would used to output hCalendars wherever you were displaying a date, hCards
wherever you were displaying author profiles, and so on.
Though fairly simple conceptually, Symphony’s presentation layer is remarkably powerful thanks to the capabilities it
inherits from XSLT. That said, for many people, it’s also the toughest part of the Symphony learning curve. Have no fear,
though, because Chapter 8 is going to tell you everything you need to know about templating in Symphony, and may
even turn you into an XSLT master of unparalleled guile and charm (if not actual skill).
1

. Microformats are a set of simple, open formats that allow you to embed meaningful data in markup that otherwise

couldn’t convey it (like HTML). See http://microformats.org/. ↩

Summary: Symphony’s Functional Anatomy
In these brief overviews of Symphony’s three functional layers, we’ve learned the following:
Sections and fields allow you to define the various kinds of content that you’ll be managing.
Views allow you to set up a front end for your website’s visitors.
Data sources allow you create recipes for delivering content to your visitors.
Events allow you to accept input from your visitors.
View templates and utilities allow you to format the content you present to your visitors in any way you like.
We’ll cover each of these elements in much greater depth in Chapters 5 through 8.

The Admin Interface
Having taken the time to familiarize yourself with Symphony’s basic moving pieces, you’re now ready for a more
meaningful walkthrough of the admin interface we looked at so briefly earlier. Assuming you installed Symphony on your
computer or on a hosted server in Chapter 3, open the admin interface in your browser so you can follow along.

Composition and Layout
Figure 4-8 shows a breakdown of Symphony’s back-end layout:

Figure 4-8

[f0408.png]

The admin interface is designed to be easy to navigate and easy to use. Wherever you happen to be in Symphony’s back
end, and whatever you happen to be doing, you’ll see the same basic layout. A title bar (1) identifies the project and the
current user. A simple, horizontal menu (2) allows you to navigate through the back end. And the main content area (3) is
used to display the various tables and forms that you’ll use to manage your website and its content.
Functionally speaking, the admin interface provides access to three basic areas. We’ll review those quickly now.

Content
The content area, on the left side of the navigation menu, can consist of any number of submenus that allow you to
manage your content entries. When you create a section, you assign it to a navigation group. Each navigation group
becomes a submenu in the content area, and each Section belonging to that group becomes an item in that submenu
(unless it’s hidden, which we’ll discuss in Chapter 5).
Confused? Well let’s go back to our magazine example. Imagine you were to create sections for issues and articles, and
assign both sections to a navigation group called “Content.” Then imagine you created three more sections—writers,
photographers, and editors—and assigned each of them to a navigation group called “Contributors.” What you’d end up
with is a menu that looked like Figure 4-9:

Figure 4-9

[f0409.png]

Clicking any item in one of these content submenus will take you to the index page for that section. A section’s index will
display a paginated table of all content entries in that section. So, using the example in Figure 4-9, clicking Content and
then Articles would allow you to browse all article entries in the system. Each column in the table will correspond to one
of the section’s fields (you get to decide which fields display in the table).
You’ll notice that each entry in the index table is linked. Clicking the link will bring you to the entry editor, a form that
enables you to create and edit entries. What this form looks like, of course, depends entirely on the fields you’ve added to
your section, and how you’ve chosen to lay them out. We’ll explain how all that happens in Chapter 5.
Note
The index/editor paradigm is a convention used throughout the Symphony admin interface. All of your content
sections, and all system components (like views and data sources), have indexes—where you can view all the
items in paginated tables—and editors—where you can fill out forms to create and update individual items.

Blueprints
The Blueprints submenu allows you to manage all of the functional building blocks discussed above: views, sections,
data sources, events, and utilities. Together, these determine the structure and behavior of your entire website, hence the
term blueprints. We’re going to cover each of these elements—along with the interfaces for managing them—in great
detail in Chapters 5 through 8, so for now let’s move on.

System
The System submenu contains items that allow you to customize and fine-tune your copy of Symphony. By default, it
consists of three items: Users, Settings, and Extensions.
As mentioned above, a user in Symphony is someone who has access to the system and is allowed to log in to the back
end. Going to System > Users will take you to the user index, where you’ll see your own user account and any others
you’ve created. Clicking your name will take you to the user editor, where you can adjust your user details, change your
password, and so on. We’ll discuss users in more detail in Chapter 9.
Symphony’s Settings page is a simple form that allows you to manage a few basic system configurations like your
website’s name, the default language for the admin interface, and so on. If you install any extensions that have settings of
their own, you’ll be able to manage those here as well. Symphony only exposes the most commonly used settings in the
admin interface; many more are available in a configuration file, which we’ll talk about in the next section.
The System menu is also where you’ll find the area for managing extensions. Because a central tenet of Symphony’s
philosophy is to keep the core of the system lean and efficient, extensions are a vital part of any Symphony website. Much
of the functionality that will make your website unique and useful will be provided by the rich ecosystem of extensions
built by the Symphony team and by the community. All of your field types and your data source types, for example, are
provided by extensions.
At System > Extensions, you can enable, disable, and uninstall extensions, and monitor the status of the extensions
you’re using at any given time. We’ll cover how to work with extensions more fully in Chapter 9.

Physical Footprint
Depending on how technically inclined you are, you may not spend very much time at all exploring the various directories
and files that live on your server and keep Symphony humming along smoothly. But, whether you’re doing periodic
backups, fine-tuning advanced configuration options, or troubleshooting a problem, knowing how Symphony is structured
physically could turn out to be a lifesaver someday.

Folder Structure
When you upload and install Symphony, you create on your server a hierarchy of directories and files that looks like
Figure 4-10:

Figure 4-10

[f0410.png]

Many of the files at the root of your installation are self-explanatory. The index.php file, as you might guess, is the main
switchboard for your Symphony site. All requests, front-end and back-end, are routed through it. The update.php file has
an equally obvious use: you run it when you want to update from one version of Symphony to another. When Symphony
is installed it also creates a file called .htaccess (depending on your operating system, it might be hidden from view). This
file contains server-level directives that help with routing URL requests and is a common place to look when your site
isn’t behaving as expected.
In addition to these top-level files, Symphony will create several directories. Let’s look at those now.

Extensions
This one is simple enough. It’s where your extensions live. Each individual extension has its own directory inside the
extensions/ folder. When you want to install a new extension, simply place it in this directory, and you’ll be able to enable
it from within the admin interface.
Note
Symphony auto-includes extensions by predicting their folder names based on the names of the extension classes
in PHP. If you’re ever trying to install an extension and it’s not appearing in the back-end, one of the first things to
check is that the extension’s folder is named correctly.

Install
The install/ folder contains the files necessary to run Symphony’s installer. Once you’ve successfully installed Symphony,
this folder should be removed.

The Manifest
In shipping, the manifest is a document that contains a log and description of all the cargo and passengers on board a
ship. The idea is that most of what you need to know about a ship can be gleaned from looking over its manifest.
Symphony’s manifest/ directory is named in that same spirit. Most of what you need to know about a particular installation
of Symphony can be found in the various files in its manifest.
The manifest contains your site’s cache, its configuration files, its system logs, and its temporary directory. It also contains
your extension configuration. In other words, all the system information specific to your website can be found here (as
opposed to build and content information, which can be found in the Workspace).
Inside the manifest folder is a config directory. This directory contains XML configuration files, which you can edit directly
in lieu of, or in addition to, using the Settings page in the admin interface. Many configuration options are available in
these files that are not accessible from the Symphony back end. We’ll talk more about those in Chapter 9.
Finally, whenever you’re troubleshooting problems with your Symphony installation, a logical first place to look is in

manifest/logs/. There you’ll find system logs detailing all manner of server-level events. You’ll want to have the info handy
whenever you ask for help with Symphony.
Note
If you ever want to customize Symphony’s internal templates (like the default view template XSLT, or the default
system error pages), you just need to create a directory within manifest/ called templates/ and copy into it
duplicates of the files you find in symphony/templates/. The files in manifest/ will override the default system
versions, and you customize them to your heart’s content.

The Symphony Directory
The symphony/ directory is where the core of the system is located. You shouldn’t muddle about in there, but if you know
what you’re doing and are interested in seeing how Symphony works, feel free to explore. Just note that modifying
anything in here will void all warranties, as they say.

The Workspace
The workspace/ directory contains all of your project-specific files. By default, the workspace will store data sources,
events, sections, views, and utilities. Because all of your website’s blueprints are file-based and stored in the workspace,
Symphony projects can be very elegantly version-controlled, and integrated structures can be easily shared, reused, and
remixed between websites. Symphony’s admin interface will dynamically accommodate changes to files in the
workspace, even if those changes aren’t propagated from within the back end itself.
In addition to your blueprints, you can use the workspace to store files uploaded via upload fields in your entries, and
developers will often store other assets here as well, like CSS and JavaScript files or template images. As long as the
default subdirectories are left intact, users are free to create any directory structure they like within the workspace/ folder.
Example

Common Workspace Setup
In addition to the default directories where your blueprints are stored, it’s common to have folders in your
workspace like scripts/ (for your JavaScript files), styles/ (for your CSS and related assets), and uploads/ (for files
uploaded via entry fields). It’s also fairly common to have subdirectories within uploads/ to separate each section’s
files, e.g. uploads/issues/ for your magazine’s cover images and uploads/writers/ for your authors’ profile pictures.

Differences Between Symphony 2 and Symphony 3
This book covers the current version of Symphony, version 3. But many existing Symphony users will be most familiar
with its predecessor, Symphony 2, and the majority of websites running Symphony at the time of this book’s publication
will still be powered by Symphony 2. With that in mind, it probably makes sense to review some of the key differences
between the two versions, in case you ever find yourself having to work with Symphony 2. If you don’t need to work with
Symphony 2 at all, feel free to skip ahead to the summary at the end of this chapter.

Nomenclature
In Symphony 2, views were known as pages. Pages was actually a misleading term, though, because one “page” in
Symphony could actually power an entire front-end interface that rendered any number of web “pages” to a visitor. It
turned out to be doubly confusing because most other content management systems have a “page” concept as well
wherein “pages” are containers for static content. The fact that Symphony’s use of pages went against this widespread
convention probably caused some confusion and frustration for new users, so with version 3 the term was changed to the
more appropriate views.

File Structures
In Symphony 2, sections and views were stored in the database rather than in XML files in the workspace. As a result,
version control and collaboration was much more tricky with Symphony 2.
Also, in Symphony 2, the configuration was stored in a single PHP file in manifest/, rather than two separate XML files.
Splitting the configuration into two files for version 3 makes it possible to move the database configuration to a more
secure, inaccessible location on the server.
In Symphony 2 it was not possible to override Symphony’s default internal templates as described above.

Database
Symphony 2 stored lots of structural data (section schemas, page configurations) in the database alongside actual
content. Symphony 3, on the other hand, moves that structural data into files, as described above.
Also, Symphony 3 adopts a much more meaningful table-naming schema, sym_data_section-name_field-name rather
than sym_entries_data_field-id. So where, in Symphony 2, you’d have a table called sym_entries_data_42, in Symphony
3 it’s called sym_data_articles_title. This makes working directly with the database much easier.

Extensions
Many things became extensions in Symphony 3 that were built into the core in version 2:
Field types. In Symphony 2, there were core field types, a set of 6 field types that were bundled with the core and couldn’t
be altered or removed. Additional field types could be added as extensions. In Symphony 3, though, all field types are
extensions, meaning they’re all treated equally and can be swapped and replaced at will.
Data source types. In Symphony 2, there were only five data source types. Custom data sources could be written in PHP,
and extensions could provide their own individual data sources, but it wasn’t possible to provide new types that users
could use when creating data sources. In Symphony 3, all data source types are extensions, and extensions can provide
new data source types.
Event types. In Symphony 2, there was only one event type: the section saving event. It was possible to author custom
events, but not to create other kinds of events from within the admin interface. In Symphony 3, however, it is possible for
extensions to provide additional event types.

Admin Interface

Figure 4-11 shows Symphony 2’s admin interface:

Figure 4-11

[f0411.png]

In Symphony 2, all navigation submenus were left-aligned, and Events, Data Sources, and Utilities were grouped
together on a single back-end page called “Components,” which was accessible in the Blueprints menu. In Symphony 3,
as we’ve seen, each of those is split out into its own separate index page.

Summary
We’ve taken a whirlwind tour of Symphony, inside and out, to give you a sense of the structure and scope of the system
before we start having fun and getting our hands dirty. We’ve reviewed the system’s functional anatomy, or the various
elements that it uses to enable you to create, manage, and deliver content on the web. We’ve also walked through the
back-end admin interface to give you an idea of where all the functional pieces are located and how you can find them
and work with them. We looked quickly at the files and folders that comprise Symphony on your server, and explained
what most of them do so that you know where to look when you want to back up your data or troubleshoot a problem.
Finally, we covered the key differences between Symphony 2 and Symphony 3, in case you ever find yourself needing to
work with the older version.
Now that you’ve seen the roadmap, and have a rough sense of how Symphony works, let’s go have some fun!

Chapter 5: Content
What's In This Chapter
Introducing our first Symphony project
About content modeling
Understanding content in Symphony
Working with content in Symphony
Let's build a website, shall we?
Over the course of the next few chapters, we're going to whip up a simple but functional blog. We’ll proceed slowly,
building the site one layer at a time so that along the way we can stop to elaborate on important concepts and tasks as
they arise. That means you’ll still have to stomach my long-winded explanations, but at least they’ll be broken up into
smaller doses (and you’ll get to do some fun web building in between).
The first thing you’ll need to do is tell Symphony what kinds of content you want to manage. And though you probably
already have a pretty good idea of what you expect to find in a blog (things like posts and comments, for instance), there's
more to it than just naming them. You have to figure out what they're going to look like, how they'll behave, and how you
want the system to handle them. The process of answering these sorts of questions is called “content modeling,” and it
shapes the very foundation of a content-driven website.
So we’ll start by talking a little bit about the general practice of content modeling—what it entails, how it works, and what
you'll need to look out for. Then we'll formally introduce you to all of the elements that make up Symphony's content layer,
and as we begin building your blog, you'll see firsthand what it takes to model and manage content in Symphony. By the
time we finish the chapter, you'll be comfortable defining content and working with the content layer on your own, and
your new blog will have a rock solid foundation.
Let's start with a teaser exercise.
1. Point your browser to Symphony's admin interface.
2. Wink coyly at the screen and whisper, “Hey there, sexy.” (What? I did say "teaser").
3. Navigate to Blueprints > Sections, and click the green “Create New” button. You'll see a page that looks like Figure 51.

Figure 5-1

[f0501.png]`

4. Under "Essentials," enter Blog Posts as the name and Content as the navigation group (don't worry, I'll explain this
later).
5. To the right, under "Fields," you’ll see the section fields tool. Click the “Add Field” button. A drawer will open
displaying a set of field types. Click “Text”
6. A panel will appear for configuring your new field (Figure 5-2). Just enter the Title as the name, and select "Single
Line" in the size dropdown. Leave the remaining items untouched.

Figure 5-2

[f0502.png]

7. Click “Text” again to add another text field to your section. This time, enter Body as the name, and in the size
dropdown, choose “Large Box.” Leave the remaining items untouched.
8. Click “Create Section.”
Well done. You’ve just created your first section, essentially telling Symphony that you want to manage a type of content
called “Blog Posts,” and that each of its entries should have a title and a body.

At this point, you could actually already begin creating blog posts in the system. See for yourself:
1. In the navigation menu, under "Content," click "Blog Posts."
2. You'll see an empty table, because we've not yet created any entries. Click the green "Create New" button.
3. You'll see the entry editor for your new section (Figure 5-3). Go ahead and fill in the form with some sample info.

Figure 5-3

[0503.png]

4. Save the entry, and navigate back to Content > Blog Posts. You should see the entry you just created listed there.
Easy, huh? Now, I’m sure you’ve got all kinds of great ideas on how we can make these blog posts more interesting, but
for now let's hold off until you've got a firmer grasp on how all of this actually works.

What is Content Modeling?
When a system gives you the freedom to dream up your own kinds of content, it needs to know what you want from that
content—how you want it to behave, how you want it treated. And it needs to be told in terms that it can use and
understand. You have to create a representation of that content for the system, a model, using the system's own tools and
idioms.
Take a spreadsheet, for example. You can put whatever you like into a spreadsheet—shop inventory, household chores,
contact lists—but it's all got to be organized into rows, columns, and cells. These are the basic elements of a spreadsheet,
and they determine how its data can be entered, sorted, graphed, and so on.
So let’s say, for instance, that you’re a nutritionist. You want to create a spreadsheet for your clients to help them get a
clearer idea of what they’re consuming. It will list all of the foods they eat on a regular basis, and you want them to be
able to sort that list to see, for example, which foods have the most calories, or sugar, or provide them most calcium. So
you decide that you’ll be entering food items, one per row, and that you’ll add columns for each nutritional fact you want
to capture. And just like that, you’ve modeled some content.
For our purposes, then, content modeling comprises three basic tasks:
1. identifying the types of content you want to manage
2. defining the data you want to capture for each
3. representing this information in the system
The idea is fairly simple, but it actually does take a bit of knowledge and forethought. In your nutritionist's spreadsheet, for
example, you had to already understand how spreadsheet applications work, and you needed to put some time into
figuring out what information you wanted to store about each food.
And that was a very simplistic approach. It could easily get more challenging. What if you wanted to organize foods by
type? Would you add that as a column? Make separate spreadsheets? And then what if a food could belong to more than
one type? Or have different characteristics depending on where it's from or how it’s cooked?
Nuances like these make it critical that you understand what you want to be able to achieve with your content and how
exactly the system is going to treat it once you've created it.

Understanding Content in Symphony
Thankfully, as you saw in the previous chapter, Symphony's content layer is pretty straightforward.
The various kinds of things you want to manage, be they blog posts, products, photos, food items, or whatever, are
sections. The bits of information you want to capture in each section—a blog post’s title, a product’s serial number—are
fields. Your data will come in many different shapes and sizes, so field types give you lots of choices for how to handle it.
And each individual content item—each blog post, for example—is an entry.
This granular approach means you can combine these various pieces in any way you like. You can decide not only what
kinds of content to manage and what data to capture but also how the data gets captured and stored, how it can be
interacted with, and so on. This is important because each bit of your data is going to be meaningful in its own, specific
way, and you don’t want to treat it all the same.
So what do you need to know in order to plan your blog’s content effectively? Let’s break it down piece by piece:

Sections
First up are sections, the fundamental building blocks of a Symphony website.
Sections define the content you can manage. Creating a section and adding fields to it enables you to start producing
content entries. The section, and the fields it contains, define what the entries will look like and how and where they’ll be
managed.
Sections define your publishing interfaces. For each section, Symphony creates an area in the admin interface for
managing its entries. There’s an entries index, or a table view for browsing and managing them in bulk, and an entry
editor for creating and updating individual entries. Sections are added to the navigation menu so you can access these
interfaces (unless you choose to hide the section).
Though Symphony creates each section’s entry editor view automatically, the section itself defines how it will be
structured (we’ll see how below). Obviously, the fields contained in a section determine the form elements that you see
(Figure 5-4), but you can configure the layout and organization of these elements.

Figure 5-4

[f0504.png]

Sections organize your content. All entries in the system are naturally grouped by section. Later on, when you need to
fetch content entries or process data submissions from the front end, you'll do so by section.
You can view and manage the sections you’ve created at Blueprints > Sections.

Fields
Fields do a lot of the heavy lifting for sections. It’s fields that give a section its shape, store its data, and determine its
output.
Fields capture discrete bits of data. When you’re creating an entry, you’re not just dumping its content into some abstract
container. Every entry is made up of one or more fields, and it’s the fields that capture the actual data, piece by piece.
Fields validate and store data. Each field is responsible for storing the content it’s captured. This means that individual
fields can use their own rules to validate, transform, and save their data.
Fields output your data for templating. When your entries are passed to the front end, it’s the fields that are responsible for
handling and outputting their own data.
Because fields are the primary data handlers, they're used throughout the system for fetching, filtering, sorting, and
outputting content.

Once you add a field to a section, you can configure how that individual field will handle all of these tasks—how and
where it should be displayed in the entry editor, what rules it should use to validate its input, if it should be displayed in
the entry index, and so on.

Field Types
The actual options you get when you’re configuring a field, and the way it captures, stores, and handles its data, are
determined by its type.
Field types define how fields capture data. A text field, for example, gives you either a text input or a textarea, depending
on its size. A select box field gives you a dropdown menu. A checkbox field gives you… wait for it… a checkbox. There
are field types that give you more advanced form elements too: calendar date pickers, maps, sliders, autocomplete
inputs, and more.
Field types define how fields validate and store their data. The number field type will only accept digits, for example. The
map location field stores the chosen locations as coordinates. The date field type accepts textual date strings and stores
them as timestamps.
Field types determine how a field's data is output. The title field in our Blog Posts section, for example, being a text field,
would output its content like this: . A date field, on the other hand, would give us something more appropriate for the kind
of content it’s meant to capture: 2010-12-21.
Field types are provided by extensions. This is one of the primary reasons that Symphony is so flexible. Instead of limiting
you to a handful of common field types like text, date, select box, checkbox, and so on, any number of specialized field
types can provide whatever functionality you might need. We’ll talk more about working with extensions in Chapter 9.
Note
Field types also determine how a field can be filtered. Each field type has its own filter rules, so while text fields can
be tested against phrases, for instance, date fields can be tested relative to other dates (e.g. ‘earlier than’ or ‘later
than’). We’ll discuss filtering in much more detail in Chapter 7.

Relationships
Very often, the various kinds of content we’re modeling for a website are somehow related to one another. The blog we’re
building, for example, should support commenting, and each entry in the Comments section will need to be linked to a
specific Blog Post entry.
Content relationships can make websites and web applications tremendously robust, allowing you to organize and
browse entries via their relationship to other entries.
Relationships in Symphony are managed via fields. There are a handful of specialized field types that can be used to
create and manage relationships. Adding one of these fields to a section will enable you to create relationships between
entries in that section and entries in whatever target section you choose.
[This part of the system is still being designed, so the remainder of this section will have to be filled in once it’s complete]

Planning Our Blog
Armed with this knowledge, let’s map out a content structure for our new blog website.
What do we want to be able to manage? We’ve already set up a basic Blog Posts section. That one’s sort of a no-brainer.
We know we’ll want visitors to be able to leave comments, so we’ll need a Comments section too. And let’s imagine that
we want to organize our posts into a handful of predefined categories like “Work” and “Travel,” so we’ll add a Categories
section. That should do it for now.
We’ve already started modeling our Blog Posts, but obviously they’ll need much more than a title and body. If we’re
aiming for a traditional blog view (posts listed in reverse chronological order), then we’ll need our posts to have a publish

date. And if we want to be able to assign them to a category, we’ll need a category field that creates that relationship.
Finally, let’s add a checkbox to denote whether the entry is published or not, this way we can have unpublished drafts.
That wasn’t too difficult, was it?
Comments are easy too. When visitors submit comments, we’ll want to capture their name, email address, and the
comment itself. We’ll also want to record the date and time. A field pointing back to the associated blog post should round
off this section.
As for categories, let’s just say each category will have a name and a description. We won’t need much more than that.
So here’s what our content structure looks like at the moment:
Blog Posts
Comments
Categories
Title
Author
Name
Body
Email
Description
Publish Date
Comment
Category
Date
Published
Post
Simple, but it will do the job. Now let’s go build it.

Working with Content in Symphony
The last section was all ideas and descriptions; this one is about doing. Here we’ll explore Symphony’s content layer in
more detail while you go about creating your blog’s content structure.

Creating and Editing Sections
You already got a taste of sections during the teaser exercise at the beginning of the chapter. You’ll remember that to
create a section, you’ll need to:
1. Navigate to Blueprints > Sections
2. Click the green “Create New” button at the top right of the view.
Aside from the field configuration and the layout (both of which we’ll cover below) there are only three things you need to
define for each section, as you can see in Figure 5-5: Figure 5-5 [f0505.png]
Name is how your section will be identified within the system. The convention is to use plural nouns, like “Products”
or “Articles.”
Navigation Group is used to organize your sections in the back-end navigation menu.
Hide this Section... keeps the section out of the navigation menu altogether (although it can still be accessed directly)
Let’s create our Comments and Categories sections now. Assuming you’re already looking at the section creation view:
1. In “Name,” enter Comments
2. In “Navigation Group,” enter Content (or click “Content” just beneath the input, which will populate it for you.
Symphony will list all existing navigation groups here, for your convenience.)
3. Click “Create Section”
4. At the top of your screen, you’ll see a green notification bar with a message that begins “Section created at...” Click
the “Create Another” link.
5. In “Name,” enter Categories
6. In “Navigation Group,” enter Content again (In the other projects at the end of this book, we’ll make much more use of
navigation groups, but our blog is simple enough that we don’t really need to over-classify our sections.)
7. Click “Create Section”
Don’t worry that we’ve essentially just created empty shells without any fields in them. I wanted you to get a rough
scaffold set up first, and I also wanted you to see firsthand that sections can be developed iteratively—that you can
update sections at any time, even after they’ve been created and saved. You can try things, see if they work, and if not, go
back and tweak them. This means that your Symphony sites are able to grow and evolve over time. We’ll see this
principle in action many times, and in many places, over the course of the book.

Working with Fields
Of course, sections are kind of useless without fields in them, so let’s go ahead and get those sorted out.

Choosing Field Types
The first thing we’ll need to do for each section is decide which field type to use for each of the fields we’re planning on
adding.
As you saw above, field types determine a great deal about how your data is going to be handled by the system. You’ll
have to take into account all of the things for which a field type is responsible:
What kind of form element does it provide in the entry editor? Do you want your users to enter text directly, for example, or
choose items from a dropdown?
What validation options are available? Can you enforce that the value be a URL, for example, or an email address?

Can you apply text formatters to the content? A WYSIWYG editor, for instance, or a syntax like Markdown?
How will filtering and sorting be handled? Text fields, for example, won’t sort numbers correctly. Relationship fields
actually store entry IDs and so filtering and sorting by those might not work as you’d expect.
What will the field’s XML output look like?
Quite a bit to keep in mind. And what’s more, once a field’s been added to a section, you can’t switch between types. So
making informed choices at this stage is important. You won’t want to add too many content entries until you’re confident
in your section structure, because swapping field types means removing the original field and losing all its data.
All that may seem intimidating, but like many things in Symphony, a lot of this can be figured out with good old common
sense. The system comes bundled with eight basic field types, most of which are self-explanatory. Dozens more are
available as extensions, but for now we’ll just review the basic ones.
For each field type listed below, I’ll outline:
what form element it provides for capturing data in the entry editor
how it stores its values
whether/how it validates its input
whether/how it can be used to filter entries
whether/how it can be used to sort entries
what some example output looks like
whether/what special configuration options are available

Checkbox
Form Element: checkbox
Stores: One of two values: “Yes” or “No”
Filter: by value
Example Output: Yes
Configuration Options: whether field should be checked by default

Date
Form Element: text input
Stores: timestamp
Validates: as date or timestamp
Filter: by year, date, or timestamp
Sort: by date
Example Output: 2012-12-21
Configuration Options: whether to prepopulate with current date

Number
Form Element: text input
Stores: number
Validates: as integer
Filter: by value
Sort: by value, numerically
Output: 0

Relationship
Form Element: select box
Stores: an entry ID
Validates: as entry ID from linked section

Filter: by ID or value of linked field
Example Output: Value of linked field
Configuration Options: what section and field to link to, what type of relationship to create

Select Box
Form Element: select box
Stores: a textual value
Validates: as one or more values among preconfigured options
Filter: by textual value
Sort: by textual value
Example Output: option 1
Configuration Options: what static/dynamic options to provide, whether to allow multiple options to be selected

Tag List
Form Element: text input with suggestions list
Stores: a textual value
Validates: as comma-delimited values
Filter: by items’ textual value
Example Output: Tag 1Tag 2
Configuration Options: where to draw suggestions list from

Text
Form Element: text input or textarea
Stores: a textual value
Validates: against any regular expression pattern (URL and email address are preset options)
Filter: by textual value or regular expression
Sort: by textual value
Example Output: Sample Text
Configuration Options: text formatters to apply, size of field

Upload
Form Element: file upload
Stores: the file, at designated location, and the file name, path, and size
Validates: as file type (image and document are preset options)
Filter: by file name
Example Output: image/png44kb
Configuration Options: upload location

User
Form Element: select box
Stores: a user ID
Validates: as user ID
Filter: by user ID or user name
Sort: by user ID
Output: Full Name
That’s a lot of info, but all pretty straightforward, actually. We’ll be able to choose our field types without much deliberation
at all. Our Blog Posts’ “title” and “body”, we know, are text fields. The “publish date,” clearly, will be a date field.
“Published” is going to be a simple checkbox, because we only need to be able to mark entries as published or not
published. And “category” has to be a relationship field pointing to Categories.
For Comments, “author,” “email,” and “comment” will all be text fields. “Date” will be a date field, of course. And “Post” will

be a relationship field pointing to Blog Posts.
Categories will just have its two text fields, “Name” and “Description.”

Adding and Configuring Fields
Now that we’ve got our content model mapped out, the rest should be easy. You’re still looking at your empty Categories
section, right?
1. Under “Fields,” you’ll see the fields tool. Click the “Add Field” button.
2. A drawer will appear containing a list of field types. Click “Text”
As you’ve seen, whenever you add a field to a section, you’re presented with a configuration panel that allows you to
specify options for that field’s appearance and behavior. Some of these options are common to all field types, and as we
saw above, field types can also provide their own configuration options.
Figure 5-6 highlights the options common to all field types.

Figure 5-6

[f0506.png]

Name is the name used to reference the field internally. It’s what you’ll use when choosing the field for filtering, sorting,
and output, and is used an as element name in the field’s XML output.
Publish Label is optional, and is used when the text you need to display with the field’s form element is more complex or
explicit. You might have a date field, for instance, whose label needs to read “Enter the date to publish this entry,” but you
don’t want the system to use that unwieldy phrase everywhere.
Show column tells the system whether to display the field’s value in the section’s entry index.
Make this a required field tells the system whether to require that the field have a valid value before saving.
The rest of the options you see above are specific to the text field type. We won’t get bogged down with all of that here,
but you might want to take a quick glance at Appendix B for a description of the configuration options provided by each
field type. For now, let’s finish configuring your Categories.
First, configure the name field:
1. Enter Name into the Name field
2. In the Size dropdown, select “Single Line”
3. Check the box next to Make this a required field
4. Leave the rest of the options in their default state
Now we’ll add the description field:
1. Click “Text” again in the field types list to add another text field
2. Enter Description into the Name field
3. In the Size dropdown, select “Medium Box”
4. Uncheck the box next to Show column
5. Uncheck the box next to Output with handles
6. Click “Save Changes”
Let’s do the Comments section next:
1. Go to Blueprints > Sections (or in the notification bar that appeared at the top of your screen when you saved this
section, click the “View all” link)
2. Click “Comments” in the sections index
3. In the fields tool, click “Add Field”

We’ll start with the author field:
1. Click “Text”
2. Enter Author as the field’s name
3. In the Size dropdown, select “Single Line”
4. Check the box next to Make this a required field
Now the email field:
1. Click “Text” in the list of field types
2. Enter Email as the field’s name
3. In the Size dropdown, select “Single Line”
4. Click the gray “email” link beneath Validation Rule. This will populate the Validation Rule with a regular expression
pattern that matches email addresses.
5. Check the box next to Make this a required field
Now a field for the actual comment:
1. Click “Text” to add another text field
2. Enter Comment as the field’s name
3. In the Size dropdown, select “Medium Box”
4. In the Text Formatter dropdown, select “Markdown (with HTML Purifier)”. Because you’re allowing visitors to submit
comments from the front end, we’ll want to make sure the input is cleaned up before we save it. Adding this text
formatter to the field will take care of that, and will also allow commenters to add formatting to their comments using
Markdown syntax.
5. Uncheck the box next to Show column. Comments will be far too long to display in a table cell.
6. Check the box next to Make this a required field. No use saving a comment if there’s no comment.
7. Uncheck the box next to Output with handles.
Lastly, add the date field:
1. Click “Date” in the list of field types
2. Enter Date as the field’s name
3. Check the box next to Make this a Required field
I know there’s one more field to add, but we’re going to take care of creating relationships a little later. For now, we’re all
set.
1. Click “Save Changes”
Now let’s go back to our good old Blog Posts section and round it out:
1. Go to Blueprints > Sections, or use the “View all” link in the notification bar
2. Click “Blog Posts” in the sections index
3. Click “Add Field” in the fields tool
4. Click “Date” in the list of field types
5. Enter Publish Date as the field’s name
6. Check the box next to Make this a Required field
We’ll skip the category field for now, because we’re going to address relationships a bit later. So let’s finish off by adding
the published field:
1. Click “Checkbox” in the list of field types
2. Enter Published as the field’s name
3. Let’s add a more descriptive label for this field. In the Publish label input, enter Publish this post
4. Click “Save Changes”

Reordering and Removing Fields

Let’s take a closer look at what the fields tool looks like once you’ve got a bunch of fields in it (Figure 5-7):

Figure 5-7

[f0507.png]

Each of the fields you’ve added is listed on the left side in a sort of “tab.” The tab contains the field’s name and field type
so you can see at a glance what your section looks like.
If you hover over these tabs with your mouse pointer, you’ll see a small delete button appear. This is how you remove a
field from your section.
To reorder fields, simply click the field tab and drag it up or down. Try reordering the fields in your Blog Posts section and
saving your changes.
Whichever field is listed first is treated by Symphony as the section’s primary field. This means it’s used when referencing
an entry in the admin interface (for instance, in the entries index for that section, it’ll be the field that’s listed in the first
column and linked to the entry). Restore the original order of the fields and save your changes again.
One last trick to know about the fields tool: sometimes you need to see the configuration options for more than one field at
a time. Try holding the Shift button while clicking on tabs. This allows you to select multiple fields, and when more than
one field is selected, the configuration panels will stack on the side. This can come in handy when you want to quickly
compare fields.

Designing Section Layouts
As you’ve seen, Symphony automatically creates interfaces that allow you to manage the content in your sections. One is
the entries index, and we’ve already seen how you can use field configurations to define what gets displayed in that
table.
The other interface that Symphony creates for you is the entry editor. You know now that each field is responsible for
rendering its own form element in the entry editor, and you’ve seen how field configurations allow you to define how
these are labeled (and often set other options as well). Let’s take a quick glance at what your Blog Posts entry editor
looks like with the new fields added:
1. Go to Content > Blog Posts
2. Click “Create New”
You should see something that looks like Figure 5-8:

Figure 5-8

[f0508.png]

Simple, but not at all elegant or user-friendly. Thankfully, Symphony allows you to define how these form elements are
organized and arranged, meaning you actually have quite a bit of control over the content publishing experience.
Let's go back to our Blog Posts section so you can see what I mean:
1. Go to Blueprints > Sections
2. Click on “Blog Posts” in the sections index
You may not have noticed this, but whenever you create a section, a second tab appears in the section editor below the
section name. Click on the Layout tab.

Figure 5-9

[f0509.png]

This is the section layout tool (Figure 5-9). It enables you to define what a section's entry editor will look like—namely, the

order and organization of its fields.
You start by choosing a base column layout. If you click the “Choose Layout” button, you’ll see a drawer appear with the
various column options. For our Blog Posts, we’ll stick with the default column setup, so go ahead and click the button
again to close the drawer.

Working with Fieldsets
Within your chosen base layout, fields can be grouped into fieldsets. Each column contains a single fieldset by default,
but you can easily add additional fieldsets using the “Add Fieldset” button.
At the top of each fieldset, above the dotted line, you can enter a title for that fieldset. This is entirely optional, and by
default fieldsets will have no titles, but they can be helpful for sections that have multiple groups of fields, and overall
usually make your entry editor much more usable.
Once you’ve chosen a base layout, you can begin organizing your fields. By default, Symphony just stacks your fields into
a single fieldset in the first column. You should see all four of your Blog Posts’ fields there. let’s do a little rearranging:
1. Click and hold the Publish Date field, and drag it into the right column.
2. Click and hold the Published field, and drag it into the right column.
3. In the left column, enter Content as the fieldset title (above the dotted line).
4. In the right column, enter Info as the fieldset title.
5. Save your changes.
Now, if you go back to Content > Blog Posts and click "Create New," you'll see a more organized entry form (Figure 5-10).

Figure 5-10

[f0510.png]

Now, your Categories section is so simple that we don’t really need to look at its layout, but let’s do some fine-tuning in
the Comments section. Even though comments are going to be submitted from the front end rather than here in the admin
interface, there’s no harm in making it tidier.
I’m actually going to leave this one to you. Using whatever column layout, fieldsets, and field arrangement you like, go
ahead and reorganize your Comments layout. Take the time to experiment with various groupings and columns and see
how they affect the entry editor for that section.
Once you’re happy with what you’ve done, we’ll move on.

Tabs and Steps
For especially complex sections, with lots and lots of fields or unique workflow needs, it’s possible to split fields and
fieldsets over multiple tabs or steps. Tabs simply allow you to spread your fields and fieldsets over multiple views,
whereas steps enable the creation of so-called “wizard” interfaces where content must be entered in order, one step at a
time.
To split your fields over multiple tabs or steps...
[This functionality hasn’t yet been implemented. Will need to revisit once development is further along.]

Creating Relationships
[This functionality hasn’t yet been implemented. Will need to revisit once development is further along.]

Managing Sections
Guess what? Your blog’s content structure is complete! And if I hadn’t spent so much time blathering about all the various
concepts and options you encountered, it probably would’ve only taken you five or six minutes from beginning to end!

The nice thing is, once you’re more familiar with all these nuances, you’ll be able to build a website’s content structure in
the blink of an eye.
I just want to review a few more helpful tidbits about managing sections before we move on.
There are two ways to delete a section. The first is to go to the section editor and click the red “Delete” button. The second
is to go to the sections index, click the section’s row (it’ll be highlighted blue when it’s selected), choose “Delete” from the
“With selected” dropdown below the table, and click “Apply.” (This paradigm actually applies to pretty much everything in
Symphony).
The other thing to know is that everything you can accomplish in the admin interface—creating, editing, and deleting
sections, adding and configuring fields, defining a section’s layout—all of this can also be achieved by directly editing the
section file (though doing so isn’t recommended).
Note
All of the configuration data that makes up a section, from its name and its field makeup to the layout of its entries,
is stored in a physical XML file in your workspace (in the /workspace/sections/ folder). Here's a simplified example
—the file for our Blog Posts section:

<section>
<name handle="blog-posts">Blog Posts</name>
...
<fields>
<field>
...
<type>textbox</type>
<element-name>title</element-name>
<name>Title</name>
...
</field>
...
</fields>
<layout>
<column>
<size>large</size>
<fieldset>
<name>Content</name>
<field>title</field>
<field>body</field>
</fieldset>
</column>
<column>
<size>small</size>
<fieldset>
<name>Info</name>
<field>publish date</field>
<field>published</field>
</fieldset>
</column>
</layout>
</section>

Having all of this information in a physical file will help you develop more efficiently. For starters, unlike tables in a
database, files can be easily version-controlled. That means teams can develop content structures for their projects
collaboratively, and iteratively, without worrying about stepping on each other’s toes. It also means that if you spend time
developing a very finely-tuned section for one site, and then you find that you need to manage similar content in another
site, all you need to do is copy the file over.

Synchronizing Sections
Whenever a section file is updated, the system will detect the changes and ask you to sync the section so your database
can be brought up to date. This is an automated and painless process.
[This functionality hasn’t yet been fully implemented. Will need to revisit once development is further along.]

Managing Entries
The last thing we need to discuss in this chapter is how to manage entries. You’ve already seen how entries are created
and edited. And by now, I hope you’re becoming familiar with Symphony’s common user interface paradigms (the
indexes, editors, action buttons, and so on). So most of this should be easy to figure out on your own, but I’ll just highlight
a few especially helpful things.
You’ll probably find yourself needing to sort, browse, and search through entries on a regular basis. The entries index
table for each section is sortable by whatever fields you choose to include in the table, so if you want to sort your Blog
Posts by date, for instance, make sure to check “Show column” in that field’s configuration. By default, entries are sorted
in order of creation, newest to oldest. The tables are paginated, of course, and the number of items per page can be
adjusted in the system configuration (which we’ll discuss in Chapter 9).
There’s also a filtering mechanism that allows you to run more precise searches on a section’s entries. [This functionality
hasn’t yet been fully implemented. Will need to revisit once development is further along.]
Deleting entries works exactly like deleting sections. You can do so either from the entry editor itself, or from the entries
index (using the “With selected” dropdown).
This “With selected” dropdown—or bulk actions menu—can also offer other options. Certain field types allow their values
to be toggled via this menu, which means that, depending on how you’ve modeled a section, you’ll usually have some
options for updating field values in multiple entries at once. To see it in action, first add a few additional test entries to
your Blog Posts section. Once you’ve got two or three entries:
1. Navigate back to the Blog Posts index (Content > Blog Posts)
2. Click on one or more rows to select those entries
3. Click on the “With Selected” dropdown
You’ll see that the checkbox field allows its value to be toggled here, so you can publish or unpublish lots of Blog Posts at
once. Select box is another field type that allows its value to be set via the bulk actions menu. This functionality is often
very useful in situations where you need to enforce moderation or publishing workflows—for example, marking entries as
approved or published, or changing their status.

Summary
We’ve covered quite a lot in this chapter. We started by introducing you to the practice of content modeling, so that you’d
understand what goes into defining a website’s content structure. We then reviewed in more detail the elements that
make up Symphony’s content layer—sections, fields, field types, and entries.
Once you were familiar with the basic architecture and concepts, we went about setting up a content structure for your
blog. Along the way, you learned how to work with each of these elements in turn, from basic section creation to
advanced field configuration and entry management.
There always more to learn, of course. Appendix B outlines in painstaking detail everything you need to know about
common field types, and you should study that closely. On top of that, ever more can be found online in the official
documentation (http://symphony-cms.com/learn/). This is a great start, though, and by now you should feel pretty
comfortable working in Symphony’s content layer on your own.
Let’s move on to the front end.

Chapter 6: Front-end
What’s in This Chapter
About front-end architecture
Understanding Symphony’s front end
Working with Symphony’s front end
Now that you’ve got your content modeled, the next step is to begin thinking about your blog’s front end—you know, the
part that everyone sees. What interfaces do you want to provide for your visitors? Where will these interfaces live? How
do you want their URLs to be structured?
Front ends come in all kinds of shapes and sizes, from traditional websites that mimic page-based architectures to
applications with modular, responsive interfaces or even specialized setups like APIs. With so many possibilities, it’d be
incredibly limiting for a system to predetermine how your front end should be structured.
Thankfully, Symphony doesn’t. That task is left entirely up to you. This means, though, that the blog you’ve been building
doesn’t even have a front end yet. (Just like there was no content structure at all until you defined one in Chapter 5). Don’t
believe me? Try pointing your browser to it: http://yoursite.com/.

Figure 6-1

[f0601.png]

The error message you see there (Figure 6-1) is thrown because you haven’t yet created any interfaces, so Symphony
doesn’t know how you want it to handle requests. Until there are structures in place defining where and how people
should be able to access your site, Symphony will simply shrug its shoulders like this and say “sorry.”
The next step in building your blog, then, is to start mapping these structures out, developing what we’ll call a front-end
architecture. We’ll begin by talking about what front-end architecture looks like and what it entails. Then I’ll explain how a
Symphony front end works, and we’ll review all the important concepts you need to know before you get started.
After that, all that’s left is to do the work. You’ll see that the process of building out a front end is actually pretty simple
once you know what you’re doing. By the time we finish this chapter, you’ll be well on your way to mastering the art of
front-end architecture, and your blog will be beginning to take visible, tangible shape.
To get you oriented, let’s start with another quick exercise:
1. Navigate to Blueprints > Views
2. Click the green “Create New” button
3. You’ll see the view editor (Figure 6-2). Enter Home as the title, and / (a forward slash) as the handle. For now, leave
the rest of the fields blank.
4. Click “Create View”
Figure 6-2 [f0602.png]
Now, if you return to your front end, you’ll see that the error is gone. By creating this view, you’ve defined the first point of
interface for your blog, one that sits at the root (/) of your site. The view is just displaying some simple placeholder content
right now (Figure 6-3), because you haven’t written its template yet (something we’ll take care of in Chapter 8). But it’s a
start.

Figure 6-3

[f0603.png]

Before we press on, let’s take a moment to assess the task at hand.

What is Front-End Architecture?
As I pointed out above, Symphony doesn’t make any assumptions about how and where you want to deliver content to
your users. All of these decisions are left entirely up to you, which means that your site doesn’t have any front end
interfaces at all until you build them. It’s the classic Symphony trade-off: complete freedom and flexibility for a little bit of
extra work.
So what does developing a front-end architecture entail? Let’s start with a real-world example.
Imagine for a moment that you’ve been asked to help design and build a new museum. The fundamental content
questions have already been sorted—what collections the museum will house, what kinds of exhibitions it’ll host, how its
holdings will be stored. What you’ve been asked to do is to sit down with the architect and begin planning a physical
layout for the museum—its great halls and exhibit rooms, its entrances and exits, its restrooms, ticket counters, fire
escapes, and so on. In short, your task is to define how and where the museum’s visitors will be able to view its content
and accomplish important tasks.
Websites and web applications require the same sort of planning. They need to determine where various kinds of content
will be on display, where visitors will go when they need more information, what happens when people get lost, etc. Their
front ends require an architecture—a logic for handling visitors and their requests, and a structure for organizing and
facilitating interactions.
At its core, developing a front-end architecture involves three interrelated tasks:
Identifying the interfaces that you’ll make available to your visitors
Figuring out how those interfaces will be organized
Deciding what interactions each interface will need to facilitate
In a simple, page-based architecture, each page corresponds to one URL and one set of contents, so mapping out a front
end is no more difficult than organizing a bunch of files into folders. In Symphony, however, things are a bit different. A
single view can power dozens or even hundreds of pages and URLs.
It’s a far more powerful and flexible approach, and though it’s slightly more challenging conceptually, in the end
developing the architecture is almost as easy. You just have to know how it all works.

Understanding Symphony’s Front End
When you visit a Symphony site, every page that gets loaded in your browser is the result of a transaction: you submit a
request to the server, and Symphony formulates a response. I explained roughly how all this works back in Chapter 4, but
it bears elaborating here.
Views are the engines of a Symphony front end, fielding requests and orchestrating the system’s responses. Every view
has resources attached to it—data sources for fetching content and/or events for processing interactions (we’ll cover both
in the next chapter). When a view is called, these resources get executed, and they return XML content to the view. The
view then uses its template to transform that content into a digestible response. Figure 6-4 illustrates the basic process:

Figure 6-4

[f0604.png]

Put very simply, each view constitutes a point of interface between a site and its visitors.
What makes views so powerful is that their URLs can have dynamic parts, or parameters. These get passed through to
the resources and the template, meaning everything that a view needs to take care of, from content retrieval to
presentation, can be dynamic and almost infinitely extensible.
Here’s a simple example. Let’s say you’re building an online children’s store. You create a view called “Shop,” available
at the URL handle shop, and configure it to accept three parameters in its URL: department, age group, and gender. So if
someone were to visit http://yoursite.com/shop/toys/toddlers/girls, all three parameters would be set:
department = toys
age-group = toddlers
gender = girls
A data source attached to this view could fetch products from your catalog using these dynamic values to filter the results.
Assuming your Products section has the appropriate fields, the above URL would return products from the “toys”
department, in the “toddlers” age group, targeted for “girls.”
Imagine the breadth of possible variations:
http://yoursite.com/shop/clothing/
http://yoursite.com/shop/clothing/infants/
http://yoursite.com/shop/books/
http://yoursite.com/shop/books/adolescents/boys
… and so on, ad infinitum.
You could use these values in your templates, too, allowing you to adjust your shop’s theme for different departments,
age groups, or genders.
In short, you could power an entire shop interface with this single view!
As powerful as views are, you needn’t be intimidated. Planning your blog’s front-end architecture actually isn’t all that
daunting a task. Once I’ve reviewed a few important concepts, you’ll see so for yourself.

Views
Views are points of interface for a website. Everything your visitors can do, from browsing content to submitting forms, is
powered by a view. A view can be as simple as a old-fashioned static page, or robust enough to power a dynamic web
application interface.
Views define a website’s URL schema. Every view has a URL handle and is able to accept URL parameters. These two
attributes, along with the ability to nest views hierarchically (we’ll discuss this below), mean views give you full control

over even the most intricate URL structures.
Views are the context in which data exchange and templating take place. This will be important to remember over the
next two chapters. When you’re planning interactions or sketching out your presentation layer, the contextual information
(like parameters and event output) and the content that will be available to you are both determined by the view.
Note
Those familiar with MVC architecture might find all this a bit confusing, because from an MVC perspective,
Symphony’s views would actually be part of the controller layer rather than the view layer. If you’re accustomed to a
framework like Ruby on Rails and tend to think in MVC terms, it’ll help you to know that Symphony’s views combine
the functions of a classic MVC controller with a web framework’s URL routing system.
You can manage the views you’ve created at Blueprints > Views.

View Types
There are circumstances in which you want some views to behave differently than others. For this reason, Symphony
allows for different types of views.
View types define special behaviors and handling options. For example, there is a view type that restricts access to
authenticated users, and one that designates a view to handle 404 errors. View types give you an added measure of
control over not only the structure but also the behavior of your front end interfaces. What’s more, view types can be
provided by extensions, making Symphony’s front end endlessly flexible.

URL Parameters
URL parameters allow views to accept dynamic values in their URL. These values can then be used by the view (and its
resources and templates) as it orchestrates the system’s response.
Note
Views are able to use values passed via a URL’s query string as well. This makes it possible to work with optional
values that shouldn’t affect a URL’s basic structure, for instance:

http://yoursite.com/shop?sort=price&order=asc&limit=50

This URL would set three query string parameters—price, order, and limit—which could then be used just like a URL
parameter. Rather than having the view define these explicitly, though, they can be tacked on to the URL on an ad-hoc
basis.

View Resources
View resources enable a view to deliver content or process interactions. There are two types of view resources:
Data sources deliver content to a view, either from within the system or from an external source. As we’ve seen, the
view is a dynamic environment, and data sources can inherit this dynamism (for instance by filtering their results
using a URL parameter).
Events process interactions. Most commonly, they allow data submitted to a view (via a web form, for instance) to be
saved into the system. Commenting and contact forms are good examples of this sort of behavior.
We’ll discuss data sources and events in greater depth in Chapter 7.

Planning Your Blog’s Front End
Now that you have a good sense of how Symphony will run your front end, we can go ahead and plan the interfaces
you’ll need for your blog. This should be fairly easy because, for the most part, blogs have developed a pretty standard

format.
For each interface we plan, we’ll need to answer a handful of questions:
Where will it live?
What content will it need to provide?
Will it need to process any interactions?
What parameters will it need to accept?
In the interest of keeping things simple, your blog will be powered by just three interfaces: a home view, a view for
reading individual posts, and an archive.
We got a head start on the first of these earlier. Your Home view is going to live at the root (/) of your site. Like most blogs’
home pages, it’ll just display a stream of your most recent posts. The wrinkle is that we’re going to allow it to be filtered by
category. So we’ll add a URL parameter for category.
The Posts view, a dedicated interface for reading individual posts, will have a handle of /posts, and since we’ll need to
fetch each post by its title, should have a single URL parameter for title. That’ll give us nice, friendly URLs like
http://yoursite.com/posts/how-to-become-a-luchador. This view will also need to process comments, something we’ll take
up in the following chapter.
The Archive view will provide an interface for browsing through your blog’s history. It’ll be located at /archive, and will
fetch posts based on their publish date. That means it’ll need to accept parameters for year and month (allowing for URLs
like http://yoursite.com/archive/2010 or http://yoursite.com/archive/2011/01).
We could add a few more interfaces, but let’s leave it at this for now.
Bear in mind, this is only one of many, many possible front-end architectures we could have whipped up for your blog.
You might already be thinking of ways you’d want to improve things, or additional interfaces you’d want to offer. But since
our goal here is just to familiarize you with the system and illustrate some important concepts, you’ll have to be patient for
the time being. You can always go back and adjust things later if you like.
With this plan in place, scaffolding your front end is going to be a walk in the park. Let’s get started.

Working with Symphony’s Front End
There are two ways to manage views: using the admin interface (under Blueprints > Views), or by working with the files
directly (in workspace/views).
Note
Like sections, views’ configurations and templates are stored as files in your workspace. Each view gets a
dedicated folder, which is named using the view’s handle. The hierarchy of these folders mirrors the hierarchy of
the views themselves.
Inside the view’s folder are two files: an XML file containing the its configuration, and an XSL file containing its template.
We’ll discuss templates in Chapter 8, but here’s a peek at a (slightly simplified) sample view configuration:

<?xml version="1.0" encoding="UTF-8"?>
<view>
<title>Inventory</title>
<content-type>text/html;charset=utf-8</content-type>
<url-parameters>
<item>department</item>
</url-parameters>
<data-sources>
<item>inventory-items</item>
</data-sources>
<events>
<item>update-inventory</item>
</events>
<types>
<item>admin</item>
</types>
</view>

Using the file system to manage views can be efficient, especially when you’re doing large-scale restructuring, but you
don’t get the same combination of ease-of-use and fine-grained control as you would with the admin interface.

Creating and Editing Views
Let’s start by revisiting your Home view and taking a closer look at the view editor.
1. Navigate to Blueprints > Views
2. Click “Home”
The one adjustment we need to make here is to add the URL parameter for category filtering:
1. In URL Parameters, enter category
2. Click “Save Changes”
Your view should now look like Figure 6-5:

Figure 6-5

[f0605.png]

The view editor, as you can see, is organized into three parts: “Essentials,” where you identify the view and its type; “URL
Settings,” where you define the various properties that will determine the view’s URL(s); and “Resources,” where you can
attach data sources and events to the view. Let’s take a closer look at each field:
Title is a simple, human-readable title for the view—something like “Home,” “About,” or “Browse Products”
View Type allows you to select a type for the view. By default the system provides four view types:
“Normal” views have no special behaviors or conditions associated with them.
“Admin” views can only be accessed by users who are logged in to the system.
A “403” view (you should only specify one) is used when a visitor requests a forbidden URL.

A “404” view is used when a visitor requests a non-existent URL.
Handle is the primary URL identifier for a view. If no handle is specified during view creation, one is automatically
generated using the view’s title.
Parent allows you to nest views hierarchically. The view’s URL will then include its parent’s handle:
http://yoursite.com/parent-handle/handle.
URL Parameters allows you to define one or more parameters that can be accepted by the view. Parameters are
slash-delimited: parameter1/parameter2.
Data Sources allows you to attach data sources to deliver content to a view.
Events allows you to attach events to a view for processing interactions.
Let’s quickly create the two remaining views. First, your Posts view:
1. Navigate to Blueprints > Views
2. Click “Create New”
3. For title, enter Posts
4. For handle, enter posts
5. For URL parameters, enter title
6. Click “Save Changes”
Now the archive view:
1. In the notification bar, click “Create another”
2. For title, enter Archive
3. For handle, enter archive
4. For URL parameters, enter year/month
5. Click “Save Changes”
Just like that, you’ve defined the three interfaces that are going to power your blog. Of course, we’ve got a ways to go
before they’ll actually do anything useful, but the structure is already in place. Didn’t I tell you it was going to be easy?
In fact, it’s been a bit too easy, so we’ll make this slightly more interesting. Let’s say, as very often happens when you’re
working on a web project, that you’ve changed your mind about something. You’ve decided that you want your posts’
URLs to include the category in which you’ve placed them. So instead of, say:

http://yoursite.com/posts/choosing-a-stripper

You want:

http://yoursite.com/painting-tips/posts/choosing-a-stripper

Seems like a sound decision. Let’s go ahead and implement it.

Crafting a URL Schema
It’s beyond the scope of this book to discuss what makes a good URL schema, and really, it depends on the site. But
whatever your needs it’s important that you understand the formula that goes into determining a view’s URL, so let’s
quickly review that now.
If you don’t specify a parent, your view will be located directly at the site’s root:

http://yoursite.com/handle

Any parameters your view accepts can be tacked on to the end of that URL:

http://yoursite.com/handle/parameter1/parameter2

When your view does have a parent, naturally its URL nests beneath that of the parent:

http://yoursite.com/parent-handle/handle

And if the parent accepts parameters, you can nest behind those too:

http://yoursite.com/parent-handle/parent-parameter/handle

If the parent itself has a parent, the same rules apply. I’m going to assume that, by now, you can use your powers of
deduction to figure out what those URLs would look like, so let’s move on.

Organizing Views
With all of that in mind, let’s make that change we talked about above. There are two ways to nest views: using the parent
field in the view editor, or by physically nesting the view directories in the file system. The latter is less flexible (you can’t
nest behind a parent view’s parameters without opening and editing the view configuration), but it’s useful nonetheless,
so we’ll look briefly at both methods:
1. Using a file browser, or if necessary the command line, browse to the location on your server or computer where you
installed Symphony.
2. Descend down into the workspace/ directory, and then into views/. You’ll see directories there for each of the views
you’ve created.
3. Move the posts/ directory into the home/ directory, so that the directory hierarchy looks like Figure 6-6:

Figure 6-6

[f0606.png]

That’s it. Your Posts view is now nested beneath your Home view. Symphony instantly recognizes the change:
1. Back in the admin interface, navigate to Blueprints > Views
You’ll see that the views index now reflects the change you made in the file system, and Posts is nested beneath Home.
Neat, huh?

Figure 6-7

[f0607.png]

But we’re not finished yet. Remember, the whole point was to nest our Posts view behind the Home view’s category
parameter, and that’s a level of control we can only get using the admin interface:
1. Click “Posts”
2. The parent dropdown now lists all the views you’ve created, along with various permutations including their
parameters (Figure 6-7). Select “/:category”
3. Click “Save Changes”

Figure 6-8

[f0608.png]

As you can see, the parent dropdown gives you the ability to choose very precisely where you want to nest a view,
whether directly beneath the parent page or beneath one or more of its parameters. When you’re building complex
websites or web applications, this kind of flexibility can come in very handy.

Also, the fact that views can be so easily rearranged, updated, and reorganized means that when you’re developing with
Symphony it’s absolutely trivial to experiment with different architectures, tweaking and adjusting until you’ve got it just
right.

Summary
And with that, you’re finished architecting your blog’s front end.
As with content modeling, I’ve tried to demonstrate here that front-end architecture really isn’t all that difficult once you
understand what it entails. If you’re a seasoned developer, of course, most of this was elementary to you, but if not, I hope
you’re beginning to feel empowered. This is serious web development work you’re doing, the sort that many systems try
to hide from their users. Symphony not only hands you the reins, it actually makes the task easy and enjoyable.
In this chapter, we talked about what it means to develop a front-end architecture, and we reviewed how exactly a
Symphony front end works. We then thoroughly dissected views and their various properties and accoutrements. Finally,
we planned a structure for your blog’s front end and then built it, fairly quickly and unceremoniously, in just a handful of
steps.
Though we restrained from doing anything too complex, I hope you’ve gotten a sense of how powerful views really are.
They give you the ability to craft almost any kind of front end you can imagine. Just how this is so might not be entirely
clear yet, but as we pull everything together over the next two chapters, I think you’ll begin to see for yourself.

Chapter 7: Data Flow
What’s in this Chapter
What is data flow?
Understanding how data flow works in Symphony
Working with data sources
Working with events
This is an exciting moment. Over the past two chapters, you’ve been dutifully creating the structures that are going to give
your blog its shape—from its content models to its front-end architecture. With these pieces in place, you’re finally ready
to begin breathing life into your new site.
On the web, “life” means interaction. It means give and take. It means communicating with your visitors, responding to
their requests, allowing them to do things. And the substance of all these interactions is data.
Every time one of your visitors clicks a link or submits a form, data is on the move—being exchanged, requested,
collected, altered, stored, and so on. This data can be anything from website content to server information to user details.
All the stuff that makes the web tick.
In short, every interaction on the web is a product of data flow. And so your next task is to pave the way for data to move
within and around your blog, powering the interfaces you’ve so carefully planned.
As in the previous two chapters, we’ll begin with a broad discussion of the concept itself—what we mean when we talk
about data flow, and what designing data flow for an application or a website generally entails. Then we’ll talk more
specifically about how this works in Symphony, and introduce you to a few important concepts that you’ll need to
understand before you get started. Finally, we’ll go about setting up the structures that will be responsible for managing
data flow in your site.
But first, let’s get a brief taste of what this sort of work entails:
1. Navigate to Blueprints > Data Sources
2. Click the green “Create New” button. You’ll see Symphony’s data source editor (Figure 7-1).

Figure 7-1

[f0701.png]

3. Name your new data source Recent Posts
4. In the Section dropdown, select “Blog Posts”
5. Under “Filtering,” you’ll see the filter tool. Click “Add Filter”.
6. In the drawer that opens up, select the “Published” field. A panel will appear for configuring your filter.
7. Leave the Mode dropdown set to “Is” and in the accompanying input, enter yes (or click the “yes” link beneath the
field).
8. Under “Sorting,” in the Sort By dropdown, you’ll see a list of fields from your Blog Posts section. Select “Publish
Date”.
9. Beneath that, in the Sort Order dropdown, select “descending”.
10. Under “Limiting,” enter a limit of 10 results per page.
11. In the “Included Fields” multiselect, choose “Title (formatted)”, “Body (formatted)”, “Publish Date”, and “Category”.
12. [Step to attach DS to Home view -- this functionality is not fully implemented yet]
13. Click “Create Data Source”
Now, if you recall, in Chapter 6 you decided that you wanted your blog’s Home view to serve up your most recent posts
(well, actually, I decided that... but let’s pretend it was you). What you’ve done here, then, is created a data source that’s
responsible for fetching that content—ten published posts, sorted by their publish date in descending order—and then
attached that data source to your Home view.

Now I’m going to show you something really cool. Navigate to your blog’s Home view, but append ?debug to the end of
the URL (so, http://example.com/?debug). You’ll see something that looks like Figure 7-2:

Figure 7-2

[f0702.png]

What you’re looking at is Symphony’s debug devkit—an interface, provided by one of Symphony’s core extensions, that
allows you to go behind the scenes of any Symphony view (only if you’re logged into the system, of course). The debug
devkit will show you a view’s XML source content, the stylesheets that have been used to transform it, and the result of
that transformation (e.g. HTML). You can also examine the parameters available to the view at runtime. In short, it’s X-Ray
vision for every view on your site—allowing you to see exactly how it was built and from what pieces. Neat, right?
Don’t worry if you’re a little overwhelmed by what you see. If you’ve never looked at code before you might feel like you’re
staring at the title sequence from The Matrix. Take courage—I’m going to teach you all about XML in the next chapter.
Now, do you remember the sample blog posts we created back in Chapter 5? You should see those entries in your
view’s source XML. Look closely. See them? Congratulations. Your content has made its way to the front end.
Note
The debug devkit has even more tricks up its sleeve, but we’ll save most of those for Chapter 15. Still, it won’t hurt
you to poke around a little bit if you’re curious. You’ll use this tool a whole lot when developing in Symphony—
might as well get familiar with it.
Now that you’ve laid the foundation for this very basic interaction—a visitor arrives at your blog’s home view and is
provided with a listing of recent posts—it’s time to think a little more thoroughly about how you imagine people using your
blog. Every interaction you plan is going to have its own specific data needs, and in this chapter your job will be to figure
those out, and to meet them.

What is Data Flow?
Think of the last time you received a package in the mail, or a bill, or a postcard from a “friend” who was visiting some
beautiful and exotic land and felt compelled to shove it in your face. Just a handful of coded lines jotted onto the front of
an envelope or label and that little something could travel halfway around the world and land right on your doorstep.
Amazing, no?
Millions of letters and parcels travel through the world’s postal systems every day—originating at mailboxes and post
offices and in handshakes with letter carriers, and then somehow finding their way to even the most forgotten alleys, back
roads, and outposts.
Part of this everyday miracle is in the infrastructures—the buildings, machines, vehicles, and workers that collect,
organize, sift, transport, and disseminate all that mail.
The other part of the miracle is basic logic. Every day, millions and millions of decisions are made to help move all this
stuff along. What mail goes into which pile. Onto which truck. Which carrier gets which bag. These decisions are made
over and over, every day, based on three or four tiny lines of information.
These systems aren’t perfect, as we’ve all learned at one time or another, but for the most part things tend to get to where
they’re going, and every time they do it’s a little bit incredible.
Websites have to perform a similar task, albeit on a much smaller scale. While your visitors are submitting forms, clicking
links, and browsing through interfaces, your site is churning away behind the scenes—handling and routing requests,
parsing information, and retrieving, sorting, and delivering content.
Maybe not as miraculous, I’ll admit, but your website actually manages to keep all this data flowing in much the same way
that a postal system does: with a carefully-designed and flexible infrastructure, and with a collection of rules and
conditions that enable it to make decisions about what data goes where.
When we talk about designing data flow for a Symphony website, then, we’re talking about a handful of interrelated tasks:
identifying the data needs of each of your interfaces
building the infrastructures to manage that data
designing logic to ensure that the data goes where it’s supposed to
Let’s take a quick look at how all this is implemented in Symphony.

Understanding Data Flow in Symphony
You saw in Chapter 6 that when a view is called upon to respond to a request, it kicks its resources into action—first
triggering its events and then executing its data sources. These two components are responsible for regulating the flow of
data to and from the view (Figure 7-3).

Figure 7-3

[f0703.png]

Events process various kinds of interactions, and these can be fairly wide-ranging—they’re able to save data to the
system, set or alter contextual information, or perform other kinds of tasks depending on the event type.
Data sources are more specific in scope. They fetch data and deliver it to the view as XML. Pretty straightforward, but
there are many data source types, each responsible for retrieving content from a different kind of source.
What makes data sources and events so important is not just that they handle the flow of data to and from a view but that
they also define the logic that governs it all. They comprise what would commonly be called the site’s “application
logic”—the rules that determine what the system does and when.
For events, this logic comes in the form of event options, which make it possible to adjust an event’s behavior—for
instance by specifying conditions for its execution or adding additional actions to be triggered.
Data sources do most of the heavy lifting, though, when it comes to application logic. Data source filtering is the primary
hinge for determining what content is going to be delivered and under which circumstances. Data sources can also
specify conditions for their execution, rules for how their results should be sorted and limited, and various options for how
those results should be output.
The key to designing data flow, then, is understanding how you can use data sources and events to craft meaningful,
intelligent interactions. Let’s review the most important concepts:

Data Sources
Data sources fetch, filter, sort, and output content. Each of these tasks is a sort of logic axis—a place where you can have
the system make decisions about what it should do.
Data sources can use dynamic environmental variables. You saw this in our URL parameters example in the previous
chapter. The decisions your data sources make while fetching and processing content don’t have to be static or rigid.
Their logic can adapt to their environment.
Data sources can have execution conditions. This is yet another logic axis, another decision point, where you can tell a
data source whether or not to execute at all.
Data sources deliver their content to views. After all that, after all these decisions wrapped in decisions that depend on
other decisions, it’s still entirely up to the view’s template to decide what it’s going to do with the content it gets.

Data Source Types
Data source types determine where a data source gets its content. Most often, you’ll be fetching content from your entries
—content that you modeled and created yourself. But there are many other data source types, which allow you to grab,
for example:
XML or JSON from external sites (for instance from APIs and feeds)
static XML
system information like users or views
anything else an extension developer can dream up
You could say, then, that data source types define the range of data that can be used to power your site’s interactions.

Data source types determine how content can be filtered. Entry data sources, for instance, give you granular filtering and
sorting options on a per-field basis. Dynamic XML data sources, on the other hand, allow you to filter their content using
XPath (more about that in Chapter 8). This means that the logic implicit in the filtering process is both extensible and
context-specific—it’s tailored to the data itself.

Data Source Filters
Data source filters are rules used to identify the content you want. They are the difference between walking into a library
and saying “I’m looking for books,” and saying “I’m looking for books written by political theorists on the concept of
biopolitics.”
In other words, data source filters allow you to be precise about what you deliver to your visitors and in what contexts.
Note
If you’re familiar with SQL syntax you might find it helpful to think of filters as WHERE clauses in a query—you
define conditions that need to be met in order for content to be selected and returned.
When a data source contains multiple filters, they are joined using AND, meaning all of the filters must evaluate to TRUE
in order for content to match and be returned.

Events
Events enable views to take action with their data. For this reason, they’re often seen as complementary to data sources.
Events can do anything from authenticate users to process credit card transactions or run commands on a server. But by
far the most commonly used type of Symphony event is the entry-saving event, which allows system content to be
submitted and saved from the front end.
Note
Entry-saving events are often used to power simple user interactions like commenting, voting, and rating, but they
can just as easily allow you to build fairly complex web applications. The Symphony website (http://symphonycms.com), for example, has user-driven forums and a downloads repository, all powered by simple entry-saving
events.

Event Options
Event options allow you to adjust an event’s behavior or handling. There are generally three types of event options:
conditions for the event’s execution (restricting events to authenticated users, for example, or performing anti-spam
tests)
additional actions to be performed (for instance, sending an email when an event is successful)
event-specific settings (such as whether to allow an entry-saving event to process multiple entries in a single
request)
Event options give you an additional vector of control when you’re crafting interactions.

Planning Your Data Flow
Now that you’ve got a handle on the basic ingredients, let’s get down to business.
You’ll recall from the previous chapter that you’ve got three interfaces you need to plan around: a Home view, a Post
view, and an Archive view. And you’ve already put some thought into the interactions that these three interfaces will need
to support. Let’s take a moment now to evaluate the specific data needs of each.
Evaluating your interfaces’ data needs involves asking a series of targeted questions:
Where is the content coming from?

Under what circumstances do you want it to be provided?
What rules should be used to evaluate and select results?
This is also where you need to begin thinking about presentation, because how you intend to display your content
determines what exactly you ask your data sources to output. Let’s add those questions too:
What data do you need to display?
How do you want it arranged and organized?
Answering these questions for each of your interfaces will give you a helpful blueprint when planning data flow.
Your Home view, we know, is going to display your ten most recent posts; we already took a swing at that at the
beginning of this chapter. But you’ll recall that we also decided to allow that interface to be filtered by category. So the
data source will need not only to deliver the ten most recent posts, but also to optionally filter its results by the category
parameter if that’s been set in the view’s URL. Here’s a summary of what you need from this data source:
Source: Blog Posts
Filtering: Must be published; if category parameter is set, fetch only entries in that category
Sorting: By date, descending
Limiting: 10 entries per page
Output: Title, Body, Publish Date, Category
The Post view is going to display a single post in its entirety. We’ll create another data source for this purpose, one that
filters its results by the title and category parameters in the view’s URL. It’ll need some special handling instructions too. If
the title parameter isn’t set, for instance, it shouldn’t even execute. And if it doesn’t execute, or if there’s no entry that
matches the title, it should throw a 404 (Page not found) error. Here’s an overview:
Source: Blog Posts
Conditions: The title parameter must be set
Filtering: Must be published; fetch the entry whose title matches the title parameter, and whose category matches the
category parameter.
Limiting: 1 entry
Output: Title, Body, Publish Date, Category
Handling: Redirect to 404 if no results
We also want to enable commenting on individual posts, so this view will need an entry-saving event allowing Comments
to be submitted and saved. We’ll want to add some basic security measures to the event, which I’ll discuss later. Finally,
we’ll have the event send you an email whenever someone comments. This is what you need from the event:
Section: Comments
Overrides: Post field set to the ID of the post being viewed
Options: Send email filter, XSS Filter
You’ll also need a data source to fetch a post’s comments so that you can display them alongside the post. Let’s keep this
one basic—return all comments attached to this post, and sort them from oldest to newest:
Source: Comments
Filtering: Post field matches the ID of the post being viewed
Sorting: By date, ascending
Output: Author, Email, Date, Comment
Finally, your archive view is going to provide an interface for browsing older posts. Let’s think about how you’ll want it to
behave. By default, when no parameters are specified in the URL (http://example.com/archive/), the view should simply
display all entries in the current year, grouped by month. If only a year is specified (http://example.com/archive/2011/),
we’ll have it display that year’s entries, again grouped by month. If both year and month are specified
(http://example.com/archive/2011/01/), it’ll just list all the entries from that month. And since we only want to list post titles
here, we won’t need the body returned. Sound good?

Here’s the breakdown:
Source: Blog Posts
Filtering: Must be published; publish date matches year or year/month
Sorting: By publish date, descending
Output: Title, Date, Category; grouped by publish date
Now that you’ve got a clear sense of each interface’s data needs and the logic you’re going to use to regulate their
interactions, let’s get the data flowing!

Working with Data Sources
Data sources are managed in the admin interface at Blueprints > Data Sources.
Note
Like sections and views, data sources are stored as physical files in your workspace, making them easy to version
control. Unlike those other elements, though, data sources are stored as PHP files, and really shouldn’t be edited
directly unless you know what you’re doing.

Creating and Editing Data Sources
The first step in creating a data source is to choose its type. Each data source type has distinct filtering, sorting, and
output options, so you’ll need to define the type before you can configure anything else.
1. Go to Blueprints > Data Sources
2. Click “Create New”
The configuration options available in the data source editor will change depending on what is selected in the “Type”
dropdown (Figure 7-4).

Figure 7-4

[f0704.png]

There are five data source types included by default with Symphony (many more are available as extensions). Each is
identified by where it gets its content:
An Entries data source fetches entry content from the sections you’ve defined in Symphony.
A Users data source fetches user account data from within the system.
A Views data source fetches data about the system’s views (useful for building a navigation, for example).
A Dynamic XML data source fetches raw XML from an external source such as an RSS or Atom feed or a web
service or API.
A Static XML data source actually stores raw XML itself and returns that.
“Entries” is far and away the most common and so is selected by default. All of the data sources we’ll create in this
chapter are going to be Entries data sources. Feel free to cycle through the other types to get a sense of what they look
like, but in this chapter we’ll only cover the Entries type. You’ll be introduced to each of the others later in the book, and
Appendix C provides a complete breakdown of all the types and the configuration options available for each.
Let’s walk through the configuration options available when creating an Entries data source. There are six sections—
Essentials, Conditions, Filtering, Sorting, Limiting, and Output Options.

Essentials
Name is how your data source will be identified within the system.
Section is the section from which your entries will be fetched.
Note / Best Practice
Because data sources are attached to views, and because in very simple websites there can often be a one-to-one
correspondence between a view and the data source that delivers its content, it can be easy to fall into the habit of
thinking about a data source in terms of the view for which you’ve intended it. For example, you might be tempted
to create a “Home” view and an accompanying “Home” data source.
This isn’t a great practice, though. Not only will most of your views rely on more than one data source, but you’ll
also find ways to reuse data sources across multiple views.

Instead, try thinking about—and naming—your data sources in terms of their logic and the results they yield, rather
than the views you’re attaching them to. You’ll notice, for instance, in the example at the beginning of this chapter
we named the data source for your Home view “Recent Posts” rather than something like “Home” or “Homepage
Posts.” If we ever decide to create a web feed, and we want to provide it with our most recent posts, we’ve got a
data source clearly earmarked for just that purpose.
This practice will help you think more carefully about planning your data sources to be flexible and reusable, and in
large projects you’ll always be able to tell exactly what each data source does just by glancing at its name.

Conditions
The conditions tool (Figure 7-5) allows you to add and configure execution conditions for your data source.

Figure 7-5

[f0705.png]

Each condition you add allows you to specify a parameter to test and a state (“is set” or “is empty”), and the data source
will not execute if any of its conditions are met. Data source conditions can help you optimize your views by preventing
unnecessary processing.

Filtering
The filtering tool (Figure 7-6) allows you to add and configure filters to hone your results.

Figure 7-6

[f0706.png]

For each filter you add, you need to specify a field to use. Once you’ve selected a field, you’re presented with a dropdown
of the filtering modes that field offers (a text field, for example, has modes like “matches,” “contains,” “does not contain,”
and so on), and an input for the expression you want to use to filter the results.
We’ll discuss filtering—modes, patterns, syntaxes, and the like—in greater detail below.

Sorting
Sort By allows you to select the field to use for sorting your results. Different field types may have different sorting
rules, so be sure to review the list of field types and their behaviors in Appendix A.
Sort Order allows you to specify how entries will be ordered: ascending, descending, or random. Limiting
Results per page is the number of entries you want the data source to return for each page of results
Page is the page to return, and the field can accept a URL parameter. This allows you to automatically paginate
results simply by using URLs like http://example.com/1/ and http://example.com/2/.
The Redirect to 404 checkbox allows you to have your system respond with a “Page not found” error when no results
have been returned. Output Options
Included fields allows you to specify which fields’ content you want to output and, for some fields, the output mode
(some field types allow you to output either formatted or unformatted text, for instance). You can also choose to
include system fields.
Grouping allows you to optionally choose a field to use for grouping entries. Most field types will just group entries
that have the same value, but some have special grouping rules. Date fields, for example, create a grouping
hierarchy by year, month, and then date. This will be helpful for your archive view, where we want to list entries by
month.
Two additional checkboxes allow you to specify whether you want to output Pagination data and Sorting data for
your results alongside the field content.
Having reviewed all the options available, let’s go ahead and create another data source—the one that’ll return your
individual posts. You should already be looking at a blank data source editor:
1. Make sure “Entries” is selected as the Type

2. For Name, enter Individual Post
3. In the Section dropdown, choose “Blog Posts”
We said that you don’t want the data source to execute if the view’s title parameter is empty, so let’s add that
condition:
4. In the conditions tool, click “Add Condition”
5. In the condition panel (Figure 7-5, above), you’ll see two fields: Parameter and Logic.
6. Enter title in the Parameter field and select “Is Empty” from the Logic dropdown.
Now, this data source is supposed to return the entry whose title is specified in the URL’s title parameter, and then
only if that entry is marked as published. We also want to make sure the entry is in the right category. We’ll need
three filters, then:
7. In the filtering tool, click “Add Filter”
8. In the drawer that appears, click the button for the Published field.
9. In the filter panel (Figure 7-6, above), select “Is” in the Mode dropdown and enter yes in the Value field (or click the
“yes” link beneath the input—some field types give you hints like this if their values are predefined).
10. Click “Add Filter” again.
11. In the drawer that appears, click the button for the Title field.
12. In the filter panel, select “Is” in the Mode dropdown and enter {$title} into the Value field.
Note
You’ll use this sort of syntax a lot when creating data sources and events. It mirrors XPath’s attribute value
template syntax (see Appendix C), which uses curly braces to wrap expressions that need to be evaluated
rather than taken literally, and dollar signs as prefixes for parameters. (Don’t stress out; we’ll talk more about
XPath in Chapter 8).
Let’s imagine your view’s title URL parameter is set to choosing-a-stripper. Here’s how the system would
interpret the following filter values:
| Entering... | ...would filter using the string | | ----------- | -------------------------------- | | title | title | | $title | $title | |
{title} | title | | {$title} | choosing-a-stripper |
We’ll discuss filtering syntax in more detail below.
13. Click “Add Filter” one more time
14. Click the button for the Category field
15. In the filter panel, select “Is” in the Mode dropdown, and enter {$category} into the Value field.
16. You can leave the Sorting options at their defaults. Since we’re only returning one entry, sorting instructions won’t
apply.
17. Enter 1 in the Results Per Page field.
18. Check the box next to “Redirect to 404 when no results are found”. This ensures that if a visitor enters some
nonsensical post title, like http://example.com/painting/i-hate-this-website/, they’ll get bounced to an error page
(where you can scold them for making up nasty URLs).
19. Under “Output Options,” in the Included Elements field, select “Title (Formatted)”, “Body (Formatted)”, “Publish Date”,
and “Category”.
20. [Step to attach DS to Posts view -- this functionality is not fully implemented yet]
21. Click “Create Data Source”
You’ve created a data source called Individual Post that uses the view’s title and category URL parameters to help it find
the right entry, while taking care to filter out posts that are unpublished. It also makes sure that title parameter is actually
set, otherwise there’s no use in it executing. If the requested post isn’t found, the view will redirect to a 404 error page.

Your Post view will now get live entry data when a valid, published post is requested. Go see for yourself. In Chapter 5,
we created a test post titled “My First Post,” and we placed it in the “Journal” category. If you visit
http://example.com/journal/my-first-post/?debug, in the XML source you should see the output of your new data source.
It’ll look something like this:


<individual-post>
<entry id=”1”>
<title handle=”my-first-post”>My First Post</title>

</entry>
</individual-post>


Delivered to the front end and ready for templating.
This data source required you to specify several filters, and I’m sure it’s left you with some unanswered questions about
how exactly this filtering stuff works. Before we go any further, let’s get those questions answered.

Filtering Data Sources
As noted above, every data source type has its own particular methods for filtering the content it fetches. Rather than bog
you down in the details of each one, I’ve collected thorough descriptions of all the core data source types, and their
filtering options, in Appendix B. For our purposes, then, we’ll only look closely at the entries data source type.
When you filter an entries data source you’re essentially telling the system what attributes you want your results to have. If
you think back to Chapter 5, you’ll remember that your contents’ attributes are captured by fields. So filtering a data
source’s results is a matter of identifying the fields you want to filter on, and evaluating their contents to determine
whether a particular entry should be included in the results.
The filtering tool you saw in Figure 7-5 provides a straightforward workflow for doing this: you select the field, select a
filter mode, and enter a value expression.
Note
This probably sounds a lot more complicated than it actually is. In truth, you likely formulate rules like this every day
—when you’re choosing a place to eat lunch, for instance:
Attribute (Field)

Filter Mode

Value Expression

Distance

is within

1 mile

Cost of lunch

is less than

$10

Quality of food

is

yummy

Kitchen

does not contain

roaches, rats, open bottles of poison

Filter Modes
In Chapter 5, I made a big fuss about how important field types are because they enable you to treat distinct kinds of data
differently. This is one of the places where you see this principle in action.
Each field type defines its own filter modes. Text fields, for instance, have modes like “contains” and “regexp” (a regular
expression search). Date fields have modes like “earlier than” or “later than.” A map location field would have some sort
of radius filtering mode.
What each mode does is pretty straightforward, and I don’t imagine you’ll have much trouble figuring out how they work. If
you do have any questions, though, Appendix A lists each of the core field types and the filtering modes it supports.

Value Expressions
While choosing the field and mode for your filter usually takes all of about four seconds, value expressions can be a bit
more challenging. They don’t have to be, though. They’re evaluated using some relatively simple rules, and once you
understand those, you should have no trouble at all creating data source filters for every purpose. Here’s what you need
to know:
By default, expressions are interpreted literally. That means if you enter the word melonhead as a filter’s value
expression, it’s going to test the filtering field in each entry for that exact word.
Anything wrapped in curly braces will be evaluated by the system first. As I’ve mentioned several times, filters have
access to all of the view’s environmental variables (URL parameters, contextual information, and so on). In order to
include dynamic values like these in your expression, they must appear inside curly braces so the system knows to
evaluate them and not use them literally.
Within curly braces, the following rules are used when evaluating expressions:
A dollar sign delimits a parameter. So: {$title} or {$category}.
A colon delimits a fallback option. Entering {$category:programming} is akin to saying, “If the category parameter is
set, use that, otherwise, use the word programming.”
Commas are used as a union operator. They delimit possible matching values that are joined using OR. Entering
programming,football,botany tells the system, “I’m looking for matches to any of these terms, doesn’t matter which one.”
Plus signs are used as an intersection operator. They delimit items in a set of required matching values joined by AND.
So entering food+travel says “I’m looking for matches where the target field contains both of these values.”
As I’ve noted elsewhere, it’s the field types that are ultimately responsible for taking care of the filtering, and they’ll often
provide additional keywords and operators. One example is the range operater to in date and number fields, allowing
you to enter, say, 1 to 10 or 2009-01-01 to 2009-12-31. Consult Appendix A for a breakdown of all core field types and
the operators and keywords they support.
Note
The combination of the curly braces syntax with all the various delimiters and operators can make for all sorts of
possibilities.
The operators, for example, can come from within the dynamic values themselves. Example: you’ll recall that your blog’s
Home view accepts a category parameter. Let’s say you visited http://example.com/writing,reading/. This would set the
value of the category parameter to writing,reading. Which means using {$category} in your filter expression would be
functionally equivalent to using writing,reading.
On the other hand, you could just as easily do something like painting, {$category}. It all depends on your exact use case.
And this applies to field-specific operators too. It’s not uncommon to see expressions like 2011-01-01 to {$today}.
As you see, curly braces and delimiters can also be interspersed with literal text: my-favorite-{$color:black}-websites.

Conditional Filtering
If a filter value expression contains only a parameter, and that parameter isn’t set when the data source is executed, the
filter rule will be completely ignored and the data source will execute as if the filter didn’t exist.
Confused? Hopefully an example will help.
Remember the Recent Posts data source that you created at the beginning of this chapter? The plan for your Home view
was that it’d be filterable using a URL parameter called category. You wanted visitors to be able to view all posts at
http://example.com, but then drill down to categories like http://example.com/journal/ or http://example.com/painting/.
Because the sorting and pagination logic is that same, it’d be nice to be able to use one data source for all of these

interfaces.
Because of conditional filtering, we can add the category filter to your Recent Posts data source, and if category is not set,
it’ll just be ignored:
1. Go to Blueprints > Data Sources and click on the “Recent Posts” data source you created earlier.
2. In the filtering tool, click “Add Filter”
3. Click the button for the Category field
4. Leave “Is” selected in the Mode dropdown and enter {$category} in the Value field.
5. Click “Save Changes”
This allows you to create an additional layer of conditionality without having to duplicate any structure or logic. If the
parameter is set, the filter will be applied. If not, it’ll be ignored. One data source, as many interfaces as you have
categories.
Let’s finish our discussion of filtering by creating another of your blog’s data sources, this one for its archive functionality:
1. Go to Blueprints > Data Sources and click “Create New”
2. Name your data source Posts by Date
3. In the section dropdown, choose “Blog Posts”
4. In the filtering tool, click “Add Filter”
5. In the drawer that appears, click the button for the Published field.
6. In the filter panel, select “Is” in the Mode dropdown and enter yes in the Value field (or click the “yes” link beneath the
input).
7. Click “Add Filter” again.
8. In the drawer that appears, click the button for the Publish Date field.
9. In the filter panel, select “Is” in the Mode dropdown and enter {$year:$this-year}-{$month}
10. In Sort By, select “Publish Date” and in Sort Order select “descending”
11. In the “Output Options” section, in the Group By dropdown, select “Publish Date.” This will group the result entries first
by year, then month, and then date.
12. [[Attach to view]]
13. Click “Create Data Source”
This data source uses a date field to filter entries based on the value of two URL parameters: year and month. Year
defaults to the current, meaning if the value is not specified in the URL (i.e. a visitor simply goes to
http://example.com/archive/), it’ll show entries for this year. Month, on the other hand, has no fallback. If it’s not provided,
the data source will simply filter by year alone.
Let’s make sure it’s working. Visit http://example.com/archive/?debug. You should see your sample entries again in the
source XML, only this time you’ll only see the titles, and they’ll be nested further down in the hierarchy, because you’ve
grouped the results by date.
That leaves us with just one more data source to build.

Chaining Data Sources
Very often, you’ll want to filter one of your data sources using data that’s been output from another. Such is the case with
your blog’s comments. In order to fetch the comments for an individual post, you need to filter the comments entries using
the ID of the post itself. This is not information that’s defined by the view or in a URL parameter, though. It is returned by
the Individual Post data source. We need to use that data source’s output to filter our new Post Comments data source:
1. Go to Blueprints > Data Sources and click the green “Create New” button
2. Name your data source Post Comments
3. In the Section dropdown, select “Comments”
4. In the filtering tool, click “Add Filter”
5. Click the button for the Post field
6. Leave the Mode dropdown set to “Is” and enter {/individual-post/entry/@id}
7. In the Sort By dropdown, select “Date”

8. For Sort Order, choose “ascending.” We want older comments at the bottom.
9. We want to include all comments with the post, so uncheck the Paginate Results box.
10. [[Step to define dependencies??]]
11. [[Attach to view]]
12. Click “Create Data Source”
Using a piece of output from one data source for filtering in another is called “data source chaining.” With this technique,
multiple data sources can be linked together, each depending on the results of the one before. This can add a great deal
of dynamism to your interfaces.
Data source chains can be one-to-many in either direction. Several dependent data sources can be chained to the same
primary data source, and a single dependent data source can be filtered using results from multiple primary data sources.
Again, let’s go back and check our results. The first thing we’ll need to do is add a test comment. Because we’ve not set
up commenting on the front end yet, we’ll just do this in the admin interface.
1. Go to Content > Comments
2. Click “Create New”
3. Enter your name and email address in the appropriate fields, and then enter a comment
4. In the Post field, select “My First Post”
5. Click “Save Entry”
Now, check out http://example.com/journal/my-first-post/?debug. You should see your comment listed there in the source
XML.
Now that you’ve been through the ins and outs of how data sources work, let’s move on to discuss events.

Working with Events
Events are managed in the admin interface at Blueprints > Events.
Note
Events, like data sources, are stored as PHP files in your workspace. The same ideas apply: easy to version
control, easy to reuse between projects, not trivial to edit directly or customize unless you’re comfortable with PHP.

Creating and Editing Events
As with data sources, the first step in creating an event is to choose its type. By default, there are X core event types that
are included with the base package of Symphony. The one you’ll use most often is the entry-saving event type, and we’ll
cover that in depth here. The rest of the event types are described in Appendix D.
Entry-saving Events and Form Submission
Entry-saving events allow content to be submitted and saved to your sections from the front end. Symphony-powered
web applications rely on this functionality for nearly everything, but even simple sites use entry-saving events for things
like contact forms, comment submission, and so on.
Entry-saving events specify a section and a set of options and then, once attached to a view, will process POST data
submitted to that view.
Note
If you don’t know what POST data is, you should read up on it. Here’s a quick summary though. Browsers and other
clients can make different types of requests to a server. The most common are GET and POST. When you enter a
URL into your browser, the browser makes a GET request at that URL and waits for data to be sent back. When you
submit a form, on the other hand, the browser takes the data you entered and sends a POST request to submit that
data to the server.
You need to create an event that saves comments, so that people reading your blog posts will be able to submit
comments from the front end.
1. Go to Blueprints > Events
2. Click the green “Create New” button. You’ll see the event editor (Figure 7-#). Figure 7-# [f070#.png]
3. Name your event Save Comment
4. In the Section dropdown, choose “Comments”

Event Options
The next section of the event editor allows you to specify options for the event, which you’ll recall from earlier allow you to
adjust a particular event’s behavior with additional actions, conditions, and the like.
The base package of Symphony ships with the following event options:
[[This functionality is not fully implemented or defined]]
Let’s assume that you want to receive an email notification whenever someone leaves a comment on your blog. Let’s
also assume you want to protect your blog against common cross-site scripting attacks. All you have to do is add these
two options to your event.
1. In the Options multiselect, choose the “Send Email” option and the “XSS Filter” option.

Defaults and Overrides

Because entry-saving events rely on user submissions from the front end, you’ll want to take other kinds of precautions
with your data too. There’s no stopping a malicious visitor from manually changing names or values in your form markup
to try to save unwanted or potentially harmful data to your system.
Thankfully, Symphony gives you a way to prevent this. You can specify default values and override values for any field.
Default values will be used if no value is submitted for the field. This allows you to specify a fallback if your users skip a
field. Override values are used no matter what users submit. This allows you to prevent users from forcing in data you
don’t want.
For our purposes, we’re capturing five fields. Three will be provided by the user: Name, Email, and Comment. The other
two, Date and Post, we’ll specify as overrides. This will keep malicious users from trying to manually specify values that
they shouldn’t:
1. In the Overrides and defaults tool, click “Add Item.”
2. In the Type dropdown, select “Override”
3. In the Field dropdown, select “Date”
4. In the Value field, enter {/data/context/date}
5. Click “Add Item” again
6. In the Field dropdown, select “Post”
7. In the Value field, enter {/data/individual-post/entry/@id}
8. [[Step to attach event to view]]
9. Click “Create Event”
Now, no matter what data is submitted, every comment’s Date field will be populated with the current date, and the Post
field will be populated with the ID of the post being viewed.

Form Markup
Once you save your event, you’ll be provided with sample form HTML. You could simply copy and paste this into your
template, but you should know the basic syntax that’s at work here. Entry-saving events rely on fields in the POST data
following a naming convention: fields[field-name]. Here’s an example:

<input type=”text” name=”fields[email]” />
<textarea name=”fields[comment]”></textarea>

You can use whatever kinds of form elements you like. The only other requirement is that the name of the input used to
submit the event contains the event’s handle: action[event-handle]. In your case, then:

<input type=”submit” name=”action[save-comment]” value=”Submit”/>

We’ll leave it at that for now. You’ll finish setting this up in the next chapter.

Summary
In this chapter you were introduced to the concept of data flow—the transactions and exchanges between websites and
their users that make interactions possible on the web. We talked about data flow being defined by infrastructures and by
logic, and you learned that, in Symphony, designing data flows means:
identifying the data needs of each of your interfaces
building the infrastructure to manage that data
designing the logic that will make it all work
You were then introduced to the two elements that regulate data flow in a Symphony website—data sources and events.
You learned ins and outs of each, and you went on to build out the infrastructure that will be responsible for managing the
flow of data for your blog.
You were also introduced, briefly, to Symphony’s debug devkit, which allowed you to check your work and verify that your
content is indeed making its way to the front end.
It is, and that means that your crash course is almost complete. You started by learning how to model content in
Symphony, then how to define front end architecture. Now you’ve learned how to set these structures in motion and
channel data to and from your interfaces.
There’s just one big piece left to the puzzle: what your visitors will actually see.

Chapter 8: Templating
What’s in This Chapter
Understanding Templating in Symphony
An Introduction to XSLT
Working with View Templates and XSLT Utilities
This is it. There’s only one thing standing between you and your first fully-functioning Symphony website. Your content’s
been sculpted. Your front end is in place and is fielding requests. Data is flowing. All that remains is to give your blog a
face, to turn it into something that people can actually use.
In this chapter, you’ll learn how to template a Symphony website—in other words, how to define the output that will be
returned to your visitors. Most often, you’ll be outputting HTML pages, but not always. You can also output Atom feeds,
JSON documents, raw XML, or pretty much any other text-based format you can imagine. For the sake of your modest
blog project, though, we’ll stick to plain old XHTML (XML-flavored HTML), at least for now.
This chapter’s going to be a little more challenging than the previous few. Although Symphony’s templating layer is
structurally very simple, conceptually it’s different than systems you may have encountered elsewhere. On top of that, it’s
powered by XSLT, which is a language unto itself (and one you may know nothing about). But just because it’s going to
be challenging doesn’t mean it can’t be fun. In fact, if I do my job well, you’ll leave this chapter excited about XSLT and
eager to learn more.
We’ll start by talking about that conceptual difference, then, in order to explain the unique approach that Symphony takes
to templating. After that, I’ll outline the components involved in Symphony’s templating layer (which should be easy—
there are only two), and then we’ll dive right into XSLT itself. That’s a book-length topic in its own right, but I’d like to teach
you enough that you feel comfortable following along with the remainder of this book. A lot of Symphony’s punch comes
straight from this wonderful templating language. Once we’ve gotten through all that, we’ll finish up by writing the
templates that will give your new blog a face, even if it’s a fairly plain one.
Note
Until now, I’ve tried to avoid making too many assumptions about how much web development experience you
have. This is the exception. I need to be able to trust that you know at least the basics of HTML. If you don’t, I worry
that this chapter might be a bit overwhelming for you.
If you’re not confident in your HTML knowledge or think you could use a refresher (or if you’ve never even heard of HTML
and at first glance figured it was a leftist political party in Honduras), then it’s probably a good idea to set this book aside
for a day and read through a quick introduction to HTML. The folks at

http://htmldog.com

have an excellent HTML

Beginner tutorial.
Before we get started exploring Symphony’s templating layer, though, let’s try a sample exercise to get your feet wet.
1. Go to Framework > Views
2. Click "Home" to edit your Home view
3. You’ll see two tabs in the view editor, "Configuration" and "Template" (Figure 8-1)

Figure 8-1

[f0801.png]

4. Click "Template"
The view template editor is fairly simple (Figure 8-2). It contains a large textarea for your template code, and a list of
available XSLT utilities (more on those later).

Figure 8-2

[f0802.png]

By default, Symphony generates a simple starter template for each new view—just a placeholder that outputs an
XHTML page with some basic info about the view and its data. Don’t panic if any of the code scares you. By the end
of this chapter, you’ll be comfortable with all of it.
The starter template looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/ xhtml1-strict.dtd"
omit-xml-declaration="yes"
encoding="UTF-8"
indent="yes" />
<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="context/website/name"/></title>
</head>
<body>
<h1><xsl:value-of select="context/view/title"/></h1>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

On the whole the syntax should feel vaguely familiar, and if you’ve got a keen eye you’ll notice some HTML in there.
For now, we’re just going to make some very simple changes to this template so it will output the entry titles being
returned by your Recent Posts data source.
5. Just below the line containing

<h1><xsl:value-of select="data/context/view/title"/></h1>

, enter:

<h2>Recent Posts</h2>
<ul>
<xsl:apply-templates select="recent-posts/entry"/>
</ul>

Translation
"Output a second-level header ( h2 ) element containing the text Recent Posts, followed by an unordered list
( ul ) element. Inside the unordered list, I want you to apply templates to the entry items being returned by my
Recent Posts data source."
6. Now, after

</xsl:template>

and before

</xsl:stylesheet>

, enter:

<xsl:template match="recent-posts/entry">
<li>
<xsl:value-of select="title"/>
</li>
</xsl:template>

Translation
"Here’s the template I want you to use for those entry items. Just create a list item ( li ) element and inside it
output the entry’s title."
Your final template should look like this (I’ve emphasized the bits I asked you to add):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/ xhtml1-strict.dtd"
omit-xml-declaration="yes"
encoding="UTF-8"
indent="yes" />
<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="context/website/name"/></title>
</head>
<body>
<h1><xsl:value-of select="context/view/title"/></h1>
<h2>Recent Posts</h2>
<ul>
<xsl:apply-templates select="recent-posts/entry"/>
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="recent-posts/entry">
<li>
<xsl:value-of select="title"/>
</li>
</xsl:template>
</xsl:stylesheet>

7. Click "Save Changes"
If you visit your Home view now, you should see something like Figure 8-3.

Figure 8-3

[f0803.png]

It’s pretty barebones at the moment, I’ll admit, but it’s something. The content that you modeled and created yourself back
in Chapter 5 has finally found its way to your adoring public.
Now, if you’ve never seen XML or XSLT before, that exercise might have been a little intimidating. Don’t worry. Like me,
it’s actually far simpler than it looks. Before we get into figuring out how to crack all that code, though, let’s review exactly
how templating works in Symphony.

What is Templating?
Loosely speaking, templating is how a web application prepares the output that it will render to its users. There are lots of
different kinds of web templating systems out there, each with its own virtues (and shortcomings), but the majority of them
can probably be said to take one of two approaches:
The first, which we'll call "parsed output," allows you to write your output directly (in HTML template files, for
instance), adding in dynamic bits via specialized tags or bits of procedural code. The system then parses the
template, evaluates the dynamic bits, and outputs the result.
The other approach, which we'll call "programmed output," allows you to write code that will generate the output
you're after using the system's native programming language.
Of course, this is an oversimplification, and there are certainly exceptions, but in my experience these do seem to be the
dominant paradigms. If you've done any web development before, chances are you're familiar with one or both of them.
The parsed output approach has the benefit of being fairly simple and easier for beginners to grasp. If you already know
how to write HTML, for example, you can can just whip up your templates as normal and then drop in a few copied-andpasted tags where necessary.
The programmed output approach, on the other hand, is very powerful, because you can lean on the full capabilities of a
robust programming language like PHP, Python, or Ruby. If you know the language well, you can do pretty much
anything you want in the course of generating your output.
Both can and have been used to great effect, but they usually have significant drawbacks too. Parsed output, for example,
tends to be very limited, both in terms of the data you can access and what you’re able to do with it. These systems often
rely on a narrowly-defined custom syntax or set of functions that’s fairly shallow and not useful in other contexts.
Programmed output, on the other hand, has a pretty high barrier of entry for designers and other non-programmers. More
importantly, though, it subjects you to the procedural constraints of languages that aren’t really designed for templating.
These kinds of systems can easily get messy because often there is no clear distinction between the presentation logic
and, well, everything else.
Whichever approach they take, the vast majority of web templating systems make it difficult or impossible to intelligently
organize and reuse code, and they nearly always leave their dirty little fingerprints all over your output. As a result, in
many systems, templating on the whole can often feel like an afterthought—something pieced together and tacked onto a
system just to allow its content to be turned into HTML and decorated.
Symphony’s approach doesn’t really fall on this spectrum. It’s a radically different tack, one you might call "transformed
output." With it, you craft a standalone system of stylesheets with rules for turning the raw data delivered by the system
into some sort of digestible format. So rather than having you write output laced with procedural code, or procedural code
laced with output, Symphony's templating system is an entirely self-contained layer, powered by a language that was
designed just for templating (XSLT).
This can be a little disorienting if you're accustomed to other kinds of systems, and it isn't without its own drawbacks. For
starters, XSLT can involve a bigger learning curve than simple tag-based template syntaxes, and it's more verbose
(although some people like that about it). There are also things that XSLT can't do as easily as a full-fledged
programming language can.
That said, though, the benefits of a transformed output approach far outweigh these minor gripes. First of all, you have
complete, unfettered access to all the raw data you need to craft your presentation. Also, as I said above, the templating
layer is completely self-contained, which means it’s clean and lean, and the system can’t interfere with your output in any
way. This self-containment also means that your code can be organized elegantly and reused. Finally, and perhaps most
importantly, you get all the benefits of a dedicated, open templating language in XSLT. We’ll talk about what those
benefits are in a moment.
So what does Symphony’s implementation of this approach look like?

Understanding Templating in Symphony
As you’ve seen, when someone visits your Symphony site's front end, a view handles their request and goes on to build
the XML data that will power the view and its interactions. But this isn't what gets delivered to your visitor. Instead, it’s left
entirely up to the templating layer to transform that raw data into some sort of usable output.
The templating layer is made up of view templates and XSLT utilities. Every view has an accompanying view template
that it uses to transform its source XML. XSLT utilities are more generic and can be included in these transformations at
will. Figure 8-4 illustrates the templating process:

Figure 8-4

[f0804.png]

Both view templates and XSLT utilities are simply vanilla XSLT stylesheets. No custom syntax or special processing
required. So in order to understand how Symphony’s templating system works, you just need to understand how XSLT
works.
To help you get there, I'm going to whisk you through a basic introduction to XSLT at neck-breaking speed. I hope you’re
wearing a helmet. (Not because you need protection, though. It’s just funny to imagine you reading this book with a
helmet on.)
Ok, ready?

Understanding XSLT
XSLT is the keystone in a trio of languages developed to transform and format XML. Collectively, those languages are
known as XSL, or Extensible Stylesheet Language.
Each member of the XSL family has a specific role:
XSLT, or XSL Transformations, is used to transform XML data into other kinds of output.
XPath, or XML Path Language, is used to identify nodes in an XML document for transformation or formatting.
XSL-FO, or XSL Formatting Objects, is a presentational language used for formatting XML data, usually for print.
In the Symphony context, we only need to talk about the first two. XSL-FO can be useful for things like PDF-generation,
but that sort of thing is a bit advanced for this book.
Though the usage of XSLT as a web templating language is not exactly commonplace, there are lots of factors that make
it ideal for this exact purpose. Here’s a handful of them:
It’s an XML technology. This means native handling of every web feed, every XHTML page, every RDF format, and
nearly every API that exists on the web.
It’s an open standard. Maintained by the world’s web standards body (W3C), XSLT is widely-used, widelysupported, and well-documented. You won’t have trouble finding resources or getting answers, and once you’ve
learned XSLT it can be helpful anywhere XML is used (which is pretty much everywhere).
It’s content-driven. Everything you output is directly tied to the data you need to present, meaning your presentation
can always be lean and semantic.
It’s rule-based. Rules are much more powerful than mixtures of markup and procedural code. They are distinct and
self-contained, but can also have complex relationships and interdependencies.
It’s flexible. XSLT can output nearly any text-based format there is, even ones that haven’t been invented yet.
It’s a complete templating language. With XSLT you can craft an organized, coherent presentation system rather
than cobbling pages together out of snippets and tags using languages like PHP.
In short, XSLT is what one might call "awesomecake," and after reading about all the ways it can make your life easier,
there’s a good chance you’re standing up doing fist pumps right now. With your helmet on. Which is fantastic.
So here’s how it all works...
XSLT defines sets of instructions that are used to transform source XML and create some kind of output (Figure 8-5).

Figure 8-5

[f0805.png]

Let’s look at a few very simplistic examples of this process to give you an idea of what I mean. Just try to follow along as
best you can, but don’t panic if anything confuses you—we’ll go through it all in more detail below.
Imagine that you have the following XML content:

<book>
<title>Symphony Start to Finish</title>
<author>Craig Zheng</author>
</book>

We’ll assume you don’t need to do anything fancy with it—you just want to output the book’s title. In your XSLT stylesheet,
the first thing you’d do is write a template rule that matches that book element:

<xsl:template match="book">
… do stuff …
</xsl:template>

Now anything you put inside this template will be used to generate output when that element gets processed. Since you
just want to spit out the book’s title, you’d write:

<xsl:template match="book">
<xsl:value-of select="title"/>
</xsl:template>

That template, applied to the XML above, would just output the text from the title element:

Symphony Start to Finish

And if you wanted to output XML or HTML, you would do something like this:

<xsl:template match="book">
<h1><xsl:value-of select="title"/></h1>
</xsl:template>

That transformation would get you this output:

<h1>Symphony Start to Finish</h1>

Not too bad so far, right? Before we get into the nitty gritty details of the language, let’s step back and review what’s
actually going on during an XSLT transformation.

How Transformations Work
Imagine you’re my personal assistant (I’m liking this example already). I have several stacks of unorganized books, and I
want you to help me create a catalog. So I ask you to sift through the books, one by one, and do the following:
Enter each book’s details—title, author, publisher, year, and subject—into a row in a spreadsheet
Scan the cover and save the resulting image to my hard drive
What I’ve done is I’ve asked you to process a bunch of content, and I’ve given you some instructions telling you what to
do for each item you come across. When you’re finished, I’ll have a nifty spreadsheet and a stack of cover images.
This is more or less how XSLT works. A processor starts with some XML content, and as it parses that content, it uses
instructions from an XSLT stylesheet to generate some other sort of output.
When you write XSLT stylesheets, then, you’re essentially creating systems of rules and instructions.
Note
If you’re familiar with other programming languages, this might take some getting used to. Many common
programming languages are imperative—they issue lots of commands, one after the other. And as you saw above,
lots of web developers are accustomed to systems that rely on imperative languages for templating—they might
even begin to think about building output as a series of commands: First include the head, then loop through
entries, then include this other snippet...
XSLT, on the other hand, is a declarative language. Instead of issuing commands, it simply states what should be
done in a given context. It’s rather similar to CSS in that way. Neither language describes a sequence of events or
functions. They just say, "Hey, when you come across this element, this is how you should style/transform it."
Templating with this kind of rule-based language takes a different sort of mindset, but it’s actually a much more
powerful and flexible approach. A list of commands can only be followed, but rules can have scope and
interdependencies, they can cascade, they can override one another.
You might not fully understand what I mean here, and as I said above, this is really a book-length topic of its own.
My hope is just that by the end of this book you’ll have seen enough of XSLT’s power as a web templating
language that you’ll want to go and spend a little bit of time learning it in earnest.
Now that you’ve gotten an overview, let’s walk through what’s happening during one of these transformations. I’ll begin
by explaining how an XSLT processor sees and interprets its source XML. Then we’ll talk about how a stylesheet’s
instructions are applied and what they can do. We’ll finish up with a brief review of stylesheet structure and organization.

Parsing XML
The first thing the processor does during a transformation is load the source XML. It needs to parse all of the data into a
document tree—a hierarchy of identifiable bits called nodes—so that the stylesheet can work with it. Let’s look at how
XML data is broken down.
Note
We’ll stick to the basics here—if you want a detailed history of the language or a thorough breakdown, there are
much better places to get it than this. We’re just going to concern ourselves with what you need to know in order to
grasp the fundamentals of XSLT.
XML is a markup language, which basically means that you use it to describe content in some way. For example, look at
this text:

Amazon

That could be any of a half-dozen things—the internet company, the rainforest, the mythical tribe of female warriors. So
let’s use XML to mark it up:

<river>Amazon</river>

Ok, now the text has got some meaning attached to it. You’re no longer just looking at some ambiguous word but at a
meaningful XML element.
At its very simplest, XML is made up of elements like this—just various things that exist in the universe of a particular XML
document. A menu, for example, might have elements like dish and beverage, while a real estate listing might have
elements like house or apartment.
Elements are identified by tags. In the example above, and are the tags. One opens the element, the other closes it—
anything in between is the element’s content. Elements can have textual content, as above, or can contain child
elements, like this:

<river>
<name>Amazon</name>
</river>

If an element hasn’t got any content at all, the opening tag can simply close itself:

<river />

Elements can also have attributes—key-value pairs that store additional information for the element:

<river continent="South America" miles="4200">Amazon</river>

Taken all together, the basic ingredients of XML syntax are pretty straightforward:

<element-name attribute="value">text content</element-name>

Each of them—elements, attributes, and text—is a different kind of node that can be identified and processed during an
XSLT transformation.
Now, if you’ve ever written any HTML in your life, all of this should look pretty familiar. If not, I’m fairly certain you won’t
have any trouble catching on. After all, the syntax, by definition, is descriptive. Let’s imagine what a house might look like,
for example, if we described it with XML:

<house color="yellow" square-feet="2560" style="colonial">
<room square-feet="420" type="kitchen"/>
<room square-feet="660" type="bedroom"/>
...
</house>

Not too difficult, right? We’ve got a house element with a few descriptive attributes and a couple of room elements for
children.
Now let’s look at a snippet of the XML that your Recent Posts data source is providing to your Home view:

<recent-posts>
<entry id="2">
<title handle="my-second-post">My Second Post</title>
<category handle="journal">Journal</category>
<publish-date>2011-01-21</publish-date>
</entry>
<entry id="1">
<title handle="my-first-post">My First Post</title>
<category handle="journal">Journal</category>
<publish-date>2011-01-19</publish-date>
</entry>
</recent-posts>

If you can parse the above and identify the two entries and the various nodes that comprise them, then congratulations...
you’re already conversant in XML! (You must have a really fantastic teacher.) And you’ll be glad to know that XSLT is
itself an XML format, which means you already have a basic understanding of its syntax!
Note
This is all simplified, of course. There are lots of little rules and wrinkles that you’ll have to learn. For instance, XML
is a very strict language and most use cases require it to be well-formed—meaning elements must be nested
properly, closed properly, contain only valid characters, and so on. But we’ll cover most of those rules as we go
along. No need to get bogged down right now.
So, as I was saying above, once the XSLT processor loads an XML source document, it begins stepping through its
nodes, one by one. Let’s look at the XML for your Home view to see how this works. You can see the source for yourself
at

http://example.com/?debug

, but I’ll paste a sample here for reference:

<data>
<context>
<view>
<title>Home</title>
<handle>home</handle>
<path>/</path>
<current-url>http://example.com/</current-url>
</view>
<system>
<site-name>Tales of a Highway Bandit Hacker</site-name>
<site-url>http://example.com</site-url>
<admin-url> http://example.com/symphony</admin-url>
<symphony-version>3.0</symphony-version>
</system>
<date>
<today>2011-01-25</today>
<current-time>19:03</current-time>
<this-year>2011</this-year>
<this-month>01</this-month>
<this-day>25</this-day>
<timezone>America/New_York</timezone>
</date>
...
</context>
<recent-posts section="blog-posts">
<entry id="2">
<title mode="formatted" handle="my-second-entry">My Second entry</title>
<body mode="formatted">is flavored like potato.</body>
<publish-date time="15:38" weekday="6">2011-02-12</publish-date>
<category handle="journal">Journal</category>
</entry>
<entry id="1">
<title mode="formatted" handle="my-first-entry">My First Entry</title>
<body mode="formatted">Is flavored like awesomesauce</body>
<publish-date time="15:38" weekday="3">2011-01-12</publish-date>
<category handle="journal">Journal</category>
</entry>
</recent-posts>
</data>

The processor starts at the root (or document) node, which is a node that contains the entire source tree. It then
processes the top-most element (in this case,

data

), and begins working through its children one by one. First up would

be the context element—the processor would crawl down through each of its descendants ( view ,
system

,

site-name

, and so on). Then it would proceed to the

data

title

,

handle

,

path



element and crawl through its descendants, and their

attributes and contents.
As it’s stepping through XML like this, the processor checks the stylesheet for any instructions that it should apply to a
particular node in order to generate output.
Let’s talk about how those instructions work.

Templates
Templates are where all of the action happens, as you saw in some of the simple examples above. They are the real
meat of an XSLT stylesheet, and they define most of what happens during a transformation—building output, specifying
logic, routing the processor, and so on.
There are two types of templates, template rules (sometimes called "matching templates") and named templates. Both are
defined using

xsl:template

elements. The stylesheet you’re using to transform the XML above has two templates in it:

<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="data/context/website/name"/></title>
</head>
<body>
<h1><xsl:value-of select="data/context/view/title"/></h1>
<h2>Recent Posts</h2>
<ul>
<xsl:apply-templates select="data/recent-posts/entry"/>
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="recent-posts/entry">
<li>
<xsl:value-of select="title"/>
</li>
</xsl:template>

Both of these are template rules—they specify the nodes to which they should be applied using a pattern in their match
attribute (more on those patterns in a moment). When the processor reaches nodes that match the pattern, it follows the
instructions provided by the template. Template rules can have more than one match pattern (they’re separated by the
pipe character, | ), meaning the same template can be used to process different node-sets.
The other kind of template, the named template, isn’t matched to the source tree but rather is invoked explicitly. We’ll
discuss these more in depth a bit later.
Note
If you’re accustomed to writing CSS rules, which have a selector and then a set of declarations, template rules are
sort of an analogous structure. The match attribute contains the "selector," and then the template contains details
about how the selected node is to be handled:

<xsl:template match="recent-posts/entry">
… do stuff …
</xsl:template>

Template rules are matched to source nodes using XPath patterns. Let’s look at the two that are used in the stylesheet
above:

/

and

recent-posts/entry

Each of these patterns is used to match the template to a particular node or node-set in the source XML. The first matches
the root node; the second matches entry elements that are children of a recent-posts element.
A great deal of what templates do depends on being able to select or match nodes in the source tree like this, so let’s
take a quick detour into the world of XPath so you can get a sense of how these expressions work.
Note
The debug devkit actually allows you to test XPath expressions live on your source XML. If you go to
http://example.com/?debug

, you’ll see an XPath expression bar (it’s got

//*

in it by default). Any XPath expression

you type into that bar will highlight the matching node or nodes in the source XML. It’s a tremendously helpful tool
for learning XPath. As we walk through the various kinds of XPath expressions in this section, feel free to test them
out. You can also experiment with expressions of your own to get a sense of what works and what doesn’t.

XPath: A Crash Course
XPath is designed specifically to enable you to identify nodes or node-sets in an XML tree. There are several types of
nodes, as you’ve seen: the root node, element nodes, attribute nodes, and text nodes (along with a few others that aren’t
really important for us at the moment).
XSLT transformations rely on XPath extensively, because you have to identify nodes in the source tree in all kinds of
contexts—when you’re defining template rules, when you’re grabbing and manipulating source content, when you’re
giving instructions to the processor, and so on.
Thankfully, XPath provides a very powerful and versatile syntax for building all kinds of expressions. Expressions allow
you to pinpoint nodes based on their location, their node type, and even their contents and values.
Note
Patterns, like the ones you saw above, are a subset of XPath expressions that are used in specific contexts (like
template match attributes). While expressions as a whole are written to target particular nodes in a source tree,
patterns allow you to specify conditions that you want nodes to meet in order to be considered a match. The
difference is subtle, but it can be important. You’ll see why in a moment.
Selecting Nodes by Location
The simplest kind of expression is a path expression, which is used to select nodes based on where they are in the tree.
These will look familiar to you because they work very much like filesystem paths and URLs.
If you look back at your home view’s XML, for example, you could select the current date with the following expression:

/context/date/today

Easy enough, right? Each bit is the name of an element, and each slash indicates a level in the hierarchy.
Note

Path Expressions and Context

When you’re describing locations like this, context becomes an important factor.
Patterns are not evaluated relative to any context because they’re just general conditions that nodes need to
match. So something like
match="recent-posts/entry"

match="entry"

will apply to any entry element in the entire source tree, and

will apply to all entry elements that are a child of a recent-posts element.

Expressions in general, though, are evaluated relative to the node being processed. So if you have a template rule
that matches

/context/date

expressions like

entry

, any XPath you use inside that template has to be relative to the date element. Path

and

wouldn’t work because those elements don’t exist inside the date

recent-posts/entry

element.
When you’re dealing with relative paths like this, you have to be able to move around the source tree. XPath makes
this possible with axes (this is an advanced topic, so I’ll just give you the highlights and you can read up on your
own). There are 13 axes, among them

parent::

,

ancestor::

,

following::

, and so on. Each allows you to

child::entry ). The

other axes enable you to select

descendent::

,

navigate through the source tree in a different way.
The default axis in XPath is

child::

(meaning entry is the same as

nodes that are not children or direct descendents of the current context node.
Many axes have shorthand equivalents, so
//entry

is the same as

../context

descendent-or-self::entry

is the same as

parent::context

(just like in a file system), and

(it’ll look for entry elements at any depth from the context node).

Aside from using axes, the other way to sidestep the current node’s context is to make an expression root-relative
by preceding it with a forward slash:

/context

. You can then build your expression to target a node based on its

location from the root.
These path expressions should be pretty intuitive, and I’m sure you’ll pick them up quickly, so I’ll leave it at that for now.
Selecting Nodes by Type
The expressions we’ve seen so far only match element nodes. You can select attribute nodes and text nodes just as
easily, though. To target an attribute node, you just prepend

@

before its name:

@id

. In a path expression, an element’s

attributes go at the same level in the hierarchy as its children:

//entry/@id

There are also times when you don’t want to select an entire element, only its text content. In that case, you’d use text() to
specifically target the text node:

/context/view/title/text()

Selecting Nodes by Condition
You can also select nodes based on various conditions. Let’s say, for instance, that you only want to select the Recent
Posts entry element whose id attribute is 2:

/data/recent-posts/entry[@id = ‘2’]

Or you only want to select the last entry in the source:

//entry[last()]

The part of the expression that appears in brackets is called a predicate. Predicates allow you to specify additional
conditions for selecting a node. The predicate doesn’t always have to come at the end of the expression, either:

/data/recent-posts/entry[@id = 2]/title/@handle

Cool, huh?
There’s a lot more to XPath than this—the

*

wildcard, for instance, and functions like

position()

,

count()

, and

substring()

,

but we’ll continue to flesh that stuff out over the rest of the book. This should be enough for now.
If you’ve done much web development, hopefully XPath syntax feels sort of natural to you. It’s actually not unlike many
other selector languages, and the very popular jQuery framework actually supports some XPath syntax itself. If you’re
confused, though, you might want to read up a bit on your own before we get into more advanced XSLT techniques in
later chapters.
Anyway, now that you’ve gotten a rundown of XPath syntax, let’s get back to the task at hand—explaining the role that
templates play in an XSLT transformation.

What Templates Can Do
A processor takes nearly all of its instructions from templates, so they’ve got to be able to do everything from establishing
the structure of an output document and defining processing logic to grabbing, manipulating, and outputting data.
Control Processor Flow
One of the most important things a template can do is organize output and control processor flow during a transformation.
You see this at work in your Home view template.
You’ll recall that, above, I said that an XSLT processor steps through a source tree node by node. That’s its default
behavior. XSLT also specifies a default template (used when it can’t find a matching template for the node it’s
processing). The default template essentially just spits out any text content it finds.
If those are both default behaviors, why isn’t all the text in your Home view’s source XML just dumped out onto the page?
The key is that, when the processor does find a template to apply, it defers to the template to tell it what to do. So that first
template rule in your stylesheet, the one that matches the root node ( match="/" ), effectively seizes control of the entire
transformation from the outset. If you were to write an empty template rule matching the root node:

<xsl:template match="/">
</xsl:template>

the processor would simply stop there and output nothing at all. It wouldn’t step through any of remaining nodes unless
you told it to.
In your Home view template, then, the first template rule matches the root node and stops the processor from going about
its normal business. Then it builds the overall structure for an XHTML page, and explicitly tells the processor where and
how to proceed using the xsl:apply-templates element:

<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="data/context/website/name"/></title>
</head>
<body>
<h1><xsl:value-of select="data/context/view/title"/></h1>
<h2>Recent Posts</h2>
<ul>
<xsl:apply-templates select="data/recent-posts/entry"/>
</ul>
</body>
</html>
</xsl:template>

If used without a

select

attribute (i.e. just

<xsl:apply-templates/>

), this element would just send the processor back on its

merry way, to resume its normal processing flow. In the example above, though, you actually don’t want it crawling
through all of the XML; you have a specific template you want it to apply in a very specific place, so you direct it to the
nodes that match that template.
Note
<xsl:apply-templates>

is only one way for a template to direct the processor. You can also iterate over nodes using .

In fact, the stylesheet we’ve been talking about could’ve been written with only one template:

<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="data/context/website/name"/></title>
</head>
<body>
<h1><xsl:value-of select="data/context/view/title"/></h1>
<h2>Recent Posts</h2>
<ul>
<xsl:for-each select="data/recent-posts/entry">
<li>
<xsl:value-of select="title"/>
</li>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>

This would produce the same output, but it’s generally not as flexible. In most cases, it’s better to handle different kinds of
source content using discrete templates. This way, your code is easier to maintain and reuse (even if the structure of the
source XML changes).
This may seem like a roundabout way to achieve your desired output structure, but the point is that it’s content-centric and
imminently modular. As you continue to learn and use XSLT, you’ll come to appreciate how powerful this system can be.
Write Output
As you’ve seen, templates are also responsible for building the output that will result from a transformation.
One of the most basic things you can do in a template is to specify output directly. If you’re building an XML document,
this output can come in the form of literal result elements. All this means is that you actually just put the elements you
want in your output directly into the template. This is what you’ve done in the example above—the
<body>

,

<h1>

,

<ul>

<html>

,

<head>

, and so on… all of these are literal result elements.

You can also write plain text content or build nodes for your output explicitly using instructions like xsl:element,
xsl:attribute, and xsl:text, but we won’t get into that right now since your output is all fairly simple. You’ll see these in
action in some of the later chapters.
Get Source Data

,

Of course, a major reason for using XSLT in the first place is to work with the XML source document, and one of the things
you’ll need to do most often in your templates is pull data from that source document to add to your output. There are a
few very simple ways to do this.
The first is using the

xsl:value-of

element, which you’ve already seen in action quite a bit. It requires a

select

attribute

containing an XPath expression which points to a node (or set of nodes) in the source tree. It adds the text value of the
selected node(s) to the output.
The

xsl:copy-of

instruction works almost identically, but instead of adding just the text value, it adds a copy of the node

itself.
Let’s use a small snippet from your Home view’s XML to demonstrate the difference between the two:

<view>
<title>Home</title>
<handle>home</handle>
<path>/</path>
<current-url>http://example.com/</current-url>
</view>

Using

<xsl:value-of select="view/handle"/>

<handle>home</handle>

would just output home, but

<xsl:copy-of select="view/handle"/>

would output

.

Make sense? Now, what happens if you want to include data from your source tree in an attribute of a literal result
element in your output? You certainly cannot write something like:

<a href="<xsl:value-of select="view/current-url"/>">Home</a>

That’s all kinds of broken, and you’d probably bring down the entire internet and wipe out a penguin colony if you tried it.
You could use an xsl:attribute instruction, but that can be a pain for something so simple. Luckily, there’s another way to
output source data in this scenario; it’s called the attribute value template. It allows you, in an attribute of a literal result
element, to wrap an XPath expression in curly braces

{}

. The processor will then evaluate the expression, turn its value

into a string, and add it to the output. So to build a link to the view above, you’d just do:

<a href="{view/current-url}">Home</a>

Attribute value templates can be mixed with literal text, too:

<a href="http://example.com{view/path}">Home</a>

There are other ways to grab source data, and lots things you can do with that data before you output it, but these
fundamentals will suffice for now.
Other Advanced Mumbo-Jumbo
What you’ve seen so far are the basics, but XSLT and XPath can do much, much more. This is not the time or the place to
try to go through all of the capabilities of each language, but I do want to give you a glimpse of the various kinds of things
I’m leaving unsaid, for example:
You can define and use variables and parameters. These can be local or global in scope and are able to store
values or even entire node-sets.
You can also create various kinds of conditional logic (using elements like xsl:if and xsl:choose)
You can define advanced operations for the processor like the sorting of node-sets
You can take advantage of XPath’s many functions, which allow you to manipulate strings, perform math operations,
compare values, and more.

For more examples of cool things you can do with XSLT templates, check out http://xsltea.com/.
===
So, to summarize what we’ve covered up to this point, templates contain instructions for the processor to follow. You can
use templates to structure an output document, define processing logic, write output, grab and manipulate source data,
and much more. They are pretty powerful things.
A lot of their power, though, actually comes not from what they can do but from how they can be organized and applied.

How Templates are Organized
Every template is a modular, self-contained set of instructions that’s crafted to handle a specific kind of content. But
matching them directly to source nodes isn’t the only way they can be used. Templates can also be grouped functionally
into separate stylesheets, given varying levels of priority, invoked selectively and recursively, applied based on arbitrary
modes, and used and reused over and over again.
Multiple Stylesheets
Because templates are usually content- or function-specific, it’s often helpful to group them into separate stylesheets
based on what they do, what content they work with, or how they’re used. Imagine, for example, that you’ve got several
templates that you use to help you format dates and date ranges. You could put those into a dedicated stylesheet and
then import or include that stylesheet whenever you need to use those templates:

<xsl:import href="path-to-stylesheet.xsl"/>

Or:

<xsl:include href="path-to-stylesheet.xsl"/>

This is how Symphony’s XSLT utilities are pulled into a transformation by a view template. The view template can contain
any instructions specific to that view, and everything else can be abstracted into XSLT utilities.
Note
There’s a subtle difference between including and importing, but you don’t need to worry about it at the moment.
We’re going to discuss the subject in much more detail in Chapters 12 and 14.
Named Templates
As I mentioned earlier, in addition to matching source nodes, templates can also be called explicitly by name. Named
templates are often used for specific tasks that can be helpful in multiple contexts—things like formatting dates, building
lists, truncating strings, and so on.
What makes named templates especially useful is that they can be passed parameters when they’re called. So you could
have a generic template for truncating strings, for instance, and then you could call that template from any context and
have it truncate some bit of text to a desired length:

<xsl:call-template name="truncate-string">
<xsl:with-param name="string" select="path/to/content"/>
<xsl:with-param name="length" select="’250’"/>
</xsl:call-template>

This allows you to keep the template itself generic enough to be applied to any string, in any context, and invoke it only as
needed.

Note
Calling named templates with parameters is a common way to do recursive operations in XSLT.
Priorities
Because XSLT allows you to build a complex system of template rules and instructions, the system needs a way to
decide what to do when the node it’s processing is matched by more than one template rule. There’s a lot that goes into
this decision, but the primary method of defining which template will win out is with a

priority

attribute:

<xsl:template match="entry" priority="1">
… do stuff …
</xsl:template>

The priority attribute can contain any real number, positive or negative. The template with the highest priority will be used.
Modes
We’ve already talked quite a bit about the ability to apply the same template to multiple nodes. Sometimes, though, you
need to do the opposite—specify multiple ways or modes of processing the same content.
XSLT makes this possible with a mode attribute. I’ll spare you the details for now, but you’ll see a useful example of
modes in Chapter 12, when we abstract your HTML

<head>

into a common stylesheet while still allowing individual

views to add CSS and JavaScript references to it.

Anatomy of a Stylesheet
So how does this all come together? Let’s take another look at your home view template and break it down:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/ xhtml1-strict.dtd"
omit-xml-declaration="yes"
encoding="UTF-8"
indent="yes" />
<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="data/context/website/name"/></title>
</head>
<body>
<h1><xsl:value-of select="data/context/view/title"/></h1>
<h2>Recent Posts</h2>
<ul>
<xsl:apply-templates select="data/recent-posts/entry"/>
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="recent-posts/entry">
<li>
<xsl:value-of select="title"/>
</li>
</xsl:template>
</xsl:stylesheet>

Because every XSLT stylesheet is also an XML document, they all begin with what is called an XML declaration—
basically just a line identifying the file as XML. It looks like this:

<?xml version="1.0" encoding="UTF-8"?>

All XML documents also have what’s called a root element. This is a single element that contains all the other elements in
the document. The root element of every XSLT stylesheet is

<xsl:stylesheet>

.

Note
The xsl: you see in front of the element’s name is a namespace prefix. XML namespaces are a pretty advanced
topic, and you don’t need to worry too much about them now, but the basic idea is actually quite simple.
Because XML formats are allowed to define whatever elements they like, it’s possible for the same element names to be
used in different contexts. Namespacing helps avoid confusion between formats, sort of like area codes in U.S. telephone
numbers. Calling within an area code only requires a seven-digit number, but across the country lots and lots of people
share the same seven-digit telephone number. Area codes are prefixes that allow people to communicate across
different areas without confusion.
Everything in an XSLT stylesheet, then, is contained within an element that looks like this:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
… everything goes here …
</xsl:stylesheet>

Note
You’ll notice that the root element has two attributes. The first declares the xsl namespace so that the processor
knows how to interpret the elements it finds. The second declares the version of XSLT that you’re using.
Top-Level Elements
The elements that can be direct children of xsl:stylesheet are called top-level elements. There aren’t many of these—just
a dozen in total—which means that XSLT stylesheets are actually pretty simple, structurally speaking.
You’ve already seen the

xsl:import

and

xsl:include

elements. If you use those, they need to go before any other top-level

elements. I also mentioned earlier that you could declare global parameters and variables ( xsl:param and
And of course there’s

xsl:template

xsl:variable

).

. Aside from those, there’s only one more important top-level element to talk about.

Because XSLT can transform XML into any kind of text-based format, you need to be able to configure a transformation’s
output. You can do this with a series of attributes in a top-level element called

xsl:output

. Have a look at the output

element in your Home view template:

<xsl:output method="xml"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/ xhtml1-strict.dtd"
omit-xml-declaration="yes"
encoding="UTF-8"
indent="yes" />

An XSLT stylesheet can have one of the following three output methods:

html

, or

text

Your home view template’s output element begins by setting the output method as

xml

because it’s generating strict

xml

,

.

xml

is used for all proper

XML formats, html for normal HTML documents, and text for everything else.

XHTML, and adds a couple of doctype attributes for the result document. It then specifies that it wants to omit the XML
declaration that normally sits at the top of an XML document, and that its output should be encoded as UTF-8. Finally, it
opts to have the output nicely indented. For your blog project, all of your view templates will use these same settings.
Most of the remaining top-level elements are seldom-used in a Symphony context, so most of the stylesheets you’ll create
will have a structure that looks more or less like Figure 8-6:

Figure 8-6

[f0806.png]

Exhale. That concludes your whirlwind tour of XSLT. Hopefully you’ve begun to see how it can empower you to craft
elegant, modular, content-driven presentation systems. But if you’re not impressed yet, just know that it gets a lot cooler
than this. We’re barely scratching the surface here. The point of this walkthrough has just been to expose you to XSLT’s
syntax and basic structures so that you have a point of reference as we begin reviewing the language’s fundamentals.

[[deleted]]

Either way, you’ve learned enough that we can move on for now. I’m sure you’re itching to get your blog’s front end up
and running, so let’s not dally any longer.

Working with View Templates and XSLT Utilities
View templates, as you saw earlier, are managed alongside the views they’re attached to, at Framework > Views.
XSLT Utilities can be managed at Framework > XSLT Utilities.
Of course, because they’re both XSLT stylesheets, they are available as physical files in your workspace. View templates
are located in a view’s folder alongside its configuration file (so your Home view’s template is located at
workspace/views/home/home.xsl

). XSLT utilities are located in your workspace/xslt-utilities/ folder.

Writing a View Template
Home View
We’ll start by writing a proper view template for your Home view. You can follow along using the view template editor, or
you can just open the file directly using your favorite text editor ( workspace/views/home/home.xsl ).
First things first, you’ll need to take a look at the source XML for the view ( http://example.com/?debug ). It should look
something like this:

<data>
<context>
<view>
<title>Home</title>
<handle>home</handle>
<path>/</path>
<current-url>http://example.com/</current-url>
</view>
<system>
<site-name>Tales of a Highway Bandit Hacker</site-name>
<site-url>http://example.com</site-url>
<admin-url> http://example.com/symphony</admin-url>
<symphony-version>3.0</symphony-version>
</system>
<date>
<today>2011-01-25</today>
<current-time>19:03</current-time>
<this-year>2011</this-year>
<this-month>01</this-month>
<this-day>25</this-day>
<timezone>America/New_York</timezone>
</date>
...
</context>
<recent-posts section="blog-posts">
<entry id="2">
<title mode="formatted" handle="my-second-entry">My Second entry</title>
<body mode="formatted"><p>Something something something complete.</p></body>
<publish-date time="15:38" weekday="6">2011-02-12</publish-date>
<category handle="journal">Journal</category>
</entry>
<entry id="1">
<title mode="formatted" handle="my-first-entry">My First Entry</title>
<body mode="formatted"><p>Something something something dark side.</p></body>
<publish-date time="15:38" weekday="3">2011-01-12</publish-date>
<category handle="journal">Journal</category>
</entry>
</recent-posts>
</data>

That’s all the data that’s available to you as you’re crafting your output. Now let’s think about your desired XHTML:

<html>
<head>
<title>The Name of Your Website</title>
</head>
<body>
<h1>The Name of Your Website</h1>
<ul id="posts">
<li>
<h2><a href="/category/my-second-entry">My Second Entry</a></h2>
<p class="date">2011-02-12</p>
<p>Something something something complete.</p>
</li>

</ul>
</body>
</html>

Pretty simple, and thankfully, the default template has gotten you much of the way there. It sets up a basic XHTML
document, taking care of the output declaration and so on. Here’s what it looks like after we tweaked at the beginning of
the chapter:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/ xhtml1-strict.dtd"
omit-xml-declaration="yes"
encoding="UTF-8"
indent="yes" />
<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="context/website/name"/></title>
</head>
<body>
<h1><xsl:value-of select="context/view/title"/></h1>
<h2>Recent Posts</h2>
<ul>
<xsl:apply-templates select="recent-posts/entry"/>
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="recent-posts/entry">
<li>
<xsl:value-of select="title"/>
</li>
</xsl:template>
</xsl:stylesheet>

As you can see, there’s not much that you need to do. In the root template (I’m going to adopt the convention of referring
to template rules according the nodes they match), you’ll just replace the content of the
of the "Recent Posts"
1. In the

<h1>

<h2>

, change the

select

attribute of the

value-of

element to

<h1><xsl:value-of select="context/website/name"/></h1>

2. Delete the

<h1>

with your site name, get rid

, and add an id to the posts list. Let’s take care of all that now.

<h2>Recent Posts</h2>

3. Add an id attribute to the

<ul>

line

element, so it looks like this:

context/website/name

. So the line should read:

<ul id="posts">

Now the last thing you’ll need to do is beef up the list items that are being output by the recent posts entry template. Right
now, they just contain title text, but as you can see in the desired output, you’re aiming for a linked title heading, a
paragraph containing the date, and then the entry’s textual content.
Building the title heading should be fairly easy. The

<h2>

and the

<a>

can be literal result elements. For the link’s

content, we just need to use value-of to grab the title. The attribute is the only tricky bit. You’ll recall that individual posts
will have URLs like posts/category/title. So you’ll have to piece together the anchor’s href attribute out of several different
bits:
The website’s base URL, which we can get from
The entry’s category:
The entry’s title:

category/@handle

/context/system/site-url

(you want the URL-friendly version provided by the element’s handle)

title/@handle

You’ll notice a difference between the first expression and the latter two. Because this template matches
posts/entry

recent-

nodes, we’re able to grab the category and title data directly, but for the base URL we need to jump outside

that context, so we build a path relative to the root node.
Piece it all together using attribute value templates (mixed with a bit of direct output), and you get:

<h2><a href="{/context/system/site-url}/posts/{category/@handle}/{title/@handle}"><xsl:value-of select="title"/></a></h2>

Next you want to add a paragraph for the entry’s date. This bit’s pretty easy:

<p class="date"><xsl:value-of select="publish-date"/></p>

The date won’t be nicely formatted (it’ll look like

2011-02-05

), but we’ll cover that later in the book.

Finally, you want to output the entry’s content. Because we’re capturing the content using Markdown formatting, it’ll be
available as HTML, so you’ll want to use

xsl:copy-of

to make sure you get any HTML elements in the content.

<xsl:copy-of select="body/node()"/>

Why

body/node()

and not just

body ?

If you used

<xsl:copy-of select="body"/>

element in your output too. What you want is a copy of everything inside the
node()

, you’d actually get the original
body

<body>

element, including any child elements.

gets you exactly that.

One last optional bit: if you want some basic styling for your blog, you can add the following stylesheet to your head:

<link rel="stylesheet" type="text/css" media="screen" href="http://book.symphony-cms.com/workspace/uploads/blog.css"/>

That’ll make your site a bit more presentable for the time being. Here’s the final stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/ xhtml1-strict.dtd"
omit-xml-declaration="yes"
encoding="UTF-8"
indent="yes" />
<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="context/website/name"/></title>
<!-- Optional stylesheet line goes here -->
</head>
<body>
<h1><xsl:value-of select="context/website/name"/></h1>
<ul id="posts">
<xsl:apply-templates select="recent-posts/entry"/>
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="recent-posts/entry">
<li>
<h2>
<a href="{/context/system/site-url}/posts/{category/@handle}/{title/@handle}">
<xsl:value-of select="title"/>
</a>
</h2>
<p class="date"><xsl:value-of select="publish-date"/></p>
<xsl:copy-of select="body/node()"/>
</li>
</xsl:template>
</xsl:stylesheet>

Got it? Ok, save the template. Now if you visit your home view you should see the full posts being displayed (Figure 8-7).
Don’t worry that there’s no navigation yet. We’ll get to that shortly.

Figure 8-7

[f0807.png]

Post View
Now let’s get the Post view set up so those title links will actually point to something. To edit the Post view template, either
go to Framework > Views, click "Post," and switch to the template tab, or open

/workspace/views/post/post.xsl

in your text

editor. You’ll recognize the default template.
Let’s start again by figuring out what the desired XHTML will be for your individual posts. As with everything else, we’ll
keep it very simple for now:

<html>
<head>
<title>The Name of Your Website</title>
</head>
<body>
<h1>Title of the post</h1>
<p class="date">2012-12-21</p>
<p>All the content...</p>
</body>
</html>

Have a peek at your source XML ( http://example/com/post/journal/my-first-entry?debug ). I won’t paste it here, but try to locate
the bits of data you’re going to need—the post title, the date, the body content. Use the XPath tester to see if you can
figure out the expressions that will point to them.

The templates you’ll end up writing are dead simple:

<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="context/website/name"/></title>
<!-- Optional stylesheet line goes here -->
</head>
<body>
<xsl:apply-templates select="individual-post/entry"/>
</body>
</html>
</xsl:template>
<xsl:template match="individual-post/entry">
<h1><xsl:value-of select="title"/></h1>
<p class="date"><xsl:value-of select="publish-date"/></p>
<xsl:copy-of select="body/node()"/>
</xsl:template>

Copy those two templates into your stylesheet (replacing the old one), and save it. If you go back to your Home view now,
and click on a post title, you’ll be able to view your post.
Archive View
Last, but not least, let’s tackle the Archive view. Go to Framework > Views and click "Archive" and then the template tab,
or open

/workspace/views/archive/archive.xsl

in your text editor.

Here’s the desired XHTML for your archive view:

<html>
<head>
<title>The Name of Your Website</title>
</head>
<body id="archive">
<h1>Archive</h1>
<h2>2012</h2>
<h3>December</h3>
<ul>
<li><a href="http://example.com/posts/journal/my-second-entry">My Second Entry</a></li>
</ul>
</body>
</html>

Pretty simple, as usual, but the XML here is going to be a little different. In the last chapter, when you created the Posts by
Date data source, you opted to have the results grouped by date. So instead of just having a set of entry elements, then,
your data source will have a slightly more complex hierarchy that looks something like this:

...
<posts-by-date>
<year value="2012">
<month value="11">
<entry/>
</month>
<month value="12">
<entry/>
</month>
</year>
</posts-by-date>
...

Your Archive view is set up to list entries either from a single month, or from an entire year, grouped by month. So this
data structure plays right into your hands. You can have a template match the month elements, allowing you do render a
separate heading and list for each month. Then another template can take care of the entry elements themselves. It’ll look
like this:


<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="context/website/name"/></title>
<!-- Optional stylesheet line goes here -->
</head>
<body>
<h1>Archive</h1>
<h2><xsl:value-of select="posts-by-date/year/@value"/></h2>
<xsl:apply-templates select="posts-by-date/year/month"/>
</body>
</html>
</xsl:template>
<xsl:template match="month">
<h3><xsl:value-of select="@value"/></h3>
<ul>
<xsl:apply-templates select="entry"/>
</ul>
</xsl:template>
<xsl:template match="posts-by-date//entry">
<li>
<a href="{/context/website/url}/posts/{category/@handle}/{title/@handle}">
<xsl:value-of select="title"/>
</a>
</li>
</xsl:template>


In the root template, you include two headings, one for the view’s name and one for the year. Then you apply templates to
the month elements. The template for months includes a third heading (for now containing just the month’s number), and
an unordered list for its entries. Inside the unordered list, it applies templates to its child entry elements. That third
template, for entries, just outputs a list item and a link for each entry.
Drop those three templates into your archive view stylesheet (replacing the default one), and save it. You should now
have a pretty simple, but functional, archive view.

Writing an XSLT Utility
Now, you’ve got three basic views, but they’re missing navigation. We’ll take this opportunity to introduce you to XSLT
utilities and to named templates.
In many cases, you want your site’s navigation to be dynamic, so that your front-end can grow and adapt without you
having to always manually change navigation items and so on. For now, though, we’re just going to stick with a static
version.
1. Go to Framework > XSLT Utilities
2. Click the green "Create New" button
You’ll see that the XSLT utility editor looks just like the view template editor. The default stylesheet here is much
more minimalist, though.
3. In Name, enter

navigation.xsl

The stylesheet you need is simple—one named template containing the output you’re looking for:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template name="navigation">
<ul id="nav">
<li><a href="{/context/website/url}/">Home</a></li>
<li><a href="{/context/website/url}/archive">Archive</a></li>
</ul>
</xsl:template>
</xsl:stylesheet>

Enter this stylesheet into the editor and click "Create XSLT utility."

Using XSLT Utilities
As you learned earlier, you can make this navigation template available to your view templates by importing the
stylesheet.
For each of the view templates you created above, go back and insert the following line before the xsl:output element:

<xsl:import href="navigation.xsl"/>

Then, just below each view template’s h1 element, add:

<xsl:call-template name="navigation"/>

Once you’ve updated and saved each of you view templates, you’ll see that each view on your front end includes a
navigation menu now. That code is shared among all the views.
Of course, there’s a lot more they could share, and a lot more we could do to organize your templates more efficiently, but
you’ll get there. What’s important right now is that you’ve got a basic sense of how view templates and XSLT utilities can
fit together.

Summary
Let’s take a walk down memory lane, all the way back to the beginning of this chapter when you were just sitting there, in
your giant helmet, with no idea what XSLT was or how it worked. We’ve come a long way since then, huh?
We talked about Symphony’s "transformed output" approach to templating, and about how it differs from the kinds of
templating systems you may have seen in the past. You learned that Symphony’s templating layer is comprised of view
templates and XSLT utilities, and powered by XSLT.
After that, you learned what XSLT is and why it’s a great templating language for the web. You then got a crash course in
XSLT and its accompanying technologies like XML and XPath. You learned about building XPath expressions, writing
XSLT templates, and composing stylesheets.
Finally, you wrote the templates that would make your new blog functional.
As exciting as this is, I’m sure you’re looking at your blog and thinking, "This is far from finished." Part 3 of the book is
going to help you master all of the most important Symphony workflows, and as you do so you’ll continue to flesh out and
improve your modest little blog.
Before we move on to all that, though, we need to spend some time discussing issues of system management. How do
you add users? How do you install extensions? Where can you set preferences? That’s what we’re going to discuss now.

Chapter 9: System Management
What’s in this chapter
System Settings
Users and Roles
Working with Extensions
Backups and Maintenance
You’ve only just finished learning the basics, and already Symphony’s enabled you to build a custom website and CMS,
essentially from scratch. Pretty impressive, no? And while you might expect managing such a capable system to be a
hopelessly complex endeavor—involving all sorts of arcane menus and page after page of switches to flip and boxes to
tick—Symphony actually packs all of its punch into a remarkably lightweight package.
All of which is to say that the work of tending a Symphony installation is much more straightforward than you might think.
This is partly due to the fact that you’re not deploying sites pieced together from cookie-cutter features. So you don’t need
loads of extra preferences to tell your site what you want it to do. It does what you designed it to do. The other reason is
that Symphony is engineered from top to bottom with simplicity as a guiding principle:
“The simplest answer is almost always right, because it has the greatest number of other answers behind it. Opting
for simplicity makes it just as easy to turn back or change direction as it is to keep going.”
— The Tao of Symphony, http://symphony-cms.com/learn/articles/view/the-tao-of-symphony/
This approach permeates the entire system, from its core architecture right through to its admin interface and the user
experiences and workflows it provides.
This chapter will be a quick one, then. It won’t take long for you to learn everything you need to know about managing
your Symphony installation.
We’ll begin with the general settings that define the system’s internal behavior—things like the default language and date
formats for your admin interface. Then we’ll go on to discuss users and roles so that you’ll be able to manage back-end
access and permissions. After that, we’ll briefly explore the world of Symphony extensions. Extensions are a crucial part
of any Symphony project because the core of the system is built to be so lean—almost every kind of specialized
functionality is provided by an extension, even things like field types and data source types. Finally, we’ll wrap up our
discussion by talking about site maintenance, backups, packaging, and so on.
When we’re finished, you’ll be fully equipped to manage, tweak, and extend your new site to your heart’s content.

Managing Settings
Settings allow you to configure various aspects of the system’s internal behavior—from simple display options to things
like file permissions and caching. There are two ways to manage your settings in Symphony: using the admin interface or
by editing the settings files themselves.
The most commonly used settings can be accessed right in the admin interface, at System > Settings (Figure 9-1). Any
settings provided by extensions are made available here as well, in a separate tab.

Figure 9-1

[f0901.png]

Let’s take a moment to review the settings available here:
Website Name. This is the name of your website. It’s used to title the admin interface, and is provided in the context
XML that is made available to your front end.
Language. The default language for the admin interface. You have to have language extensions installed to enable
selection of languages other than English. This setting is only a default. Individual users will be able to choose their
own preferred language.
Administration Path. This is the URL path for the admin interface. By default, this is ‘symphony’, but you can change
that here.
Date Format, Time Format, and Timezone. These settings allow you to specify how dates will appear in the admin
interface, and whether times should be adjusted to a particular timezone.
[[Additional settings not yet defined... caching, logging]]
All of Symphony’s settings—both these common ones and several more advanced settings—are stored in XML files in
your manifest/settings/ folder. Extensions will save their own settings files to this directory too. The second way to manage
settings, then, is to edit these files directly. Because you’re now familiar with XML syntax, you should be able to find your
way around the files pretty easily. Here’s a sample:

PASTE

You can always change any setting by editing these settings files directly, but make sure you know what you’re doing. If a
setting requires more than a simple yes/no value, you need to know what will work and what won’t.
Let’s review the remaining default settings we haven’t already discussed, so that you’ll be able to adjust these if
necessary.

Website settings
Version. This will be updated automatically when Symphony is installed or updated. You shouldn’t change this or
you might risk throwing off future upgrades.

Email settings
Provided by gateway extensions?

Front End Settings
Display Event XML in Source. This setting specifies whether the system will append to its output, in an XML
comment, any data returned by an event. Expects yes or no.

System Settings
Cookie Prefix. Prefix for cookies stored in the browser by Symphony. Defaults to sym- but any string will do.

File Write Mode. Default permissions for files created by Symphony. Defaults to 664 but any mode writable by the
server will work. Don’t change this unless you know what you’re doing, or you could create a security problem.
Directory Write Mode. Default permissions for directories created by Symphony. Defaults to 775 but any mode
writable by the server will work. Don’t change this unless you know what you’re doing, or you could create a security
problem.
Archive. Whether system logs should be archived. 1 for yes, 0 for no.
Max Size. Maximum size of the logs archive. When the file reaches this size, old logs will be truncated. Enter a size
in megabytes.
Cache Driver. Method the system will use for caching. Either file or database. [[What’s the difference?]]

Admin Interface
Condense Scripts and Stylesheets. This is an option to have the system condense back-end assets to improve
performance. Accepts yes or no.
Maximum Upload Size. Maximum size for file uploads in the admin interface. Enter a size in megabytes.
Maximum Page Rows. In the admin interface’s index views, the maximum number of items to show per page.
Default is 17.
Default Data Source Type. Default type selected when creating a new data source in the admin interface. Accepts
handle-ized version of any available data source.
Default Event Type. Default type selected when creating a new event in the admin interface. Accepts handle-ized
version of any available event type.
Allow Page subscription. ????
Most of these advanced settings you’ll never need to touch, but it’s good to know that they exist and how you can change
them, just in case.
As I said above, extensions can also add their own settings. If they do so, their settings will be available at System >
Settings under the Extensions tab, and in extension settings files in manifest/settings/.
X of Symphony’s default extensions provide settings of their own. Let’s review those now:

[[Default extensions and their settings]]

Managing Users
Users are people who can log into your Symphony site’s admin interface. When you installed Symphony you created the
system’s first user.

Creating and Editing Users
You can manage your system’s users at Users > Accounts. By now the interface conventions should feel like second
nature—click a user’s name to edit that account, click the green “Create New” button to add a user. Let’s start by looking
at your own account:
1. Click your name in the users index (you can also get to your account by clicking on your name in the title bar).
2. Your account information will be displayed in the user editor (Figure 9-2):

Figure 9-2

[f0902.png]

Let’s quickly review the information:
First Name
Last Name
Email Address
Username
Password
Start Page
Language
All of this is pretty standard. You can use this form to update your details, change your password, or modify personal
settings.

User Roles
Symphony’s core allows for only one type of user with full permissions, meaning any user can access anything in the
back end. This is great when you’re working on a site by yourself or with a trusted small team because it saves you the
overhead of a complex permissions system.
Once you’re dealing with more than a few users, though, it’s likely that you’ll need fine-grained control over who has
access to what. Symphony’s got your back here too. The system ships with an Access Control Layer (ACL) extension that,
once enabled, allows you to create discrete user roles and specify role-based permissions.
To demonstrate how roles work, let’s imagine that you’ve decided to make your blog a collaborative endeavor. You’ve
brought on a second author and

Creating and Editing Roles
Creating and Editing roles...
Note about frontend users

Managing Extensions
Because different people will require different things in different situations, Symphony is designed to allow you to swap
pieces in and out as you need them. This is done via extensions.
A good deal of setting up and managing a Symphony installation, then, is

The Core Extensions
There are a handful of core extensions.
Field types: text, date, select, upload, ?
Data source types: entries, users, views, dynamic XML, dynamic JSON
Event types: ??
View types: ??
Devkits: debug, profile
Export ensemble, maintenance mode, ??

Finding and Installing Extensions
Basic: locate extensions at getsymphony.com; download or clone; activate/enable Advanced: install Extension Manager
extension; configure git and/or curl permissions and details; browse extensions at Extensions; use search & filter;

Managing Extensions
Update notifications
Updating extensions
Note about uninstalling extensions

Backups, Updates, and System Maintenance
Blah

Summary
Yeah text

Chapter 10: Planning Symphony Projects
What’s in This Chapter
Planning to Plan
Project Architecture
Workflows
This chapter begins the third leg of your journey to complete and unquestioned Symphony mastery. (No pressure,
though.)
In Part 2 of the book, your goal was to learn the ins and outs of how the system works and what it can do. Here, your goal
will be slightly different. Instead of focusing on how the system itself works, we’re going to focus on how you can work
with the system.
In other words, Part 3 is all about workflows—about learning to wield this powerful tool skillfully and efficiently. If the
previous six chapters were your Symphony schooling, the next six will be your apprenticeship. We’ll explore concrete
techniques and best practices that will get you working faster and smarter and building websites that are elegant and
easy to maintain.
You’ve got the basics under your belt, so we’re going to pick up the pace a little bit now. In just a handful of chapters,
you’re going to learn how to use Symphony for iterative development, how to abstract and reuse templates, how to profile
and debug a site, and much more. And when it’s all said and done, you’ll be well prepared to tackle the fourth, and final,
part of the book—the one with all the awesome projects.

But before we dive into all of that, we should begin, naturally, at the beginning. Every web project starts with some degree
of planning—with making decisions about what you’re trying to achieve, how things are going to look, how they’ll behave,
and so on.
So far in our journey together, I’ve been making all these kinds of decisions on your behalf. You’ve just followed along
dutifully and trusted me to be right. Thankfully, for your sake, I’m every bit as thoughtful and intelligent as I am humble.
Wait—
Anyway, sooner or later it’ll be time for you to build your first real Symphony site on your own, and you’re going to need to
be able to scope the project yourself, map it out, manage its development, and so on. And even if you’ve done this sort of
thing before, it can all look a bit different when you add Symphony to the mix. As with any tool, Symphony will impose a
certain amount of structure, and certain kinds of conditions, on how you go about things. Getting your thinking attuned to
the system early in the process will be an important first step whenever you’re about to embark on a new project.
My goal in this chapter, then, is to equip you with tools and techniques that will help you plan Symphony projects
effectively. We’ll try to keep things brief. I want to talk about three separate planning topics—preparation, project
architecture, and workflows—and for each I’ll just quickly review some helpful techniques and pointers.
Whatever your role—hobbyist, independent developer, project manager—my hope is that you’ll leave this chapter feeling
confident in your ability to map out and orchestrate Symphony projects large and small.

Planning to Plan
Blah

Be Open
Every project will be different. Sometimes you know right away how you want a site to look and feel. Other times, it’s the
content and interactions that are most clear from the outset.
Rather than always forcing yourself to proceed in this or that particular way, try to recognize what it is that you’ve got in
the beginning and let that drive the planning process.
If what you’re starting with is a vision of an interface or a user experience, so be it. You can plan from the outside in, from
sketches and wireframes to front-end architecture and down to the content, letting your vision of the user’s experience
guide you.
If, on the other hand, the first thing you’ve got is a well-defined data model, then you can take an inside-out approach,
starting with content outlines and data flow charts and letting those determine the site’s structure and design.
Now, of course, if you’ve already got a tried and true method of scoping and planning projects, by all means feel free to
stick to it if it works for you. But in my experience no one approach is inherently better than any other. It all depends on the
circumstance. And sometimes trying to prematurely force a great content-driven idea into wireframing, or a purely visual
idea into abstract data modeling, can kill momentum and wind up being counter-productive.

Lurk in the Community
Symphony’s is a vibrant open source community where conversation is constant and new projects and ideas are
surfacing all the time. When you’re gearing up to start a new project, spend a little bit of extra time tuning into the
community chatter. Chances are, other people are out there solving problems very similar to yours, and you’ll be able to
learn from the questions they ask and the solutions they find. You can also gather inspiration from among the
community’s ever-stunning showcase sites, or keep an eye on the development roadmap to see what changes are
coming to the system.
The first and best place to go is the Symphony website: http://symphony-cms.com/community. But there are other places
to find fellow Symphonists too:
IRC: #symphony on Freenode
Twitter: via the #symphonycms hashtag
Convore: http://convore.com/symphonycms

Research Extensions
The other reason to become a regular on the Symphony website is that you want to be intimately familiar with the
extensions ecosystem.
As you’ve seen, Symphony is a lean, lightweight content management framework. All non-essential functionality is
provided by extensions, which means that every project you’ll build will probably rely heavily on extensions.
These extensions are constantly being developed and refined, and new ones are born every week. You won’t be able to
plan your projects effectively without knowing exactly what’s out there, what it does, how reliable it is, and so on.
This is especially true of extensions that provide core elements like field types, data source types, and the like. You’ve
already seen how important these can be. Field types, for example, determine pretty much every aspect of how your data
can be used. Coming up with a sound content model means knowing what field types are available to you and what the
differences are between them.

Ask for Help

Because there’s more than one way to do almost everything in the Symphony universe, you’ll probably spend lots of time
ruminating over various kinds of approaches and implementations when you’re getting ready to start a new project.
One of Symphony’s best traits is that it makes it very easy for you to try things out quickly and see how they work
(something we’ll discuss at length in the next chapter). But sometimes trial-and-error is too time-consuming, or the scope
of the thing you’re trying to figure out is just too broad.
Generally speaking, it’s a good habit to spend time puzzling through things on your own, researching and weighing
various options and trying to pinpoint the questions and uncertainties. But whenever you’re in doubt, do yourself a favor
and ask for help. You’ll undoubtedly save yourself lots of time, and probably learn something new in the process.
Make sure your questions are well-considered and specific. Don’t be the person who comes to the forum making vague
demands, like “Hey tell me how I can implement an ecommerce site.” Figure out what exactly your dilemma is. Are you
unsure about your content model? Do you want suggestions for how to set up a certain set of views?
Asking well-thought-out, specific questions will get you clearer, faster answers.

Project Architecture
No particular order...

Outline your Content
As you saw in Chapter 5, the structure of content in Symphony has a cascading effect throughout an entire project. It
determines what the publishing interface will look like for content producers. It determines how data is stored, and how
entries can be sorted, filtered, and searched. This makes content modeling a crucial task for Symphony sites, and each
decision you make here will reverberate into other phases and aspects of the project.
When the time comes to plan your data model, one technique that I’ve always found very helpful is outlining all of the
content types a project will require before I start any actual development.
My method is fairly straightforward, and you got a taste of it back in Chapter 5. I simply list each content type, and then list
its fields along with their types and any configuration options worth noting. Here’s an example:

Products
Label

Field Type

Name

text input

Description

textarea

Image

file upload (image)

Category

select box link

Configuration Options

/workspace/uploads/products/



Categories::Name

Categories
Label

Field Type

Name

text input

Description

textarea

This is not unlike what you might see in a diagram of a database schema, only simplified, and with some Symphonyspecific bits like upload directories or relationship targets.
As I mentioned above, you’ll want to pay special attention to the field types at this stage. They’re the primary determinant
of how you’ll be able to use your data, and because they also determine how data is stored, changing field types is a
destructive process. So you’ve got to get it right at the beginning.
I find mapping out a site’s content model like this incredibly helpful, but there’s a balance to be stricken here. The benefit
of this exercise is to get you thinking in advance about the shape of your content, and to help you see where critical
decision points will be (Should Categories be its own content type? Will I need to be able to attach more than one image
to a Product?). But this outline shouldn’t be set in stone, and it’ll almost certainly change during implementation.
The important thing here is to prioritize completeness over perfection. Don’t worry if you’re uncertain about a handful of
details, but make sure you’ve been through the whole content model at least once.

Wireframe
Websites and web applications often begin their lives as wireframes—simplified visual outlines of pages or interfaces that
roughly approximate things like layout and content placement (Figure 10-#).

Figure 10-#

Wireframing is a tremendously helpful planning tool and often a great place to start a Symphony project, especially for
non-developers, who might find it difficult to begin with something as abstract as a data model. Wireframes allow you to
start with the part of your project that’s probably most tangible—the interfaces your visitors will see and explore—and
help you get a feel for how your content is going to be used.
It’s common to annotate wireframes, normally by placing numbered circles over various parts of the visual and then
adding a corresponding note in the margin. When you’re working on a Symphony project, this can be a helpful way to
use what you’ve got (visual ideas, in this case) to help you begin planning other parts of the system. For example, a
wireframe for a blog’s home view might contain annotations like “Blog Post entries, 10 most recent” and “Title, teaser,
date, author” (Figure 10-#). Now you’ve got a head start on a data source and a content type.

Figure 10-#

If you’re reading this book, there’s a good chance you know all about wireframes and have probably created lots of them
yourself, so I’ll leave it at that. If you want to explore the practice a little more in depth, there’s a fairly thorough guide at
http://sixrevisions.com/user-interface/website-wireframing/.

Do a Task Analysis
Another technique that’s common among information architects and user experience designers is the task analysis or
task flow.
Details can vary, but the basic idea is to chart out what it is that users need to be able to do on your site and where.
Sometimes this takes the form of flow charts that track particular user journeys. Sometimes it’s a sequential table of user
actions and accompanying system actions. Figure 10-# provides some examples:

Figure 10-#

The important thing is that this sort of exercise gets you thinking about how people will use your site, and that can help
you raise architecture and design questions early on that you might otherwise miss.
If task analysis is part of your planning process, it can be a great place to mine for structural Symphony requirements.
Charting user journeys, for example, can help clarify the interfaces you’ll need to provide and where they’ll live. And
detailing how the system should behave in response to specific user actions is a good way to start planning data sources
and events.
Figure 10-# shows how you might layer Symphony specific details onto the examples provided above.

Figure 10-#

Plan Your Markup as a System
When you’re ready to produce live presentation code for the first time (which will hopefully be fairly early on, as page
prototypes), try to remember that with Symphony you’re not “skinning” system output but rather developing a robust and
flexible design system. In other words, you’ll want to be attentive to patterns as they emerge.
This is the sort of thing you might even begin to intuit during the wireframing stage—where you’ll often be identifying
global interface elements and reusable visual idioms.
By the time you get around to building live prototypes, writing the actual code will likely reinforce these early intuitions
and reveal even more patterns and opportunities for abstraction. Imagine, for instance, that you decide to markup some
event data in one of your prototypes using the hCalendar microformat. If you knew you’d be using events all throughout
your site, this would be an ideal place to abstract that markup into a reusable template that can be applied whenever
event data is being output.

Being able to streamline and organize your presentation layer like this is one of the nicest benefits of using a rule-based
templating system like XSLT, and you should be prepared to take full advantage of it.

Map Everything
Another common technique in web design and development is site mapping—part of the information architecture process
that, in its simplest form, maps a site’s pages or interfaces into a hierarchy to help visualize its organization.
With a Symphony project, especially a large or complex one, it’s often helpful to take this mapping exercise one step
further. You can begin by listing and arranging all of the views you imagine your site will require. You’ll want to include
details like their handle and parameters, so that you can get a sense of how your URL schema will look. Views can also
be organized hierarchically, so you’ll want to capture or represent those relationships too.
Then, for each view, think about what content it needs to display or what interactions it needs to support. This is where
wireframes can come in handy if you’ve made them. Going through the views this way will give you an overview of the
various kinds of data sources and events you’ll need, and you can begin to list and describe those too.
What you end up with in the end is a pretty thorough mapping of your front-end. Mine often look like Figure 10-#:

Figure 10-#

This exercise helps you pull disparate pieces together, fill in gaps, and spot redundancies and trouble areas before they
become problems. It can be overkill for small projects, but for large sites, I find it invaluable.

Because I happen to find these techniques so helpful, I created a Project Planning Kit that provides PDF and SVG
templates for creating Symphony-specific wireframes, content outlines, system maps, and the like. The templates have
dozens and dozens of variations and can be printed out or used within your favorite vector drawing program (Figure 10#).

Figure 10-#

You can find the project planning kit in a community-maintained Github repository at http://github.com/####/#####.

Workflows
Of course, getting the system scoped and mapped out is only part of the battle. In addition to knowing what you’re going
to build, you’ll probably want to spend time figuring out how you’re going to build it.
This is especially true if you’re working with others. When you’re working alone, you get to do things however you like. No
one will be stepping on your toes, getting in your way, or making changes while you’re not looking. But when you’re
working in a team, whether it’s two people or twenty, things can get complicated very quickly.
In either scenario, it can pay to spend a little bit of time before any project hashing out workflows and procedures to keep
things from getting messy.

Plan to Test
First and foremost, plan to test. The kinds of system specifications you saw above are going to help you spot the easy
errors, like when an interface is misbehaving or is missing content. But you’ll want to be prepared to catch subtler
problems before your project goes live and they start tripping up your users.
One obvious way to surface these kinds of issues quickly is to develop iteratively—building specific sections and
functionalities one-by-one, starting with the simplest implementation and then adding to it little by little and testing
(preferably with real users) all along the way. We’ll cover this strategy in much more depth in the next chapter.
There are other ways to incorporate testing into your workflows, though, whether it’s stress-testing your data model with
sample content, seeing how views and data sources respond to unexpected parameters, submitting malformed or
malicious data to your front-end events, and so on. We’ll talk more about testing and debugging in Chapter 15, but do
yourself a favor and work it into your plans and timelines from the beginning.

Think about management
Will ppl be working concurrently? Or in rapid succession?
One benefit of Symphony’s modular architecture is that you can you can

Use Version Control
This is not really a suggestion. Just do it. It might take you some time to get the hang of using a version control system (I
recommend Git), but trust me: it’s well worth it.
Version control will give you peace of mind as you commence development on your Symphony project. You’ll be able to
undo changes, resolve conflicts if you’re working with others, and if you use a hosted service like Github or Codebase,
you’ll know that your build is always backed up somewhere.
Symphony itself is optimized for version control. All of the structural information about your project is stored in physical
files right in your workspace (the database only contains entry data). So by using version control, you’ll give yourself
access to incremental snapshots of your entire build at every stage of development (Figure 10-#).

Figure 10-#

When you’re going to version-control a project, you need to have a plan. Know where you’re going to host your
repository. Know how it’s going to be organized (for example, separate branches for development and deployment code).
And know exactly how you intend to deploy from the repository to the production server.
For individuals and small teams, you’ll want to keep all of this as simple as possible. But really big projects may require
elaborate schemes for things like branching and versioning, and if you’re working with a large team you’re going to need
guidelines on how changes should be reviewed and merged. If you’re working in an agency setting or planning a big,
ambitious project, make sure you think this stuff through first.

Getting into the details of a version control system like Git are well beyond the scope of this book, but Symphony’s online
documentation has loads of details on how to use Git with Symphony, and it will also point you to other helpful Git
resources: http://symphony-cms.com/documentation/git.

Have a Solid Plan for Deployment
This is related to the discussion about version control, but there are specific questions about deployment and ongoing
development that I want to make sure you consider.
First things first, have a deployment plan and test it before you start actively developing. For example, if you plan to use
Git, test your deployment strategy as soon as you install Symphony and initialize the repo. After you’ve done some initial
development work, see what happens when you try to pull those updates to the production server. You don’t want to wait
until the day before launching a site to see if all this stuff works as intended.
For big projects, a staging server can be a good idea. Instead of developing entirely in isolation on your local machine or
network, you periodically deploy the project to a private staging server. This gives you a chance to test with your clients or
users and gather live input. And if your staging server is located on the same host as your production server, it’ll also give
you a chance to test the environment and iron out any problems there.
Finally, if you’re developing locally or on a staging server and then deploying to a production server, think carefully about
how you’ll keep your databases in sync. Entry data is the only thing that falls outside the purview of a version control
system, so just have a plan in place. If your client is entering live data on the staging server, for instance, you don’t want
to lose that when you push to production.

[[Symphony 3 may have some built-in db tools, so will have to revisit this]]

Summary
We’ve quickly run through a whole bunch of shit that I think you will find helpful next time you have to sit down and plan a
new project.
One technique we haven’t discussed, though, can often be the most useful of all. It’s the anti-plan.

Chapter 11: Adaptive Techniques
After that entire chapter on planning, let’s pause for a moment to face the facts. Sometimes requirements change.
Sometimes plans blow up in your face.
In this chapter we’ll talk about what to do when plans go awry, or when you don’t have the ability or luxury to plan
everything in advance, or when you decide that iterating makes more sense than planning...
Start with an introduction to adaptive/iterative development … Then take some baby steps with your existing blog project
… Finally we’ll go all out and develop a new section/function for your site. The idea is to give you a sense of how flexible
workflows can be when you’re using Symphony.

Rapid Prototyping
Interative Development
When everything goes according to plan, it usually involves unicorns and talking fish (because it’s all in your
imagination).
A whole lot of development methods have gained popularity in the last few decades in response to what is commonly
called “Waterfall development.” WD is when each phase of planning and development is nicely and neatly completed
and then serves as the basis for the next bit.
As development teams began to realize that this method almost never mapped onto reality, they started coming up with
alternatives: adaptive development, agile development, iterative development... Though each of these has its own
particular definition and history, I think of them as a family of approaches that are trying to solve the same problem in
different ways.
the upshot is that they’re trying to combat the top-heavy process of WD with more flexible approaches where things are
scoped as you go, there’s some room for trial ad error, for learning on the go, for prototyping something simple and
building it up... and for all of these tasks, symphony’s a great tool it’s modular, it allows to you build your solution bit by bit,
and so you’re able to go in thin layers, or to do a circular thing. when you’re building symphony projects these kinds of
approaches can be invaluable, esp when plans are difficult or they fall apart or requirements are shifting. let’s give you a
taste of how it works.

First Steps: Adjusting What You’ve Got
We’ve already got a basically functional blog, so the first thing would be talking about how to add fields to an alreadyexisting section and carry that through to the front end.
decide field to add
go to section editor, add it, configure it, add to layout
now update entries to reflect the change
get that data through to the front end by updating the DS
debug the page to check the data’s coming through
add/edit a template to handle that field
That’s the basic back-to-front linear process. Let’s look at some other workflows...

Prototyping a Portfolio addition
Start at the design level this time... whip up a wireframe to guide us.
create the view, write some XSLT to give us basic output
take a rough swing at the data model
create some entries, adjusting the data model iteratively until we get what we want
create a ds to deliver them, attach to view
Test DS filters/sorts/etc/ like i just did with the Symphony home page
update templates to pull the data in where we want it

enhance the design, adding new elements
repeat the process

Summary
This was fun...

Table of Contents
Introduction
Why You Need Symphony
Symphony in Action
Getting Started
Symphony Anatomy
Content
Front-end
Data Flow
Templating
System Management
Planning Symphony Projects
Adaptive Techniques

1
2
13
22
35
48
64
74
91
119
125
134

Sponsor Documents

Or use your account on DocShare.tips

Hide

Forgot your password?

Or register your new account on DocShare.tips

Hide

Lost your password? Please enter your email address. You will receive a link to create a new password.

Back to log-in

Close