Skip to content Skip to navigation

Blog

Shea McKinney Posted by Shea Ross McKinney on Monday, April 11, 2016 - 10:20am

There are times where I curse open source software but those times are far outweighed by the times that I am reminded why I love it so much.

Normally my blog posts are on the technical side because that is where I feel safe and comfortable writing in a public space but I felt compelled, okay, urged by the boss and team, to write about a moment that I gushed about during a recent staff meeting.

The week started off as a bug fix week, a sprint to tackle long-standing or annoying bugs that are in our sites and products. One peculiar bug was on our Subsite Feature: when an anonymous user first landed on the subsite node after a cache clear, they would be presented with the default (wrong) theme instead of an alternate theme. Before I even began, one of my workmates (John Bickar) pointed me to a blog article that clearly outlined the problem I was seeing. This was a very timely article as it was fresh off the press. Looking in to the issue I confirmed that, indeed, the issue described in the article was what I was seeing.

This spurred a major refactor in to how the module worked, but that is beside the point. If it wasn't for the fact that someone else wrote an article about the problem and solution, and my workmate hadn't passed it along, I would have spent many more hours in my debugger trying to figure out the cause of the issue. Yay open source!

Once the module was refactored to get around the issue with using hook_custom_theme() and loading entities, I passed off the final code to my other workmate, Greg Garvey, who did the majority of the heavy lifting of the refactor, to test to see if the solution was complete.

His testing came back negative; the issue was still happening in his environment.

Back and forth we went trying to figure out why he was still seeing the issue and why I was not. Through a bit of chance, we found out that another contributed module on his environment (subpathauto) had the same issue in it. Boo open source! Having already dealt with the issue once, I took it upon myself to fix the issue in the contributed module and posted a patch, which I hope will be adopted soon. Yay open source!

It may have been an unlikely path in which the patch came back to the subpathauto project but it really highlights the awesomeness that is open source and the Drupal community. Someone with the exact problem I faced took the time to write about it. Someone in my working group shared that information with me, and when I found the issue in another project I was able to contribute my knowledge back to it. I find times like these powerful and what will give Drupal the long term adoption we hope for.

Posted in:
Photo of John Bickar Posted by John Bickar on Friday, April 1, 2016 - 12:01am

The modern web developer has a variety of markup languages available for use in different contexts: XML, HTML, YAML, Markdown - the list goes on and on. Yet each has its limitation(s), whether that be performance, readability, or ease-of-use.

That all changes today with the introduction of the Syntactically Accurate Markup Language (SAML).

SAML is a human-readable markup language designed to be used in a variety of contexts - web, mobile, APIs, and so forth.

As the modern web moves away from desktop browsers and more towards "content anywhere, on any device", we need a markup language that supports that end.

The Premise of SAML

SAML is a straightforward, human-readable language. There are no tags, no attributes, no esoteric syntax. Words are what they mean; a new line is a new line; and punctuation is what it says it is.

To write SAML, you simply write.

SAML Example

As a concrete example, let's look at a list of items in SAML:

Apple
Orange
Banana
Pear
Watermelon

Now, let's compare the same list in HTML:

<ul>
<li>Apple</li>
<li>Orange</li>
<li>Banana</li>
<li>Pear</li>
<li>Watermelon</li>
</ul>

As you can see, SAML is clean, forthright, and syntactically accurate.

Special Symbols in SAML

As SAML is syntactically accurate, it supports all of the usual punctuation symbols. There are no hidden meanings.

Below is a summary of commonly-used punctuation marks and their equivalent in SAML:

Text Punctuation Mark SAML Equivalent
. .
, ,
! !
? ?
¿ ¿
¡ ¡
# #

 

