Jun 18 2018
Jun 18
June 18th, 2018

Last month, Ithaca College introduced the first version of what will represent the biggest change to the college’s website technology, design, content, and structure in more than a decade—a redesigned and rebuilt site that’s more visually appealing and easier to use.

Over the past year, the college and its partners Four Kitchens and design firm Beyond have been hard at work within a Team Augmentation capacity to support the front-to-back overhaul of Ithaca.edu to better serve the educational and community goals of Ithaca’s students, faculty, and staff. The results of the team’s efforts can be viewed at https://www.ithaca.edu.  

Founded in 1892, Ithaca College is a residential college dedicated to building knowledge and confidence through a continuous cycle of theory, practice, and performance. Home to some 6,500 students, the college offers more than 100 degree programs in its schools of Business, Communications, Humanities and Sciences, Health Sciences and Human Performance, and Music.

Students, faculty, and staff at Ithaca College create an active, inclusive community anchored in a keen desire to make a difference in the local community and the broader world. The college is consistently ranked as one of the nation’s top producers of Fulbright scholars, one of the most LGBTQ+ friendly schools in the country, and one of the top 10 colleges in the Northeast.

We emphasized applying automation and continuous integration to focus the team on the efficient development of creative and easy to test solutions.

On the backend, the team—including members of Ithaca’s dev org working alongside Four Kitchens—built a Drupal 8 site. The transition to Drupal 8 keeps the focus on moving the college to current technology for sustainable success. Four Kitchens emphasized applying automation and continuous integration to focus the team on the efficient development of creative and easy to test solutions. To achieve that, the team set up automation in Circle CI 2.0 as middleware between the GitHub repository and hosting in PantheonGitHub was used throughout the project to implement, automate, and optimize visual regression, advanced communication between systems and a solid workflow using throughout the project to ensure fast and effective release cycles. Learn from the experiences obtained from implementing the automation pipeline in the following posts:

The frontend focused heavily on the Atomic Design approach. The frontend team utilized Emulsify and Pattern Lab to facilitate pattern component-based design and architecture. This again fostered long-term ease of use and success for Ithaca College.

The team worked magic with content migration. Using the brainchild of Web Chef, David Diers, the team devised a plan to migrate of portions of the site one by one. Subsites corresponding to schools or departments were moved from the legacy CMS to special Pantheon multidevs that were built off the live environment. Content managers then performed a moderated adaptation and curation process to ensure legacy content adhered to the new content model. A separate migration process then imported the content from the holding environment into the live site. This process allowed Ithaca College’s many content managers to thoroughly vet the content that would live on the new site and gave them a clear path to completion. Learn more about migrating using Paragraphs here: Migrating Paragraphs in Drupal 8

Steady scrum rhythm, staying agile, and consistently improving along the way.

In addition to the stellar dev work, a large contributor to the project’s success was establishing a steady scrum rhythm, staying agile, and consistently improving along the way. Each individual and unit solidified into a team through daily 15-minute standups, weekly backlog grooming meetings, weekly ‘Developer Showcase Friday’ meetings, regular sprint planning meetings, and biweekly retrospective meetings. This has been such a shining success the internal Ithaca team plans to carry forward this rhythm even after the Web Chefs’ engagement is complete.     

Engineering and Development Specifics

  • Drupal 8 site hosted on Pantheon Elite, with the canonical source of code being GitHub and CircleCI 2.0 as Continuous Integration and Delivery platform
  • Hierarchical and decoupled architecture based mainly on the use of group entities (Group module) and entity references that allowed the creation of subsite-like internal spaces.
  • Selective use of configuration files through the utilization of custom and contrib solutions like Config Split and Config Ignore modules, to create different database projections of a shared codebase.
  • Migration process based on 2 migration groups with an intermediate holding environment for content moderation.
  • Additional migration groups support the indexing of not-yet-migrated, raw legacy content for Solr search, and the events thread, brought through our Localist integration.
  • Living style guide for site editors by integrating twig components with Drupal templates
  • Automated Visual Regression
Aerial view of the Ithaca College campus from the Ithaca College homepage. From the Ithaca College Homepage.

