Launching a college news site with Drupal

SUNY Oswego recently switched from a legacy install of Expression Engine to integrating with the rest of our web platform and using Drupal hosted by Acquia to “re-design” our new News site. Hopefully this post will help others thinking of migrating to Drupal and provide some helpful tips if you’re already in the process of doing so.

Our old site

Even though our old news site was in Expression Engine, the power of it being a PHP/MySQL app wasn’t fully utilized.

Now, this is through no fault of our office, it just hasn’t been looked at in a very long time. The old site worked well enough for what we needed so we left it alone until an opportunity presented itself to give it a little update.

As a result, the homepage was consistently static. Photos and images were dumped into one WYSIWYG text blob which meant it was difficult to display teaser photos or do anything that is possible with structured content.

Photo captions were placed at the bottom of the articles, separated from their photos. Tagging had no specific function other than creating a word cloud that kinda looked cool. Categories weren’t maintained and difficult to browse by. Finding a list of just all news ordered by date was a hard task to complete.


Moving forward

In order to move forward and utilize Drupal to the fullest extent, we planned out content types, audited our workflow, and looked for areas that could be improved as we moved into Drupal.

Auditing our content types

First we sat down and looked at what kind of content was being created. We had a few different content types that were regularly published. News story, People in action, and Spotlight. All of this content was published using one content type and tags to differentiate them in the system.

For the new news site, we now have the same three as before, plus a new Media mention content type. I separated each piece of content into different content types. This allows us to style the content differently and add different fields depending on what the content type needs. The content types are:

  • News story
    • This is the bread and butter of the news site. Most of the content being entered is a news story about something awesome happening on campus.
  • People in action
    • This content type is for faculty, staff, and students who are doing cool things but it’s not necessarily enough to make an entire story or Spotlight out of it.
  • Spotlight
    • This is for highlighting faculty, staff, and students in an in-depth in a Q&A format.
  • Media mention
    • When a news outlet picks up one of our stories, we log it in this content type and display it on the news site to show how our word of our college is spreading.

Social media sharing

When we looked at our analytics of the old site, it wasn’t surprising to find that a large portion of our traffic was when something was shared to Facebook or Twitter. This made the decision easy to invest some resources into:

  • Making sure that the site is easily sharable
  • Making sure the teasers look good on accounts

Metatag module to the rescue

The Drupal metatag module was a YUGE help in making sure that our teasers looked good when shared on social media. If you’re using Drupal, this module is a no brainer.

Beautiful social media teasers, made possible by content strategy and the metatag module.

Google news sitemap module

Another must-have module is the Google news sitemap module. This ensures your articles and content are in a format that is easily consumable by Google. This allows our news stories to be indexed by Google news.

How our news stories appear in Google news search results
How our news stories appear in Google news search results

Human-centered workflow

Last but certainly not least, massive improvements were made to the editorial experience. Drupal gives a site maintainer/developer a tremendous amount of control over the editorial experience, which I tried to leverage as much as possible to make the site easy to update and maintain.

Tabs for each type of content

I’ve referenced this technique in another post and I can’t recommend it enough for improving the editorial experience. By cloning some administration views, we gave editors a super easy way to look at all content of a certain type. This helps reduce cognitive load, making editors more efficient.

Our news admin content interface
Our news admin content interface

I can’t tell you how many times I’ve logged into Drupal with a task in mind, and by the time I figure out which admin area I need to go to, I’ve forgotten what I was doing. Small shortcuts like this technique can reduce these errors and make people’s lives a little better.

Make common tasks as easy as possible

One of the tasks that our news team needs to do is to switch out our featured story once or twice a week, depending on what is happening on campus. I tried to make this as painless as possible, understanding that our writers are not web people. They’re writers. They shouldn’t need to be a web genius to change the featured news story.

Using a combination of views and nodequeue, I added a column to the “News Stories” content tab that allows our senior editor to simply click a link to make that story the featured story on the home page.

Using Views and Nodequeue, a link was added to our news stories admin list to make switching the featured story as easy as clicking a link

Make content guidelines visible

For each of the different types of content, guidelines were developed to ensure that the content would look great once no matter where it is syndicated or in what context it is used.

To help editors know what character count they are at for the summary, I wrote a small module that counts characters for the summary field. As you can see from the screen shot, even the greatest technical solution is at the whim of people and process.


A major feature of this news site is now the ability to syndicate news stories from the news site to academic department and college sites through the use of tags and AJAX.

We worked on a list of tags for editors to use that would allow them to syndicate a piece of content to a particular site based on what it was tagged. When implementing, I ensured the field had auto-complete in the add/edit form so we could reduce the number of slightly duplicate tags (for example, Physics department / Physics Department).