Advantages of SAML

  1. Readability: In SAML, words and punctuation are used to create sentences. Sentences are used to create paragraphs. It's that simple.
  2. Performance: In the list example above, SAML is 37 bytes, compared to 92 bytes for HTML. That's a 248% increase in performance.
  3. Security: No Bobby Tables in SAML; a semicolon is just a semicolon.
  4. Device-independence: SAML is device-agnostic. Desktop browser, tablet, mobile phone, app, pen-and-paper - SAML works on them all.
  5. Backwards-Compatibility: SAML is compatible with all historical web browsers (only tested as far back as Mosaic 0.5) and mobile devices.
  6. Multilingual: SAML is language-independent. You can write SAML in any language you wish.

SAML Sounds Great - What Now?

At Stanford University, we are dedicated to finding solutions to big challenges. At Stanford Web Services, we believe in the power of open source, and releasing early and often.

Therefore, today we are announcing the open-source release of SAML 0.1. Learn more at discoversaml.org.

Posted in:
Caryl Westerberg Posted by Caryl J Westerberg on Friday, March 4, 2016 - 3:55pm

We are excited to announce that registration and session proposals are now open for Stanford Drupal Camp 2016!

Register now for the seventh Annual Stanford Drupal Camp April 1-2, 2016 at the Stanford Law School.

https://drupalcamp.stanford.edu/user/register

Drupal Camp is a great opportunity for the Stanford Drupal community to come together and share new approaches, best practices for the web, and love of Drupal. The schedule includes great sessions for those new to the web and Drupal all the way to advanced users and plenty of opportunities to network with colleagues.

We will have tracks for web content strategy, user experience and design, operations and development (DevOps), and building sites for research and academia.

As always, it’s free!

Once you've registered, you are invited to propose a session. In the right sidebar, click on Propose a Session!

If you have any questions, please contact [email protected]

Happy Drupalling, and look forward to seeing you in April!

Posted in:
Sara Worrell-Berg Posted by Sara Worrell Berg on Tuesday, February 23, 2016 - 4:49pm

University IT will perform maintenance on the Stanford Sites Drupal hosting service on the following date:

This maintenance requires switching Stanford Sites to using its secondary database server in preparation for upcoming maintenance on the university's network. Planned changes should result in improved stability and faster performance for all websites hosted on Stanford Sites. This maintenance does not include Drupal core application or module updates.

Website owners should avoid content or configuration changes to their websites hosted on the Stanford Sites Drupal hosting service between 4:45-5:30 AM on Thursday, February 25. A brief loss of connection to the database server can be expected, though there should be no data loss or extended downtime.

Monitor https://uitalerts.stanford.edu for more information.

If you experience issues with your website(s) hosted on Stanford Sites, please submit a HelpSU request. We will respond as soon as possible.

Thanks for using Stanford Sites!

Posted in:
Jamie Posted by Jamie C. Tsui on Friday, February 12, 2016 - 12:25pm

Stanford Web Services serves a diverse set of clients throughout Stanford University, ranging as large as schools to as small as individual labs. With over 200 active or completed website projects, and an average of 18 new project inquiries per month, we needed to implement a Customer Relationship Management system to track all of our operational data and communications.

Which CRM?

Last year we evaluated 7 different CRMs, including: Insightly, SalesForce, Zoho, Sugar CRM, HubSpot, RedHen, and Podio. After analyzing each of the options through an evaluation matrix based on our needs, we settled on Podio for our team. It has now been over 7 months since we’ve migrated all of our data from disparate systems into Podio, and the reception has been very positive across all roles in the team. We were able to consolidate various types of information from Basecamp, Google Docs/Sheets, Excel files, email, mailing lists, and even information that only existed in our staff’s memory.

Importing and Setting Up Your Data

One of the critical requirements for adding a CRM to our operations was its ease of data import and export. Podio, at its core, can be thought of as a UI on top of a relational database, so we found it extremely flexible and customizable for our needs. It’s quick and simple to import and export data in Excel format. We set up several “apps” for each of our types of data: an “app” is similar to that of a Content Type in Drupal, though simplified. We have apps for our leads, organizations, projects (completed and in progress), website launches calendar, help tickets, products (we have several product offerings, including the Jumpstart product line), potential deals (new inquiries), website theme information, vendor contacts, and more.

