Copyright © 2004–2010 OpenSourcery, LLC. This work is licensed under a Creative Commons Attribution 3.0 United States License.
Today OpenSourcery announces the release of Donor Rally, an open source Drupal distribution that nonprofit organizations can use to raise money on the web. This is a developer release, and Drupal geeks can begin the tire-kicking process by downloading the project's source code on GitHub now.
This project has allowed OpenSourcery another chance to follow through on one of our central goals as a company: to share open source software developed for one nonprofit organization with the rest of the nonprofit community. Today, on the day of Donor Rally's birth as a public open source project, I'd like to take a moment a moment to relate the story about how it came to be.
In early 2009 we were contacted by the San Francisco Food Bank to discuss the possibility of attempting something truly radical: using Drupal to move a mission-critical fundraising campaign completely to the web.
The Food From the Bar campaign website was launched in February of 2010. It allowed the San Francisco Food Bank to utilize their social networks, both physical and virtual, to spread the word about their mission. And by June of this year, it had collected over $300,000.00 in web-based donations.
OpenSourcery licenses all of our client projects under the terms of the GPL, and it wasn't long before we started contemplating how this software could be used to benefit other organizations. Then a personal connection at one of our favorite organizations, 826 Seattle, gave us our first chance to spread the Donor Rally love. (Huge thanks to Sarah B., who was instrumental in this leg of the project.) 826 Seattle is a division of a parent organization co-founded by Dave Eggers to give underprivileged youths access to creative writing programs of the sort that had been previously reserved for only the most privileged private academies.
826 Seattle was planning an ambitious, grassroots fundraising campaign called Dance Your Cash Off that invited participants to raise money for the organization on the condition that they would enter a dance marathon hosted by 826. This proved to be a perfect opportunity to re-tool the codebase originally developed for the San Francisco Food Bank to help 826 Seattle bring their efforts to the social web. Because we developed the original codebase using Features, abstracting out functionality unique to the food bank (such as food donation) was a nearly trivial task. After less than 20 hours of labor, we launched DanceYourCashOff.org.
Staff members and fans of 826 Seattle were then able to use the website to raise $17,000, more than 70% of their original fundraising goal. And thanks to Drupal's administration capabilities, they spent only a few hours of staff time to co-ordinate the entire campaign.

Since then, employees of OpenSourcery have spent every Thursday afternoon sitting around a table out in the sun over a company-subsidized pitcher (or 2) of beer, working together to improve the Donor Rally codebase. Which brings us to today's developer release. Donor Rally has now been packaged into a free, general-purpose application to help any nonprofit organize a social fundraising campaign of their own. The theme is a subtheme of Zen, and hasn't yet been given a polish coat. But this should be a good starting place for a developer to use to help out his or her favorite nonprofit. To learn more, visit the Donor Rally project page on OpenSourcery.
Tagged as: Drupal, Drupal distribution, nonprofit
I have just returned from DrupalCon San Francisco 2010, the largest DrupalCon ever. With over 3000 attending, and $72,000 worth of coffee consumed, it was a very lively event. Thanks to the awesome work of those organizing, nearly all of the sessions now have high quality video available on the DrupalCon site, and on Archive.org. Below are the sessions that really left an impression on me regarding the future direction of Drupal.
While there is no video for this as of this writing, the highlight here was the sudo drush make-me-a-sandwich moment (as well as the Drush core-cli command).