A well-deserved round of kudos goes to the team. As a Team Augmentation project, the success of this project was made possible by the dedicated work and commitment to excellence from the Ithaca College project team. The leadership provided by Dave Cameron as Ithaca Product Manager, Eric Woods as Ithaca Technical Lead and Architect, and John White as Ithaca Dev for all things legacy system related was crucial in the project’s success. Ithaca College’s Katherine Malcuria, Senior Digital User Interface Designer,  led the creation of design elements for the website. 

Katherine Malcuria, Senior Digital User Interface Designer, works on design elements of the Ithaca.edu website

Ithaca Dev Michael Sprague, Web Chef David Diers, Architect,  as well as former Web Chef Chris Ruppel, Frontend Engineer, also stepped in for various periods of time on the project.  At the tail end of the project Web Chef, Brian Lewis, introduced a new baby Web Chef to the world, therefore the amazing Randy Oest, Senior Designer and Frontend Engineer, stepped in to assist in pushing this to the finish line from a front-end dev perspective. James Todd, Engineer, pitched in as ‘jack of all trades’ connoisseur helping out where needed.

The Four Kitchens Team Augmentation team for the Ithaca College project was led by Brandy Jackson, Technical Project Manager, playing the roles of project manager, scrum master, and product owner interchangeably as needed. Joel Travieso, Senior Drupal Engineer, was the technical lead, backend developer, and technical architect. Brian Lewis, Frontend Engineer, meticulously worked magic in implementing intricate design elements that were provided by the Ithaca College design team, as well a 3rd party design firm, Beyond, at different parts of the project.

A final round of kudos goes out to the larger Ithaca project team, from content, to devOps, to quality assurance, there are too many to name. A successful project would not have been possible without their collective efforts as well.

The success of the Ithaca College Website is a great example of excellent team unity and collaboration across multiple avenues. These coordinated efforts are a true example of the phrase “teamwork makes the dream work.” Congratulations to all for a job well done!

Special thanks to Brandy Jackson for her contribution to this launch announcement. 

Four Kitchens

The place to read all about Four Kitchens news, announcements, sports, and weather.

Aug 02 2017
ao2
Aug 02

Drupal 8 is quite an improvement over previous versions of Drupal with regard to the reproducibility of a site from a minimal source repository.

The recommended way to set up a new Drupal 8 site is to use composer, and the most convenient way to do that is via drupal-composer/drupal-project, which brings in Drush and drupal-console as per-site dependencies; from there the site can be installed and managed.

However the fact that Drush and drupal-console are per-site dependencies poses a problem: they are not available until the site dependencies have been downloaded, this means that it's not really possible to add “bootstrapping” commands to them to make it easier to set up new projects.

This is what motivated me to put together drupal-init-tools: a minimalistic set of wrapper scripts which can be used when Drush and drupal-console are not available yet, or when they have to be combined together to perform a task in a better way.

drupal-init-tools has been developed mainly to speed up prototyping, and it is particularly useful to set up sites under ~/public_html when the web server is using something like the Apache userdir module; however I feel it could be useful in production too after some cleanups.

drupal-init-tools standardizes the setup and installation of new Drupal projects: for example the drin new command makes sure that the original drupal-composer/drupal-project repository is still accessible from an upstream git remote so that the developer can easily track changes in drupal-composer/drupal-project and keep up if appropriate for their particular project.

Some drin commands also provide a nicer interface for frequent and important tasks, like the actual site-install step, or the creation of an installation profile that could replicate the installed site.

Here are some examples of use taken from the drin manual.

Create and install a new Drupal project:

cd ~/public_html
drin new drupal_test_site
cd drupal_test_site
$EDITOR bootstrap.conf
drin bootstrap --devel

Create an installation profile from the currently installed project:

drin create-profile "Test Profile" test_profile

Clean and rebuild the whole project to verify that installing from scratch works:

drin clean
drin bootstrap

A quick way to test drupal-init-tools is this:

git clone git://git.ao2.it/drupal-init-tools.git
cd drupal-init-tools/
make local
./drin --help

Give it a go and let me know what you think.