Connectivity and API

Using Podio’s “Email API”, we were able to easily integrate a number of other systems to feed data into Podio. Although Podio has built-in support for webforms, we use Qualtrics to create web forms with question display logic and email triggers to customize the data that gets fed into Podio (such as for help tickets or new project inquiries). We’ve also used ZenDesk’s triggers to pass help ticket information from one of our partners to Podio.

By having all of our operational data in one system, we were able to improve our operations across the board, from the intake level all the way through to the support level. We can take a look at an organization’s listing and easily see all of our active and completed projects with them, their related help tickets, a list of new project inquiries from them, as well as the potential value of those new projects.

The inbox is not where you store communications

Another one of the primary goals for implementing a CRM was to record communications more visibly and permanently as opposed to in an individual’s email or via a mailing list. Within each of these items in Podio, such as a single project, or a single help ticket, Podio allows users to add comments and attachments via an “activity stream”. This feature essentially improves coordination and communication within the team: such as if someone needs to take over a deal consultation from another team member and wants to read all the past communications with that client. To do this, our team member would simply CC or BCC the “Email To Item” email address provided by Podio for that specific item. This process also ensures information retention for the team. Changes to fields within an item are also tracked in the activity stream, allowing us to see who made the change and when.

A single point of reference

Podio serves as first point of reference for information: from there, we can link out to a project’s relevant Harvest listing, JIRA project, Basecamp listing (if applicable), as well as links to a project’s development and production site URLs. Since implementing it with our operations, it has saved countless hours of searching and coordination, as well as improved communications and information awareness within our team.

Have you looked into CRMs for your team, or do you use one already? How has your experience been? What are your favorite features from your CRM?

Photo of John Bickar Posted by John Bickar on Tuesday, February 2, 2016 - 8:25am

In November, 2015, the Stanford Web Services team got to dive into Drupal 8 during a weeklong sprint. I was excited to look at the RESTful web services that Drupal 8 gives out-of-the-box; what follows is my documentation of the various types of requests supported, required headers, responses, and response codes.

This is not intended to be an exhaustive documentation of RESTful web services in Drupal 8. However, I have pulled information from various posts around the Web, and my own experimentation, into this post.

A REST client application (e.g., Paw for Mac OS X) is extremely handy for experimenting with RESTful web services in Drupal 8.

Contents

  1. Resources
  2. GET Request
  3. POST Request
  4. DELETE Request
  5. PATCH Request

Resources

GET Request

The GET request is the simplest, and requires no authentication (if permissions are configured to allow anonymous users to "Access GET on Content resource"). Just send a GET request to the node path and add a _format=hal_json URL parameter.

More documentation available at drupal.org.

Request

https://example.com/node/<nid>?_format=hal_json

Response

200 OK