Example of news syndication to the Chemistry department website from our News site.
Example of news syndication to the Chemistry department website from our News site.

In closing: a note on people, process, and technology

As with any technology-related project, there are three components that lead to a successful product. People, process, and technology. People and process are vital, and also the most variable.

Sitting down with people to talk about their process is incredibly helpful when building the technical solutions. Often times when the technical team sits down to discuss process, the people who are closest to the process can’t really nail down what it is. That’s where it’s our job to ask questions and try to figure out how things work. This is absolutely necessary if we’re going to turn around a specific, concrete system that the process fits in.

It’s certainly a challenge and it’s never going to be perfect. People change and processes change. Good communication and trust between teams is the only way to get as close to the ideal as we can.

For this iteration, I think we did a really good job. The site is leaps and bounds better in regards to surfacing the latest goings-on at SUNY Oswego. Also, the editor experience is much better as pointed out by our writers who actually use the system (win!).

Embedding Drupal Views with the Paragraphs module

The Paragraphs module has been super helpful to developers and site builders who want to provide content editors with a solution to create amazing looking sites without having to know HTML.

I’m currently using Panels/Panelizer and Fieldable Panels Panes in the Drupal build at work to allow content editors to create the pages they want. Panels overall is great but I’ve come across situations where the In-Place Editor is buggy and/or creates confusion for users. The editing experience is a little wonky for them because between the node edit form and the In-Place Editor, there’s too many ways to skin a cat.

So, with our new department sites roll-out, I’m trying something new and moving away from Panels and going all in with Paragraphs. An immediate roadblock I ran into was How do I embed a View in my paragraphs page?

Viewreference module + Paragraphs

After asking around in Drupal IRC, a nice fellow pointed me in the direction of Viewreference. Once I came across this module, things started falling into place.

At a glance
  1. Install module
  2. Create a Paragraph bundle called “Embed view”
  3. Add a Viewreference field to the bundle
  4. Viola! Embed your views.

Install module

drush en viewreference -y

or download, unpack and upload to your module’s folder.

Create a paragraph bundle called “Embed view”

Add a view_reference field to the bundle

Now you can embed Views within a Paragraph bundle!

The result:

Sharing content between Drupal multi-sites with RESTful and Feeds modules

At Oswego, when we decided to go with Drupal multi-site, one of the biggest drawbacks was the ability “out of the box” to share content between sites. But when you think of it, how much of Drupal works just as you’d like right out of the box? We looked at a few options but what we ended up settling on was a combination of modules that is doing the trick nicely.


We have a branch campus that needs to pull in program information from another site (graduate studies). The branch campus editors should not be able to edit the content being brought in since they are not the content experts on the subject. Graduate studies maintains the “master” content, then needs to be periodically pulled into the branch campus site. Then, using views we can display a list of content that we pulled in.


Being a semi-Drupal-newbie, this took quite a bit of trial and error before I figured out something that will work. If you know of another solution to this, by all means leave a comment! I’d love to hear it.

First thing I did was set up the RESTful module on the graduate studies site. This module makes it very easy to be able to expose our graduate program data as a read-only REST endpoint. I experimented with exporting it as RSS, or trying to build something to export the graduate programs as CSV or some other form of structured data but ended up going with JSON via the REST module. JSON is so widely supported, readable, and consumable by so many other applications that it seemed like it was the best route to go.

I’m currently working on a post about setting up the RESTful module! Sign up for email updates to get notified.

The feeds module alone doesn’t consume JSON, but luckily there is a really nice module called Feeds Extensible Parsers.

I’m also working on a post about setting up the Feeds Extensible Parsers module to read JSON!

I currently have it set up to update the branch campus’ program content every 3 hours. Using Drupal’s role and permissions, I can configure it so the branch campus editors can only read the program content, keeping it in sync with the “master” copy.

Creating a hero page template in Drupal


  • Using Panopoly + Panels + Panelizer

Our current sub-pages look like this:

Screen Shot 2015-04-30 at 3.56.24 PM


Drupal is really good at having a consistent header throughout the site. But what if you want to have a landing page that looks like this:

Screen Shot 2015-04-30 at 3.58.00 PM

At first this seemed impossible to me, but after reading about theme_hook_suggestions and preprocess functions, I began to see the light.

  1. Create Hero Landing Page content type with appropriate fields
  2. Create image style to ensure the image is always the right size for the hero area
  3. Add theme_preprocess_page function to grab the image from the node
  4. Add a theme_hook_suggestion to load a different page template file
  5. Disable the hero image field in the default panels
  6. Profit