If it proves useful to others I could have it packaged and uploaded to Debian to make it more “official”, IMHO it makes sense to have such a small meta-tool like drin as a system global command.

Jun 12 2017
ao2
Jun 12

Most of the information I have come across about migrating from Drupal 6 to Drupal 8 is about migrating content, however before tackling this problem another one must be solved, maybe it is obvious and hence understated, so let's spell it out loud: preserving the site functionality.

That means checking if the contrib modules need to be ported to Drupal 8, and also checking if the solution used in the previous version of the site can be replaced with a completely different approach in Drupal 8.

Let's take ao2.it as a study case.

When I set up ao2.it back in 2009 I was new to Drupal, I choose it mainly to have a peek at the state of Open Source web platforms.

Bottom line, I ended up using many quick and dirty hacks just to get the blog up and running: local core patches, theme hacks to solve functional problems, and so on.

Moving to Drupal 8 is an opportunity to do things properly and finally pay some technical debt.

For a moment I had even thought about moving away from Drupal completely and use a solution more suited to my usual technical taste (I have a background in C libraries and linux kernel programming) like having the content in git and generate static web pages, but once again I didn't want to miss out on what web frameworks are up to these days, so here I am again getting my hands dirty with this little over-engineered personal Drupal blog, hoping that this time I can at least make it a reproducible little over-engineered personal Drupal blog.

In this series of blog posts I'll try to explain the choices I made when I set up the Drupal 6 blog and how I am re-evaluating them for the migration to Drupal 8.

The front page view

ao2.it was also an experiment about a multi-language blog, but I never intended to translate every content, so it was always a place where some articles would be in English, some in Italian, and the general pages would be actually multi-language.

This posed a problem about what to show on the front page:

  • If every node was shown, there would be duplicates for translated nodes, which can be confusing.
  • If only nodes in the current interface language were shown, the front page would list completely different content across languages, which does not represent the timeline of the blog content.

So a criterion for a front page of a partially multi-lingual site could be something like the following:

  • If a node has a translation in the current interface language, show that;
  • if not, show the original translation.

The “Select translation” module

In Drupal 6 I used the Select translation module which worked fine, but It was not available for Drupal 8.

So I asked the maintainers if they could give me the permission to commit changes to the git repository and I started working on the port myself.

The major problem I had to deal with was that Drupal 6 approached the multi-language problem using by default the mechanism called "Content translations" where separate nodes represented different translations (i.e. different rows in the node table each with its own nid), tied together by a tid field (translation id): different nodes with the same tid are translations of the same content.

Drupal 8 instead works with "Entity translations", so one single node represents all of its translations and is listed only once in the node table, and actual translations are handled at the entity field level in the node_filed_data table.

So the SQL query in Select translation needed to be adjusted to work on the node_filed_data rather than of the node table, as it can be seen in commit 12f70c9bb37c.

While at it I also took the chance to refactor and clean up the code, adding a drush command to test the functionality from the command line.

The code looks better structured thanks to the Plugin infrastructure and now I trust it a little more.

Preserve language

On ao2.it I also played with the conceptual difference between the “Interface language” and the “Content language” but Drupal 6 did not have a clean mechanism to differentiate between the two.

So I used the Preserve language module to be able to only switch the interface language when the language prefix in the URL changed.

It turns out that an external module is not needed anymore for that because in Drupal 8 there can be separate language switchers, one for the interface language and one for the content language.

However there are still some issues about the interaction between them, like reported in Issue #2864055: LanguageNegotiationContentEntity: don't break interface language switcher links, feel free to take a look and comment on possible solutions.

More details about the content language selection in a future blog post.

Jul 17 2012
ao2
Jul 17

There are cases when you want to export some content from a website, in order to import the same content at some later point into a similar website in an automated fashion.

In my case I want some “default content” to be imported every time I rebuild a Drupal site with drush make, this is particularly useful if you are building a Drupal distribution or a Drupal installation profile, or basing your product on these concepts.

I am going to show how to set up a source site and a destination site, and one possible way to export and import the content from and into Drupal.