{
  "_links": {
    "self": {
      "href": "https://example.com/node/8?_format=hal_json"
    },
    "type": {
      "href": "https://example.com/rest/type/node/article"
    },
    "https://example.com/rest/relation/node/article/uid": [
      {
        "href": "https://example.com/user/3?_format=hal_json",
        "lang": "en"
      }
    ],
    "https://example.com/rest/relation/node/article/revision_uid": [
      {
        "href": "https://example.com/user/3?_format=hal_json"
      }
    ],
    "https://example.com/rest/relation/node/article/field_tags": [
      {
        "href": "https://example.com/taxonomy/term/2?_format=hal_json",
        "lang": "en"
      }
    ]
  },
  "uuid": [
    {
      "value": "a57f21eb-a4fe-4c04-8507-7a9cb1255834"
    }
  ],
  "type": [
    {
      "target_id": "article"
    }
  ],
  "langcode": [
    {
      "value": "en",
      "lang": "en"
    }
  ],
  "title": [
    {
      "value": "Test Article 2",
      "lang": "en"
    }
  ],
  "_embedded": {
    "https://example.com/rest/relation/node/article/uid": [
      {
        "_links": {
          "self": {
            "href": "https://example.com/user/3?_format=hal_json"
          },
          "type": {
            "href": "https://example.com/rest/type/user/user"
          }
        },
        "uuid": [
          {
            "value": "46a5a516-2d00-41fa-b300-f0342bec87f5"
          }
        ],
        "lang": "en"
      }
    ],
    "https://example.com/rest/relation/node/article/revision_uid": [
      {
        "_links": {
          "self": {
            "href": "https://example.com/user/3?_format=hal_json"
          },
          "type": {
            "href": "https://example.com/rest/type/user/user"
          }
        },
        "uuid": [
          {
            "value": "46a5a516-2d00-41fa-b300-f0342bec87f5"
          }
        ]
      }
    ],
    "https://example.com/rest/relation/node/article/field_tags": [
      {
        "_links": {
          "self": {
            "href": "https://example.com/taxonomy/term/2?_format=hal_json"
          },
          "type": {
            "href": "https://example.com/rest/type/taxonomy_term/tags"
          }
        },
        "uuid": [
          {
            "value": "14bd6eeb-f0f1-4fd1-b200-e27246318b7c"
          }
        ],
        "lang": "en"
      }
    ]
  },
  "status": [
    {
      "value": "1",
      "lang": "en"
    }
  ],
  "created": [
    {
      "value": "1446588457",
      "lang": "en"
    }
  ],
  "changed": [
    {
      "value": "1446589578",
      "lang": "en"
    }
  ],
  "promote": [
    {
      "value": "1",
      "lang": "en"
    }
  ],
  "sticky": [
    {
      "value": "0",
      "lang": "en"
    }
  ],
  "revision_timestamp": [
    {
      "value": "1446588457"
    }
  ],
  "revision_translation_affected": [
    {
      "value": "1",
      "lang": "en"
    }
  ],
  "default_langcode": [
    {
      "value": "1",
      "lang": "en"
    }
  ],
  "comment": [
    {
      "status": "2",
      "cid": "0",
      "last_comment_timestamp": "1446588457",
      "last_comment_name": null,
      "last_comment_uid": "3",
      "comment_count": "0",
      "lang": "en"
    }
  ]
}

Authentication