1. Create Hero Landing Page content type with appropriate fields

You don’t technically have to create a separate content type, but you do need a specific field to hold your hero image. I created a separate content type for landing pages because our landing pages will have some differences from basic pages within our system.

First thing I needed to do was create a “Hero Landing Page” content type that would be able to crank these types of pages out. Within this content type, I created a “Hero Image” field that would be used to hold the appropriate image. Keep note of the “field_landingpage_hero_image” field. That’s what we’ll need later to grab our image.

fields2. Create an image style for the hero image

If you don’t create an image style, you’ll be stuck with Drupal’s defaults which probably won’t suit your needs. In our case, we need the hero image to be 1920px x 768px in order to fit nicely within the theme. Navigate to admin/config/media/image-styles and create a new Image Style called “Landing Page Hero Image”. Under “Effect” choose “Scale and crop” and enter in 1920 for the width and 768 for the height. Once we apply this image style to the hero image field, this will take any image the user uploads and wrangle it into those dimensions.


3 + 4. Pull out the hero image so we can use it within our page template file & and a theme_hook_suggestion

Using Drupal’s hook system, we can override the template_preprocess_page() function to grab the hero image (if it exists) and make it accessible to the page template file. The way template_preprocess_page works is, you substitute your theme’s machine name for the word ‘template’, and pass in a reference to the $variable’s array. Now within the function you can play with the variables that Drupal is about to render on the page.