In the following text there are some assumptions:

  • The Operating System is Debian GNU/Linux, in particular the group of the web server is www-data.
  • The web server has per-user web directories configured, and the user name is username; you have to substitute your own in URLs when you follow the instructions below.
  • The DBMS is MySQL (BTW, when drush sql-create becomes available I may update the article and drop this assumption).
  • In the code sections below, lines starting with $ are supposed to be commands to be written in a command line shell.
  • The reader has some Drupal knowledge, especially with regard to modules installation and content creation, knowing what the Features and Deploy modules do is a plus.

I used the OpenOutreach distribution because it is simple enough and provides a default content type which supports images, which are not trivial to export.

Let's get started.

A script to set up test sites

Here is a script to make it easier to build test sites under $HOME/public_html/, let's call it create_test_site.sh:

#!/bin/sh
 
set -e
 
[ $# -eq 5 ] || { echo "usage: $(basename $0) <db_name> <db_user> <db_password> <site_path> <site_name>" 1>&2; exit 1; }
 
DB_NAME="$1"
DB_USER="$2"
DB_PASS="$3"
 
echo -n "MySQL root user. "
mysql -u root -p <<EOM
CREATE DATABASE IF NOT EXISTS ${DB_NAME};
USE ${DB_NAME};
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES \
ON ${DB_NAME}.*
TO '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
FLUSH PRIVILEGES;
EOM
 
SITE_PATH="$4"
SITE_NAME="$5"
 
DISTRIBUTION=openoutreach
INSTALLATION_PROFILE=standard
WEB_SERVER_GROUP="www-data"
 
(
  cd $HOME/public_html
  drush dl "$DISTRIBUTION" --drupal-project-rename="$SITE_PATH"
  cd "$SITE_PATH"
  drush site-install "$INSTALLATION_PROFILE" \
    --site-name="$SITE_NAME" \
    --db-url="mysql://${DB_USER}:${DB_PASS}@localhost/${DB_NAME}"
  sed -i "[email protected]# RewriteBase /drupal\[email protected] /~${USER}/${SITE_PATH}@" .htaccess
  chmod 775 sites/default/files && \
  sudo chgrp -R "$WEB_SERVER_GROUP" sites/default/files
)

Set up the source site, create and export some content

Creating a new site is as simple as:

$ cd ~/public_html/
$ ./create_test_site.sh drupal_test_src user_test_src pass_test_src openoutreach_src "Source site"

The admin password will be printed on the standard output.

Log in to http://localhost/~username/openoutreach_src, go to node/add and create some contents with images.

Install the modules needed to export the content (NOTE: development versions are needed for now):

$ cd ~/public_html/openoutreach_src
$ drush dl --dev ctools deploy entity entity_dependency features uuid
$ drush en deploy deploy_ui entity entity_dependency features uuid
$ drush cc all

Go to admin/structure/deploy/plans/add and create a new deployment plan selecting these options:

  • Managed aggregator
  • Fetch-only

Go to admin/content, select some content and add it to the deployment plan using the “Update Options” dropdown menu.

Go to admin/structure/features/create in order to export the content to a Feature:

  1. Choose a name (e.g. Default Content) and a version (e.g. 7.x-0.1)
  2. select the option “Deployment: deploy_plans” from the “Edit components” dropdown menu, and you will see the deployment plan defined before;
  3. check it;
  4. select the option “UUID entities: uuid_entities” from the “Edit components” dropdown menu, and you will see an entry with the same name of the deployment plan defined before;
  5. check the entry with the same name of the deployment plan;
  6. then click on “Download feature”.

Let's say that the new feature module is called default_content-7.x-0.1.tar

NOTE

The resulting feature seems to be lacking dependencies, not only the needed modules from above are missing, but for instance the content type of the exported nodes is not mentioned anywhere either.

Anyhow, as long as you move contents between site installations with the same configuration the default_content feature will work fine.

Let's verify that, let's install a destination site.

Set up a destination site and import the content

$ cd ~/public_html/
$ ./create_test_site.sh drupal_test_dest user_test_dest pass_test_dest openoutreach_dest "Destination site"
$ cd ~/public_html/openoutreach_dest
$ drush dl --dev ctools deploy entity entity_dependency features uuid
$ drush en deploy entity entity_dependency features uuid
$ drush cc all

Install the exported feature and enable it:

$ cp default_content-7.x-0.1.tar ~/public_html/openoutreach_dest/sites/all/modules
$ cd ~/public_html/openoutreach_dest/sites/all/modules
$ tar xvf default_content-7.x-0.1.tar
$ cd ~/public_html/openoutreach_dest/
$ drush en default_content
$ drush cc all

Enjoy the imported content at http://localhost/~username/openoutreach_dest.

Final words

I know that a push deployment plan can be used to exchange content between two actual sites, but remember that I aim to import the content from code when rebuilding a site from scratch, that's why I exported the content to a “feature module”; in my use case, the destination site in this article can easily be seen as a future incarnation of the source site itself.

Someone may also wonder if it is right at all to export content as code; well, in my case I really see this “default content” as configuration so having it stored as PHP code in a feature module makes totally sense to me.

Jan 03 2012
Jan 03

Tips for Acquia Hosting Development

Posted on: Tuesday, January 3rd 2012 by Brandon Tate

Here at Appnovation, we frequently use the Acquia hosting platform for our clients. The Dev Cloud and Managed Cloud are impressive platforms that fit well for many Drupal sites being built today. I’ve listed some items below that have helped with the overall build quality and ease of use for these platforms.

Utilities - Drush aliases

Anyone who develops with Drupal should know about Drush by now. Acquia has gone ahead and installed Drush and the Drush aliases on your Acquia Hosting account automatically. For example, you can run the command “drush @sitename.stg cc all” from your local computer to clear all the caches within the Drupal site without having to log into the server for it to work! You can find the aliases under Sites > Managed (or Dev) Cloud > Utilities. After downloading the file to your $HOME/.drush/ directory and setting up an SSH key, you're good to go.

Enabling Git

Acquia uses SVN as its primary repository system. However, some of us like to use Git for its enhanced speed over SVN. Not a problem since Acquia supports both. Switching to Git is easy and can be found under Sites > Dev Cloud > Workflow. At the top of the page you’ll find an SVN URL by default with a gear icon located next to it. If you click that icon a drop down will appear and the option to switch to Git will be displayed. Simply click this link and your repository will switch from SVN to Git. For Managed Cloud platforms, you just have to request Git by filing a support ticket through Acquia and they will switch it for you.

Pressflow

Acquia Dev Cloud and Managed Cloud implement Varnish to speed things up. To take advantage of this I recommend you use Pressflow. The installation and setup is the exact same as Drupal and Pressflow is 100% compatible with Drupal core modules. There are some issues with contrib modules, so make sure you check the functionality of these modules before assuming they work. Once Pressflow is installed and setup on the Acquia server, you’ll notice you have a new option under Performance called “external”. This allows Varnish to handle caching instead of Drupal’s stock functionality.

Mobile sites and Varnish

I recently worked on a site that was using Varnish to speed up the performance. The site was also configured to use a different theme when a mobile device was detected. I was using the global variable $custom_theme to switch the theme when a mobile device was found. However, when this solution was implemented with Varnish we noticed that sometimes the mobile site would get served to a desktop browser and vice versa. The problem was that Varnish was caching the page and not hitting the code to determine if the device was mobile or not. To correct this, we needed to switch from using the global $custom_theme variable to using Drupal’s multi-site folder architecture. To do this, you need to add a mobile site folder (m.domainname.com) to the sites directory within Drupal. Then within the settings.php file add the following line.

$conf = array('theme_default' => 'mobile_theme');

This will force the site to use the mobile theme. Next, you’ll have to add the domain to the Acquia Hosting platform which is located under Sites > Managed (or Dev Cloud) > Domains. After that, you’ll have to get in contact with Acquia support so that they can configure Varnish to detect mobile devices and redirect to the correct sites folder.

Memcache setup

Memcache is another technology that speeds up the performance of Drupal. To enable this, you must download the Memcache module from Drupal.org. After this, you can add the following lines into your settings.php file.

if (!empty($conf['acquia_hosting_site_info']) && !empty($conf['memcache_servers'])) {
  $conf['cache_inc'] = './sites/all/modules/contrib/memcache/memcache.inc';
  $conf['memcache_key_prefix'] = 'domainname';
  $conf['memcache_bins'] = array(
    'cache' => 'default',
  );
}

First, I’d like to point out the memcache_key_prefix which must be unique across the different environments such as development to production. This prevents the cache tables from overwriting each other. Next, the memcache_bins key allows you to cache specific cache tables from Drupal. In the example above, I’ve left it to "default" but you could cache specific tables such as views, blocks etc.

Workflow - Lock out the files folder

Acquia has a drag and drop interface that allows the developer to drag the codebase, files and database between development, staging and production environments. This allows you to easily migrate your site between any of the servers. One thing I want to point out is, once your site is on the production server, its a good idea to lock the environment by setting it to Production Mode. This prevents the files directory and database from being overwritten and also allows you to pre-release the site to the client, allowing them to add content while you update the code base. To do this, go to Sites > Managed (or Dev) Cloud > Workflow. There will be a “Prod” section with a gear beside it, clicking that gear will provide a link to switch the site to Production Mode. This can be easily reverted as well by clicking the gear and reverting the site to Pre-Launch mode.

Those are some tips that I’ve discovered over my use of Acquia that have eased the development and deployment of a Drupal site on their hosting platforms. If you have any questions or tips of your own, feel free to comment.

Feb 15 2011
ao2
Feb 15

I've added an IPv6 Greeter block on ao2.it in order to greet the IPv6 users, and to inform the others about the existence of the new protocol.

The code of the Drupal module is in the IPv6 Greeter sandbox, and I applied to create a full project on Drupal.org now that the Drupal migration to git is complete, so to have it properly reviewed and eventually hosted there.

If your site has a tech audience and it is built with Drupal, consider using the module above in order to raise the awareness that, like it or not, we could be needing IPv6 sooner than expected: the last IANA IPv4 Free pool has been allocated on January 31st 2011 to APNIC, while this does not mean automatically that we have run out of Ipv4 addresses for Internet nodes today, we should be prepared.

So deploy IPv6 NOW, and be ready for the World IPv6 Day.

Jan 12 2011
ao2
Jan 12

Added short URL links to ao2.it, you will find one at the end of each node content.

I decided to use the simple approach of nids as unique identifiers, together with Apache URL rewriting as seen in URL Shorteners Must Die.

Apply this patch to Drupal .htaccess to recognize short URLs in the form http://example.com/123:

Redirect URLs in the form
  http://example.com/123
to
  http://example.com/node/123
from here on Drupal will take care of any other URL aliasing.

Signed-off-by: Antonio Ospite <[email protected]>
---
 .htaccess |    3 +++
 1 file changed, 3 insertions(+)

Index: drupal/.htaccess
===================================================================
--- drupal.orig/.htaccess
+++ drupal/.htaccess
@@ -106,6 +106,9 @@
   # uncomment the following line:
   # RewriteBase /
 
+  # Allow short URLs of the form http://example.com/123
+  RewriteRule ^(\d+)$ index.php?q=node/$1 [L,QSA]
+
   # Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d

Then from THEME_preprocess_node() (change THEME to match your actual theme name) in template.php call the function below to set a new variable that can be used in other templates:

/**
 * Add a new shortlink variable
 */
function THEME_preprocess_node_add_shortlink(&$vars) {
  $node = $vars['node'];

  $options = array(
    'language' => '',
    'alias' => TRUE,
    'absolute' => TRUE,
  );
  $shortlink = url($node->nid, $options);

  /* add also the info to the header when viewing a node page */
  if (arg(0) == 'node') {
    drupal_set_html_head('<link rel="shortlink" href="https://ao2.it/en/news/2011/01/13/short-url-links-drupal-6-ao2it/'. $shortlink .'" />');
    drupal_set_header('Link: <' . $shortlink . '>; rel=shortlink');
  }
  
  $options = array(
    'language' => '',
    'attributes' => array(
      'title' => $node->title,
      'rel' => 'shortlink nofollow',
    ),
  );

  $vars['shortlink'] = l($shortlink, $shortlink, $options);
}

The code above adds support for the shortlink relation specification, and takes care to add the nofollow relation to the short duplicate link for the content, which shouldn't hurt.

The new variable for the actual link can be used wherever the short URL link is wanted to show up:

print '<div class="shortlink">'.t('Short link'). ': ' . $shortlink . '</div>';

A problem with this approach could be the multiple redirects performed before actually serving the content:

/[nid]  ->  /node/[nid]  ->  content at Pathauto generated alias

I haven't checked if caching mechanisms at the web server can help with that, anyone?

An alternative, more complete solution, would have been to use the Short URL and Shorten Drupal modules; overkill for my use case.

I still have to find a way to add support for short URLs to AddToAny without patching it.

Oct 16 2010
ao2
Oct 16

I was looking for a way to search raw content (before input filters are applied) in my Drupal blog using regular expressions, à la grep; I googled to see what other people had come up with to solve the same problem and I found an article about Searching the Drupal Database by Regular Expression, which pointed also to the scanner module, however those solutions have both some limitations: ad-hoc Drupal scripting, only MySQL supported, and I didn't want to have a module installed for that anyways; so I tried the Drush way and I found it the most convenient one.

Drush is a good tool to know if you are somewhat into Drupal, with Drush you can do almost anything you do with the Drupal admin UI, only faster and in a scriptable way from a CLI.

The power of Drush is that it can be extended very easily to meet our needs, by writing new commands, a first resource about that is the example command sandwich.drush.inc. Oddly enough a “How to write a new Drush command?” question was not even in the FAQ, but that's fixed now.

Anyhow, I wrote a “grep” Drush command for my issue, you can find it in the dgrep git repository. Here is an example run on my blog to check out where I used the syntaxhighlighter filter:

$ cd .../my_drupal_installation_dir
$ drush grep '/syntaxhighlighter[^}]*/'

Node: 11        Title: Web scraping with PHP and XSL
                URL: blog/2009/07/26/web-scraping-php-and-xsl
                Match: syntaxhighlighter brush:php

Node: 12        Title: Renaming a DOM element with XSL
                URL: blog/2009/08/06/renaming-dom-element-xsl
                Match: syntaxhighlighter brush:php

Node: 13        Title: Translating XML documents with XLIFF
                URL: blog/2009/09/09/translating-xml-documents-xliff
                Match: syntaxhighlighter brush:xml

Node: 16        Title: git-commit with date in the past
                URL: blog/2009/10/30/git-commit-date-past
                Match: syntaxhighlighter brush:bash

Node: 19        Title: Vim buffers: status(line) symbol
                URL: blog/2009/11/12/vim-buffers-statusline-symbol
                Match: syntaxhighlighter brush:plain

Node: 26        Title: Branding patches with git and vim
                URL: blog/2010/01/05/branding-patches-git-and-vim
                Match: syntaxhighlighter brush:bash

Node: 34        Title: On piping in shell scripts and var scoping
                URL: blog/2010/03/26/piping-shell-scripts-and-var-scoping
                Match: syntaxhighlighter brush:shell

Node: 37        Title: Neat compile/run cycle with git and OpenEmbedded
                URL: blog/2010/05/27/neat-compilerun-cycle-git-and-openembedded
                Match: syntaxhighlighter brush:bash

Node: 43        Title: AO2 runs into autorun.inf
                URL: blog/2010/09/19/ao2-runs-autoruninf
                Match: syntaxhighlighter class="brush: bash"

Node: 46        Title: List header files first in a patch with git
                URL: blog/2010/10/13/list-header-files-first-patch-git
                Match: syntaxhighlighter class="brush: cpp;" title="dinner.h"

TODO: grepping blocks is not supported yet

How cool is that?

The current dgrep code is just a prototype but I'd like it to become useful for the whole Drupal community. So if you wanna help: go try it, comment about it, fork it, and report back with any feedback or code change you might have, either here or in the relative issue on drupal.org. Thanks!

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web