POST, DELETE and PATCH requests require a CSRF token, as well as HTTP Basic Authentication (with a user's Drupal user name and password).

Get the token at https://example.com/rest/session/token

POST Request

Request

https://example.com/entity/node

Headers

Header NameHeader Value
X-CSRF-Token(token from rest/session/token)
AuthorizationBasic (hashed username/password)
Content-Typeapplication/hal+json

Body

{
  "_links": {
    "type": {
      "href": "https://example.com/rest/type/node/article"
    }
  },
  "title": {
    "value": "Test Article 2"
  },
  "type": {
    "target_id": "article"
  }
}

Response

200 OK

DELETE Request

Request

https://example.com/node/<nid>

Headers

Header NameHeader Value
X-CSRF-Token(token from rest/session/token)
AuthorizationBasic (hashed username/password)

Response

204 No Content

PATCH Request

Use the PATCH method to update an existing entity.

Request

https://example.com/node/<nid>

Headers

Header NameHeader Value
X-CSRF-Token(token from rest/session/token)
AuthorizationBasic (hashed username/password)
Content-Typeapplication/hal+json

Body

{
  "_links": {
    "type": {
      "href": "https://example.com/rest/type/node/article"
    }
  },
  "nid": {
    "": {
      "value": "8"
    }
  },
  "type": {
    "target_id": "article"
  },
  "promote": {
    "value": "1"
  },
  "body": {
    "": {
      "value": "<p>foo bar baz</p>",
      "lang": "en"
    }
  }
}

Response

204 No Content

Posted in:
Cynthia Mijares Posted by Cynthia Mijares on Thursday, December 17, 2015 - 8:00am

2015 has been amazing! Big thanks to all of our wonderful and devoted colleagues around the university and in the community. We wish you happy holidays over the winter break, and we'll see you in 2016!

 

Team photo

Posted in:
Shea McKinney Posted by Shea Ross McKinney on Wednesday, December 9, 2015 - 9:14am

Not all modules belong on Drupal.org

Over time Stanford Web Services has built a large library of custom modules, features, and themes. Some of the work made its way back to Drupal.org, but some of it is specific to Stanford or higher education types. You can find most of this work on our GitHub organization page as we like to be open source. Not only do we share our code with the Stanford community...we share with the whole Drupal community. Anyone and everyone can download and use the things we build. 

Sometimes the things we build have bugs and need to be updated. A problem with our features and custom modules is that they don't have an update status like those available from Drupal.org. Some folks have asked us "Why don't you run a features server" to support update status? The reason is that we like to work with GitHub, and it provides us and our developers many tools that a features server does not have. The good news is that GitHub has an API and a release system. This allowed us to create a module to get update status information from GitHub into Drupal.

We called it ERUS

You can find ERUS on the project page of Drupal.org or on our GitHub account. ERUS stands for External Repository Update Status. With this module, and a line in your module's .info file, you can get information about release status for your custom modules and themes right in Drupal. This has proven valuable for us as more and more teams across our campus adopt and use our shared work. We don't know where our work will end up next and cannot expect those who install our modules to follow our GitHub pages. Using this module, they can get the update information they need right in their website.

How it works

  1. Pick one of your features or custom modules on GitHub. It has to be in its own repository like: https://github.com/SU-SWS/stanford_bean_types
  2. Add `project status url` to the .info file of the module that is the full url to the GitHub page. Look at this example.
  3. Set the version number to something that conforms to the Drupal 7 version naming scheme, e.g.: 7.x-1.0-dev or 7.x-1.1
  4. Create a new release via GitHub's release system using the same name as the version.
  5. Download and enable the ERUS module in your Drupal site.
  6. (optional) If the repository is private you will need to enter a GitHub username and password that can read from the repository.
  7. Visit the update status page in your Drupal site to see the versions.

You can also use Drush to view and update the modules.

For more information on the installation, configuration, and extension of this module, please visit: https://github.com/SU-SWS/erus and https://github.com/SU-SWS/erus/blob/7.x-1.x-dev/plugins/README.md

Example of ERUS in action

Update Status Bar

Credits

Thanks to Zach Chandler and Brian Wood for their contributions to this project.

Johan Baath Posted by Johan Baath on Monday, November 30, 2015 - 8:15am

Even though it feels like I have known the SWS team for years, the truth is that I have only been here for two months. The reason it feels that way might be because of the amount of things I’ve learned from my colleagues over the past 8 weeks could be compared to an intense 4-year combined degree in Computer Science/Customer Relations/Project Management. Another reason could be that the amazing people that comprise this team make you feel at home right away.

Why is SWS so good at what they do?

Something that became clear to me after just a couple of days working here was that the SWS team doesn't just call themselves a team, they area team. When someone has a lot on their plate while others don’t, they simply help each other out. This might sound banal, but far too often people within an organization do their own thing and don't bother about helping their coworkers because “it’s not their job." The reason why SWS manages to function as a team is because everyone on the team is highly flexible: the developers help out producers with their tasks; the producers help out developers with some of their tasks; the PMs jumps in wherever they’re needed. This allows for a high-productivity team that wouldn’t be able to function as it does now if part of the team just stood by the sideline and observed the bottlenecks that slowly brings down the overall productivity.

The power of communication

Communication is the key to everything in organizations such as SWS. Without good communication the team would hit multiple brick walls everyday, but SWS rarely (never as far as I know) does. Every morning at 9.30 am the team gathers in the collaboration space for a SCRUM meeting where everyone briefs the others what is on their agenda for the day. This is a perfect opportunity for people who are blocked from doing something to bring this up to the team’s attention, and by doing so opens up the possibility to get help from someone who knows how to tackle the issue at hand.

Every Friday the team has what is called "Morning of Awesome" (Mo'A), where they sit together in the collaboration space for two hours. During MoA the team could break into small groups and work on a project together, or everyone just sits together and works on their own things and asks the rest of the team for help if needed. One particularly valuable thing with these mornings is how it strengthens the team to work together as an organism, and not as separate entities. This is especially important for teams that have many different roles but also a product that depends on how these different parts come together. 

The willingness to help others

Instead of having someone on the team taking over the tasks that you can’t do, wouldn’t it be better practice to transfer the knowledge on how to solve the problem at hand? This is something that SWS does extremely well: they block a time to go over the issue at hand, solve it together and BAAM: next time the same issue comes up you have two people that know how to deal with it. If you instead frame these issues to only let one person to deal with them, you're depending too much on having this person available all the time. 

This willingness to help others extends far beyond the boundaries of the team - they contribute to the Stanford community by writing this blog, providing a user guide and also by attending conferences where they share their experience and knowledge with other Universities. 

The importance of having fun

In addition to being a high-performing, professional team with lots of flexibility; SWS also knows the importance of having fun. There’s a fine line between ‘having fun’ and ‘just goofing around’ in the workplace, and this is where the excellent management comes into the picture. Having management that is aware of this fine line and knows how to keep the team's eye on the prize while having fun - without wasting precious time - is to me astonishing and what I believe to be one of the key components to this extremely attractive workplace.

Last words

I am extremely grateful that I had the opportunity to work with these amazing people. Even though I’ve only been here for 8 weeks I’m confident when I say that every single one of the people on the team has taught me something that I will bring with me 5,379.96 miles over the Atlantic Ocean when I go back to Sweden.

Posted in:
Posted by Greg Garvey on Tuesday, November 17, 2015 - 8:05am

The development team was recently given the opportunity to stand up a Drupal 8 REST server with the intent of improving on our D7 content server, learning what's new with the framework and seeing how our content types would fit into the revised architecture. Having just attended BADcamp at UC Berkeley, we were excited to use Drupal 8 and its new special sauce (yml, composer, console, bigpipe, twig, etc).

The foray started with a quick win. Standing up a REST service with Drupal 8 was wicked fast (note: I blame the use of the word 'wicked' on marrying someone from Boston). We leveraged the core web services modules HAL, HTTP Basic Authentication, RESTful Web Services, and Serialization.

Next, we installed REST UI and Self Documenting REST API. REST UI gives you point and click configuration of your REST API end-points and Self Documenting REST API provides...well, you guessed it, a self documenting API for your REST server. REST UI has a very easy to use GUI and made getting endpoints set up a breeze. Self Documenting REST API was easy to set up and while documenting GET fairly well, it lacked some of the detailed documentation for using POST, DELETE and PATCH. I tested the endpoints using google Postman, but other tools such as PAW or DHC would work as well.

First reactions to using Drupal 8 for a REST server were positive. HAL (Hypertext Application Language) is awesome! Hyperlinks between resources in your API make it really great for exploring and understanding how the API works. Tacking '?_format=hal_json' onto a node/{nid} path and getting usable objects was effortless. 

Serving up real content types with Drupal 8 REST services was a mixed bag of success and failure based on the availability of working contrib modules that our field types used. The fierce pace of contrib module development will likely have things running more smoothly by the time of Drupal 8's release slated for November 19, 2015.

Pages

Subscribe to Stanford Web Services Blog