* Implements template_preprocess_page().
function oswego_preprocess_page(&$variables) {

  // Check to see if a hero image field is set
  if (isset($variables['node']->field_landingpage_hero_image[LANGUAGE_NONE][0])) {

    // Store the image into $img for easy reference
    $img = $variables['node']->field_landingpage_hero_image[LANGUAGE_NONE][0];

    // Build the $hero array to be used in templates/page/page--hero.tpl.php
    $variables['hero']['path'] = image_style_url('landing_page_hero_image', $img['uri']);
    $variables['hero']['alt'] = $img['alt'];
    $variables['hero']['title'] = $img['title'];

    // Add a theme hook suggestion to load templates/page/page--hero.tpl.php
    $variables['theme_hook_suggestions'][] = 'page__hero';

Note the function ‘image_style_url’ that is being called. The first parameter takes the machine name of an image style. In our case, we created our image style in step 2, so I’ll use the machine name of that image style. The function will then return the URL of the image using the specified image style.

By making a $variables[‘hero’] array, we can now access items within it on our page template file using $hero. For example, $hero[‘path’] will point to the URL that image_style_url built in our preprocess function. You can see within the code comments above that I make reference to a file called page–hero.tpl.php. By adding ‘page__hero’ to $variables[‘theme_hook_suggestions’], Drupal will now look for a page template file named page–hero.tpl.php.

Copy your existing page.tpl.php and name it page–hero.tpl.php. I won’t go into the specifics of how I used CSS to style it, but now it is possible to add the hero image in the new page–hero.tpl.php file. Example:

<div class="hero-image">
  <img src="<?php print $hero['path']; ?>" alt="<?php print $hero['alt']; ?>" title="<?php print $hero['title']; ?>">
  <?php if ($title): ?>
    <div class="hero-header">

    <div class="row">
      <div class="section-title-container">
        <div class="section-title-inner">
          <?php print $breadcrumb; ?>

    <h1 class="hero-title"><?php print $title; ?></h1>
  <?php endif; ?>

Disable the Hero Image within your panels configuration

This step will differ greatly depending on how you’re using panels/panelizer. For us, we have a default template that the content type goes into. By default I disabled the node:field_landingpage_hero_image pane so that the image wouldn’t display twice and confuse editors.


And that’s all! Quite a different process than I’m used to when I used to make WordPress themes, but still very effective. Drupal’s powerful hook system allows you to tap into the process and modify data, giving a themer and developer a ton of control. Drupal’s ability to separate logic (template.php) from the theme (*.tpl.php) files is pretty nice as well.

Migrating to Drupal

At work, we’re migrating a 10,000+ page site with 300+ editors to a single Drupal installation. At first, the task is extremely daunting, but if you learn to embrace the confusion, stick with it, and plan accordingly, a task as massive as this is absolutely doable and even rewarding!

I started a “Drupal Migration” category on my blog to document our journey to the promise land in hopes that it will help others in the same situation. I’m going to be talking in ideals here, but know that it’s basically impossible to stick to these absolutely. If you make an honest effort, gains will be had, even if you don’t execute perfectly. I’m going to go over where we’re currently at in this journey.

Work hard. Don’t be an asshole. Share what you know.
Brad Frost

Define the problem

Moving to a new CMS for no reason is a great recipe for pain. You need to have clear goals if the project is going to be a success. Some people on your team will be behind the goals more than others, and that’s absolutely fine — that’s life. As long as you know what you’re working towards, you can control the parts of the project that’s within your grasp.

In our case, our main goals for migrating are to have:

  • Reusable, structured content
  • A better editing experience (we’re migrating from Ingeniux)
  • Improved content quality
  • An updated look and feel

I’ve read articles on how people + process + technology is the magical equation for a successful IT related project. It’s naive to try to solve all three on your own. Establishing who is in charge of each of these areas will make the project go much smoother. Plenty of teams complete projects without balancing these three criteria, but I bet they have a few more grey hairs afterwards. The focus of most of these posts will be on technology and process, although I’d be willing to bet I touch on people as well.

Plan it out

Let’s clear something up right away. Drupal is not like WordPress. It’s not a CMS that you can slap a theme on and instantly have a site. It’s not like Webydoo, Wix, Weebly, or any other drag and drop website builder. It’s so much more than that. It can handle anything you throw at it, but you have to have a plan and understand how it works. This takes time. If you’re 2 weeks away from a deadline and you want to jump into Drupal and whip up a complex site, you’re going to have a bad time.

Since that’s out of the way, let’s talk about planning. When you’re migrating to Drupal, you’re not just shoveling content over from your previous CMS. If that’s your plan, you’re doing it wrong! I’d assume you want to move to Drupal in order to take advantage of how Drupal handles structured content. What you’re really doing is building a data layer for your entire organization. It’s so much more than a CMS.

Drupal and content strategy go hand in hand. Being able to think abstractly about your content will ensure you get the most out of Drupal. For example, in the context of a University website, what is a department page? What does that piece of content consist of? If you want to pull information in from other areas of your site, mapping out the structure of your content is absolutely vital. Nail it down, have meetings, have arguments, just figure it out. In our base case, we decided departments consist of:

  • A featured image
  • Positioning statement
  • List of degree programs
  • List of faculty
  • Student opportunities
  • Outcomes
  • List of events
  • List of announcements
  • Contact information

Items listed in bold refer to separate pieces of content which all consist of their own pieces. For example, abstractly, a faculty member might consist of:

  • Photo head shot
  • Full name
  • Title
  • Research interests
  • Department
  • Office hours

I could go on, but I hope you see my point. If you can think abstractly about the different pieces of content on your site, Drupal can help you weave this information together into something useful. I’d highly recommend reading Palantir’s Plan or Perish blog post. They do a fantastic job of explaining the importance of planning.

Helpful resources

Dare to fail

Unless you are a Drupal expert, it is very likely that your first try will be less than ideal. Drupal is a powerful, yet complex system. Give yourself time to learn the platform. Make mistakes. Break shit. Learn what doesn’t work. Acquia has a free development tool that allows you to mess around with Drupal on your local machine before committing to a live site. It’s much better to break stuff in a development environment than in production. The more times you fail, if you learn from it, the closer you are to succeeding.

Reach out for help

Drupal has a robust community of professionals that, in my experience, have been super helpful. To avoid a RTFM response, I’d recommend playing around locally and learning the ropes before reaching out to the community. Not because they won’t try to help you, but because there’s certain concepts that you learn about Drupal only after experiencing it first hand. is kind of a mess, but there’s lots of very useful information there. Take the time to learn.

Once you have a decent understanding of how some popular modules work, reach out to the community for clarification of how to reach your goals. I’d recommend having a good grasp of how the following modules function before you can really benefit from the community’s help:

  • Ctools
  • Views
  • Panels
  • Context
  • Organic Groups
  • Page manager
  • Am I missing any?

As I said earlier, Drupal is complex, but learning basics about the system will reap major benefits when you go to implement your site. Also become familiar with the following Drupal concepts:

  • Entities
  • Nodes
  • Contextual arguments (within Views)
  • Relationships (within Views)
  • View modes
  • Theme layer basics

Helpful resources

I’ve recently re-discovered the treasure trove that is IRC. IRC is where a lot of community members hang out, talk about Drupal, and help people with questions. I’ve had some great success in asking questions in #drupal, #panopoly, and #drupal-support channels. I’d highly recommend downloading an IRC client for your computer — or use KiwiIRC if you want to try it out — and logging into Freenode.

Wrapping up

That’s currently where we are in the process. We’ve hammered out most of the project requirements, got our hands dirty in a Drupal development environment, thought abstractly about our content, and gotten involved in the community. You may be thinking that’s a lot of work for still not having a live production site.

I’d agree that it’s a lot of work, but I’d rather measure twice and cut once.