While we've been using context on most projects for quite some time, the work presented here around the spaces presets has me itching to try integrating them into some upcoming projects.
The page rendering system in Drupal 7 waits much later in the process to transform structured data into the relevant output format (which is typically HTML). Practically speaking, what this allows for is hook_page_alter, which has access to the contents of the entire page, in a structured array. Two highlights:
This talk wasn't specific to Drupal (yet anyway), but rather, provides a sort of roadmap to the future of Drupal and the social web. By combining 4 rather new protocols (PubSubHubbub, WebFinger, ActivityStreams and Salmon), Brett Slatkin of Google walks through the potential for realtime feeds being used to contect people like never before.
It would be very powerful if any Drupal site out there were capable of sharing, in real time, at the level Brett outlines in this talk. The Feeds module is already capable of consuming PubSubHubbub, and support for ActivityStreams have a little momentum. Salmon and WebFinger, as well as publishing to hubs for PubSubHubbub are the pieces that need to be filled in.
At Dries' keynote, he showed a best case scenario (June 2010), a worst case scenario (October 2010), and an ideal scenario (lock the 3000 attendees in until it was released at the conference) for the Drupal 7 release.
While we already missed the ideal scenario, the progress made on critical bugs at the conference has the community working at a velocity that should come in closer to the best case scenario. Over the course of the week, thanks to the awesome gatherings at the chx coder lounge, the number of critical bugs dropped from 114 to 94 as of this writing.
Tagged as: Drupal, Drupalcon, DrupalCon San Francisco
We've just published a write-up of our work for Mercy Corps, where we enabled hundreds of youth organizers worldwide to join together in a global community, including multilingual support in Drupal. Read all about it here:
http://www.opensourcery.com/portfolio/projects/mercy-corps-globalcitizen...
Tagged as: Drupal, global community forums, Mercy corps, multi-lingual, multilingual, right-to-left, RTL
The context module provides great flexibility in terms of the available ways to set a context, but it's also remarkably straightforward to define custom conditions.
In order to set arbitrary contexts, hook_context_conditions() is implemented to define values and such. This example will use the value of a CCK field, called field_foo:
/** * Implementation of hook_context_conditions(). */ function mymodule_context_conditions() { $items = array(); // The key used here will be used below when setting the context. $items['mymodule_foo'] = array( '#title' => t('Field Foo Value'), '#description' => t('Set this when field_foo has a certain value.'), '#options' => array( // Note, these are hardcoded here for simplicity, but could // easily use something like CCK's content_allowed_values() api // function for more dynamic population. 'value1' => t('Label 1'), 'value2' => t('Label 2'), ), '#type' => 'checkboxes', ); return $items; }
The only other step is to actually fire the code that sets the context somewhere. In the example of setting a context based on the value of a CCK field, this can be done in hook_nodeapi(). But something like hook_init() can also be used.
function mymodule_nodeapi(&$node, $op, $teaser, $page) { if (isset($node->field_foo[0]['value']) && $op == 'view' && $page && menu_get_object() === $node) { // Use the same key here as used to define the context condition // above. Note, this logic would need some re-working if // field_foo allowed multiple values. context_set_by_condition('mymodule_foo', check_plain($node->field_foo[0]['value'])); } }
That's it. Contexts can now be added through the UI or through code that react to the value of field_foo.
The workflow module allows a piece of content to be transitioned through arbitrary states. It is most commonly used (as I've seen it) as a replacement to the core node workflow of published/unpublished. Recently I was working on a pair of sites that required a very simple workflow of draft/published (if you're wondering why core couldn't be used in this case, it has to do with the very high level of permissions required to toggle the published/unpublished bit). The sites also made extensive use of node reference, views and context for positioning various parts of the node. Not having visual indicators within those views for the end user to determine which nodes were in a draft state, and which ones were published quickly became an obvious usability issue.
The first step in the improvements applied was to add the workflow state field to every view in question.

However, as packaged with workflow, it doesn't provide a very nice output, and only nodes in the Draft state needed a visual indicator.
Using the following preprocess function, the fields for undesired workflow states are removed, and a key CSS class is added (in this case, Published content didn't need to be highlighted in such a manner).
/** * Preprocess function for template_preprocess_views_view_fields(). * * - Adds workflow class for rows in the 'Draft' state, while * removing results in 'Published state'. */ function os_custom_preprocess_views_view_fields(&$vars) { foreach ($vars['fields'] as $name => &$field) { if ($name == 'sid' && $field->handler->table == 'workflow_node') { // Get complete workflow state. $state = workflow_get_state($field->raw); if ($state['state'] != t('Draft')) { // Hide workflow if not in draft mode. unset($vars['fields'][$name]); } else { // Add workflow-{state} class. $field->class .= ' workflow-' . strtolower($state['state']); // Replace default 'Worfklow name: workflow state' formatting with // only the workflow state. $field->content = $state['state']; } } } }
Then, by borrowing some CSS that has been hanging around in the Zen theme for the core workflow, the content in draft state is easily brought to the attention of those working on the site:
The same is then done for nodes by a different preprocess function,
/** * Preprocess function for template_preprocess_node(). */ function os_custom_preprocess_node(&$vars) { $state = workflow_get_state($vars['node']->_workflow); if ($state['state'] == t('Draft')) { $workflow_class = 'node-workflow-' . strtolower($state['state']); // Prepend content with workflow state information. $vars['content'] = '<div class="' . $workflow_class . '">' . $state['state'] . '</div>' . "\n\n" . $vars['content']; } }
and and using the aforementioned, and slightly-modified, Zen CSS:
.node-workflow-draft, .workflow-draft, .node-unpublished div.unpublished, /* The word "Unpublished" displayed beneath the content. */ .comment-unpublished div.unpublished { height: 0; overflow: visible; color: #f77; font-size: 75px; line-height: 1; font-family: Impact, "Arial Narrow", Helvetica, sans-serif; font-weight: bold; text-transform: uppercase; text-align: center; word-wrap: break-word; /* A very nice CSS3 property */ } .workflow-draft { font-size: 42px; /* Smaller font for workflow display within views. */ }
the result is again obvious to people staging content:

hook_cron() is widely implemented in the Drupal ecosystem – but what if your modules have varying frequency needs? For example, perhaps you'd like your aggregator feeds to update every fifteen minutes, and notifications should fire every minute to keep emails timely. But system_cron() should run as infrequently as practicable, because it calls cache_clear_all()!
Here is a small cron.php replacement that accomplishes this task. Just plunk the file in your drupal root directory. (You could move it to your sites folder if you modified the include path.) Different cron jobs for each module or set of modules can now be configured.
<?php // $Id$ /** * @file * Handles incoming requests to fire off regularly-scheduled tasks (cron jobs). * * The file executes cron hooks selectively, instead of all-or-nothing. * This allows cron jobs to be configured with variable frequency. * Example usage: * * * * * * curl example.com/cron_selective.php?modules=notifications * *∕15 * * * * curl example.com/cron_selective.php?modules=aggregator * 0 0 * * * curl example.com/cron_selective.php?modules=system,dblog * */ include_once './includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); $modules = array_intersect(module_list(), explode(',', $_GET['modules'])); drupal_cron_run_selective($modules); /** * Executes a cron run when called * @return * Returns TRUE if ran successfully */ function drupal_cron_run_selective($modules) { // If not in 'safe mode', increase the maximum execution time: if (!ini_get('safe_mode')) { set_time_limit(240); } // Fetch the cron semaphore $semaphore = variable_get('cron_semaphore', FALSE); if ($semaphore) { if (time() - $semaphore > 3600) { // Either cron has been running for more than an hour or the semaphore // was not reset due to a database error. watchdog('cron', 'Cron has been running for more than an hour and is most likely stuck.', array(), WATCHDOG_ERROR); // Release cron semaphore variable_del('cron_semaphore'); } else { // Cron is still running normally. watchdog('cron', 'Attempting to re-run cron while it is already running.', array(), WATCHDOG_WARNING); } } else { // Register shutdown callback register_shutdown_function('drupal_cron_cleanup'); // Lock cron semaphore variable_set('cron_semaphore', time()); // Iterate through the modules calling their cron handlers (if any): foreach ($modules as $module) { module_invoke($module, 'cron'); watchdog('cron', 'Selective cron run completed for %module.', array('%module' => $module), WATCHDOG_NOTICE); } // Release cron semaphore variable_del('cron_semaphore'); } }
The Clean Economy Network (CEN) is the national advocacy association for the cleantech and green business community. The Network emerged from the 2008 presidential election with strong ties to the CleanTech and Green Business for Obama organizations. OpenSourcery was very excited to work with an organization whose guiding principle is that "economic growth, quality jobs, international competitiveness, environmental sustainability, and energy independence are not mutually exclusive, but rather are all vital elements of a healthy, dynamic economy."
The Network is a broad, nonpartisan collection of professionals, entrepreneurs, investors, workers joined by like-minded professionals and thinkers from across the economy and across the political spectrum. We work at the intersection of politics, policy and business to develop and advocate for policies and programs which meet our Guiding Principles, catalyze clean development and create green jobs.
Having emerged from the 2008 presidential election with a growing number of supporters, the Network needed a Web application that could communicate with existing supporters, deliver a strong message, and allow site administrators to easily manage content.
The development of the Clean Economy Network's Drupal + CiviCRM Web application presented a few technical challenges. The first challenge was to provide a platform whereby the Network could quickly welcome the 7,000 existing members of CleanTech and Green Business for Obama. The Network needed a donor management system that could capture their information in a database they could use to intelligently organize members around future actions. Since one of the Network's primary goals is to "to advance policies that will promote a rapid transition to a cleaner economy," the ability to inform and promote activities among its member base is paramount.
The CEN site had to be a platform that made communicating organizational information easy. While their mission remains the same from week to week, the content itself is always changing. Multiple staff and volunteer users need the ability to manage content, whether it be to edit page content, write a newsletter, or upload a new video.
The Clean Economy Network project is another example of OpenSourcery's Agile development process. Our project managers worked with the CEN's stakeholders to prioritize needs, iterate, and assess the project at every milestone. When pressing needs arose, as they do with time-sensitive projects, OpenSourcery was able to shift resources and address emerging challenges.
We also worked with their designers to customize a Drupal theme to fit their branding and messaging. OpenSourcery's user experience team coordinated with the CEN's themer to enhance the existing theme to increase its functionality and attractiveness. The result is an easy-to-navigate Web application that allows users to easily find the content they're looking for.
The CEN now manages the site and has seen their membership grow significantly. OpenSourcery looks forward to partnering with the Clean Economy Network as it continues to grow and increase its offerings.
Tagged as: CiviCRM, custom drupal module, custom theme development, Drupal
Portland's Drupal users group has announced the schedule for its June meetup, and 'tis a thing of beauty. Lightning rounds bolstered by the July Drupal challenge, with a little Modules 101 for good measure.
It's been a while since the Portland group organized Lightning Rounds, so the time draws nigh. They're fast, informative, and fun. Who's lined up so far, you ask?
The group will vote on a task or challenge that can be solved by Drupal in any number of ways. The July meeting will then focus on solutions people come up with. More information here.
Iif there's time left, and anybody wants to talk for a few minutes about a module no Drupal user should be without, we'll do this too.
We meet at the OpenSourcery office at 1636 NW Lovejoy St in Portland, Oregon. NOTE Please be aware that the developers at OpenSourcery will be working right up to event time. We ask that you arrive no earlier than 5:50pm. Thank you!
After the presentation finishes we'll walk over to the Lucky Lab for food and drink.
As always, the event is free and open to the public. We hope to see you here.
Tagged as: Drupal, lightning rounds, user group meetup
A while ago I wrote about a method we'd been using internally here at OpenSourcery for testing existing Drupal configurations. There are currently a few issues in the works that would get this functionality into core-SimpleTest:
In the meantime, however, since this functionality has immediate benefits to making more robust Drupal sites, I've decided to release the module we're using internally until this is part of core-SimpleTest, and gets back-ported to Drupal 6.x. I've placed the module on GitHub rather than on Drupal.org so as not to clog things up with placeholder modules. I've also attached a tar-ball to this post for those without Git.
Update: This module has also been released on Drupal.org in order to allow people to track updates.
To use the module, it must be enabled, and then included at the top of any test file that extend the class:
// Include SimpleTest Clone module_load_include('test', 'simpletest_clone');
class CustomTestCase extends SimpleTestCloneTestCase { ... }
Occasionally, on a given site or set of tests, it may not be desirable to clone every table because this can make tests run for a very long time. Because of this, there is a method in place for excluding tables from being cloned:
/** * When testing data-intensive sites, if the tests will still run correctly, * tables can be excluded here. The structure will still be cloned, but the * data will not be copied over. */ function __construct($testId = NULL) { parent::__construct($testId); $this->excludeTables = array( // List of tables to exclude goes here. 'example_table_foo', 'example_table_bar', ); }
Tagged as: Drupal, SimpleTest, Test-driven development
Like many Drupal developers, at any particular time I'm running dozens of Apache virtual hosts on my workstation. This allows access to each project under a friendly url. We frequently create sites that employ SSL, which creates a wrinkle: officially, it's not possible to used name-based virtual hosting with SSL.
Simply disabling the SSL features on a development copy isn't the best option, because we need to test this functionality as we're developing.
It turns out that you can use SSL and vhosts together, sort of. Name-based virtual hosts can be configured on port 443 just like any other port. Apache won't stop you, though it will throw a stern warning when it starts up:
Tagged as: Apache, Drupal, SSL, Virtual Hosts
The Linux Foundation serves a worldwide community of developers and users. Their stated mission is to Promote, Protect, and Standardize the Linux ecosystem by providing unified resources and services needed for open source to successfully compete with closed platforms. More than ever, LinuxFoundation.org helps further that mission with web-based tools and vital user-generated content.
Story
The Linux Foundation and OpenSourcery began working together in the summer of 2008, with the goal of transforming the Linux Foundation's corporate site to reflect the vibrant community it supports. Their existing site was informative and, in some ways, well loved. Long-time users knew how to access the information they needed and were familiar with the site's architecture. But in the final analysis their site architecture was not tenable. The Foundation had accumulated a number of web properties, including the Linux OpenPrinting site and a number of Programs sub-domains, which had been cobbled together to serve immediate needs. Moving forward, the combined properties needed to coalesce under a single, forward-thinking architecture. Enter OpenSourcery.
Developing a new Linux Foundation site presented several challenges, which can largely be grouped into two buckets: 1) unifying deep and diverse content into a well-architected site and 2) developing a clean interface that doesn't overwhelm visitors with options.
Solving the primary challenge required open communication between OpenSourcery and the Linux Foundation. We had to ask the right questions, consider the variety of use cases, and design the site accordingly. The discovery process is well suited to our Agile development process, which you can read about in more detail below.
Perhaps the most creative solutions employed during the development have to do with the second challenge: Linux Foundation's user interface. We realized that visitors could easily get overwhelmed by an overabundance of tabs and conflicting images. On the other hand, we wanted to avoid Flash and non-accessible JavaScript so the site could remain accessible and easily indexed by search engines. Jonathan Hedstrom solved both of these problems with a combination of contributed and custom modules, details of which can be found below.
The result is an attractive site that makes it easy for each user to quickly access what she needs, without sacrificing the Linux Foundation's goals of completeness and accessibility. OpenSourcery is proud to have collaborated with such a talented team, and we look forward to supporting the Linux Foundation's mission in the future.
Development Process
OpenSourcery had assembled a Linux Foundation team during the development of a previous project: the Linux Foundation Video Site. From the start of their corporate site refactor, we were familiar with the Linux Foundation's project team and goals.
We employed our Agile development process from the project's beginning. We maintained close contact throughout, iterated in short bursts, and frequently pushed code so the Linux Foundation would know where their project stood at all times. Our process also allowed them to guide development by prioritizing tasks, which kept the complex project on budget and on time.
Technical Details
Tagged as: custom theme development, Drupal, Drupal 6, panels, Views
I have been working on a Drupal project here at OpenSourcery that involves a dynamic form which updates via ajax whenever a radio button or checkbox is modified. Drupal has built-in ajax/ahah, making this task much simpler. It lets you specify which type of event you want to trigger the ajax, as well as many other options.
For this specifically the requirement was that it occur with the 'OnChange' event. This works great in firefox, but not so great in IE. IE does not register an 'OnChange' event until the mouse is clicked somewhere else on the page after having changed your radio/checkbox selection. This is of course not the desired behavior.
Drupal offers other choices for events that trigger the ajax. The next obvious candidate was 'click'. Click provided consistant behavior between IE and FF. When you click the new button the form would update. However, it resulted in some undesirable behavior in both browsers. The radio button selection would not update. The correct option was sent to post for ajax, but the actual radio button selection did not change.
At this point it became obvious that I was going to need to hand-code some javascript to work around this issue. At first I attempted to write javascript that would update the radio selection after the ajax fired. This was an exercise in futility. I encountered many difficulties, most of which were probably due to inexperience.
Before pounding my head too long on my first attempted solution, a better solution reached my brain. Instead of using 'Click' and trying to re-write default radio and checkbox functionality, I would use 'OnChange' and work around IE's problem. The solution was simple, if the browser is IE, add an 'OnClick' event to all the ajax elements that triggers the 'OnChange' event.
This solution worked perfectly, and was very easy to write, even for someone with little js experience. My first time through I failed to follow proper Drupal convention, and as such I had to implement my own logic to update all the element triggers whenever ajax was used. Fortunately Jonathan reviewed my JS and pointed out the proper way to achieve this (see note 2).
Here is the final version of the javascript
Drupal.behaviors.nexusForm = function (context) { if (jQuery.browser.msie) { trig_bind() } //Hide the botton we only want to see if the browser does not support js $("#edit-continue").hide() } //IE waits until another event to send the 'change' events on radios and checkboxes //This bind a trigger for those events on click. function trig_bind() { //unbind old events $("input[type='checkbox']").unbind( 'click' ) $("input[type='radio']").unbind( 'click' ) //bind the events $("input[type='checkbox']").bind( 'click', function() { $(this).trigger( 'change' ) }) $("input[type='radio']").bind( 'click', function() { $(this).trigger( 'change' ) }) }
Notes:
Drupal lovers rejoice! This month's Meetup is a Drupal double feature. "You mean in two hours I can learn about an ambitious multi-lingual, multi-domain Drupal 6 project /AND/ soak up the best of DrupalCon DC?" I wouldn't lie to you, would I? No. I would not.
Richard and Katrin from One Economy will take a deep look at The Beehive, an ambitious multi-domain, multi-lingual Drupal 6 project expertly knitted together by Katrin from a host of contributed and custom modules and some very clever theming. Katrin will answer the complicated technical questions while Richard will cover the softer aspects of drupal project management and interject snarky asides regarding ‘the drupal way’.
Jonathan Hedstrom from OpenSourcery will quickly highlight some of the things he's super excited about from DrupalCon DC (including Reusable Features in Drupal and Solr Search), then open it up for other attendees to do the same, facilitating general discussion and questions. We'd love to have DrupalCon attendees post links to their favorite sessions at the user group node so that anyone inclined can watch them before the discussion has the chance.
As always, the Meetup is free and open to the public, so please bring people who are interested in joining the community. NOTE: Please be aware that the developers at OpenSourcery will be working right up to event time. We ask that you arrive between 5:50pm and 6:00pm. Thank you!
OpenSourcery is located at 1636 NW Lovejoy St. between 16th and 17th Streets. We encourage the use of public transportation and there's plenty of space for your bike. This week we're heading to the Lucky Lab at 1945 NW Quimby for after-meeting food and beer.
See you here.
I am writing an application where I have a block whose data is coming from a 3rd-party service. Since querying that service can take some time, I am caching the data locally, so pages load very quickly. However, in the interest of keeping the data more up-to-date than the hourly updates that happen during cron runs, I had the idea to have the client browser periodically poll for updated data. Fortunately javascript (and Drupal's jQuery implementation) makes it fairly easy to set up this periodic polling from the client side.
Tagged as: Drupal, Drupal 6, javascript, jQuery

1400 Drupalers on the stairs - photo by Chrys
Having been back from Drupalcon DC for over a week now, I've had a chance to distill a few of my favorite sessions. Below is a list of my favorites, with video and links to more videos. Of course, all the videos are available on Archive.org, thanks to the wonderful work done by the videographers during the conference who worked tirelessly to capture 98 hours (and counting) of footage.
James Walker (walkah) promised to take a good, hard look at everything that's wrong with Drupal. Of course all this was a little hard to take at 9:00am on a Friday, but this session nailed some very important points about the drupal way and why it isn't always the best way.
All videos for this presentation available on Archive.org
The good folks at Development Seed have been developing the idea of Context and Spaces for some time. One very nice thing that falls out of all that work is a way to programatically package and reuse feature sets in Drupal. The session covered the fairly basic idea of a blog, but the potential for this idea is huge, and will have lasting effects on the way we develop Drupal applications.
All videos for this presentation available on Archive.org
You may have noticed that search works again on Drupal.org. Thanks to Apache Solr, and Acquia's new search service, any Drupal site can quickly have functional search that doesn't need to be hidden away in the footer, or camaflouged into the theme so nobody actually uses it.
All videos for this presentation available on Archive.org
The semantic web is already here. The W3C made RDFa an XHTML recommendation back in October. Any Drupal site can now be made into a semantic document, and with Drupal 7, this will be even easier. It's a fascinating and down-to-earth tour of the present and future of the semantic web by Boris Mann.
No embedded video available, but all videos for this presentation available on Archive.org
Tagged as: Drupal, Drupalcon DC
I attended several sessions at Drupalcon on performance and scalability. One common thread was the need to offload static files to dedicated servers or a content delivery network (CDN). The use of a CDN is also part of the well-known YSlow test for measuring front-end performance. With CDN providers getting cheaper by the day, content delivery is not just for big media companies anymore! A bit more explanation is required to understand why this is complicated in Drupal, and what's being done about it. As a bonus — I'll share a trick for getting a useful chunk of your files on a CDN in less than 3 minutes.
Tagged as: CDN, content delivery, Drupal, Drupalcon, performance
Drupal's core contact module allows users of a site to contact one another via email. Unfortunately, it also reveals the sender's email address. Normally, this is seen as fine behavior because the only person's email address that is at stake is the one taking the action. However, for a recent site, this violated the site's stated COPPA compliance, so we needed to alter the From and Reply-To headers sent with the email. As it turns out, this is quite an easy thing to do thanks to hook_mail_alter().
/** * Implementation of hook_mail_alter(). */ function somemodulename_mail_alter(&$message) { if ($message['id'] == 'contact_user_mail') { // Set 'From' address to a no-reply rather than leaking student's email address. $mail = 'NO-REPLY@example.com'; $message['from'] = $mail; foreach (array('Reply-To', 'From') as $header) { $message['headers'][$header] = $mail; } } }
The Open Source Bridge is an all-volunteer, all-awesome conference that will take place in Portland, Oregon this summer, June 17-19 at the Convention Center. When OSCON fled south, did Portland cry itself to sleep? No. It organized across languages, across disciplines, and on both sides of the mighty Willamette to stage an even more impressive event.
But the success of the conference relies on real people presenting real content. That's where OpenSourcery and other development shops come in. That's right, it's time to submit proposals. We're encouraging our developers, project managers, systems administrators, and business developers to do so.
A few words about why the Open Source Bridge exists, taken from their website:
"Our primary objective will be to explore what it means to be a responsible Open Source citizen.
"Our conference structure is language-agnostic by design, in hopes of facilitating broader community growth by focusing on Open Source development as a discipline–divorcing the techniques of development from the language used for that development. In so doing, the conference will encourage and foster cross-pollination and widespread knowledge sharing, regardless of each developer’s chosen programming language."
That sounds like the kind of activity Drupal developers should participate in. Please feel free to contact thomas@opensourcery.com if you have further questions about the event or if you would like to volunteer your time as an OSB advocate. We're looking for developers across the country (world?) to visit our fair city during the most beautiful time of year. Come June you'll see why they call us the Rose City.
Thank you for reading.
Tagged as: conference, Drupal, events, open source events, portland events
First, if you aren't at Druaplcon this year, recordings of most (all?) off the sessions are available online! I've even bookmarked several that I couldn't attend, but want to watch later.
Here are some highlights:
Tagged as: Drupal, Drupalcon, fake kittens, performance, pifr, Test-driven development
The 2nd day is nearing an end here at Drupalcon DC, and it's been amazing, as was expected. So far, there have been several very cool sessions, and even impromptu demos of up and coming modules.
While attending the Future of Files and Media in Drupal 7 presentation by Drewish and reviewing the FilesApi Wishlist for D7, I'm going to take part in attempting to get the concept of a Filefield module into core for Drupal 7. This would go a long ways towards simplifying the job contrib module authors have when they want to deal with media (although, even without this, D7 already looks to be drastically better given that hook_file_* patch was committed some time ago). There are of course other critical improvements in that list, so ideally, many people will pick up file handling improvement efforts during the upcoming code sprint.
I have to say, after banging my head against various install profiles and update scripts, the ideas presented in A Paradigm for Reusable Drupal Features was a breath of fresh air. The context and spaces modules have come a very long way since Szeged.
I missed this presentation, due to an unfortunate name of the presentation, but I caught up with Irakli and chatted about this exciting new integration of the powerful Views module with the idea of charts and graphs as display types. The key modules (although still in heavy development) will be invaluable for the upcoming Solar4rSchools overhaul:
Finally, I got a very cool preview of an up-and-coming grid builder module by Roger López. The idea is that a user can drag out, and re-arrange regions in a dynamic user-interface. Once they have a nice potential layout for a page, the module will generate the necessary page.tpl.php file, and corresponding .info files to have a theme based on the dynamically created layout. This is very exciting stuff.
That's all I have time for now, although I'll try provide at least a few more updates as the sessions proceed.
Tagged as: Drupal, Drupalcon DC