Copyright © 2004–2010 OpenSourcery, LLC. This work is licensed under a Creative Commons Attribution 3.0 United States License.
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."
To understand the work behind the Clean Economy Network's website, it's important to understand their mission. As stated on their About Us page, "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
The session I was most excited to see at this conference happened to be on the very first day, "Training: Boosting our raw capacity to provide Drupal training". It turns out, as OpenSourcery Training and Quality Assurance, I was drawn to pow wow with the presenters after we ran over time.
Barry Madore, Sean Effel, Lee Hunter, and Alex Urevick-Ackelsberg each gave a short talk, followed by panel Q&A, around the different styles of training they employ and their varied methods for improving the trainings through feedback. The training perspectives varied from speakers dealing with training drupal users every single day, to training a drupal development and sales team in how to work well with the drupal community. I will focus more here on the end-user.
One of the more potentially obvious take-aways from the talk was something I've seen folks miss the mark on: know your audience. When we start building tools to be used to understand the product the end-user has, we can lose sight of the user's goals. What is most important to the user of the software is nearly never the shiny piece of code, or a loving explanation of why it is fantastic. The exact function of the code or application may also be missing the mark of what a user really wants to know. They want to know how to use the system everyday. Your users really don't want to know how they can hack the code, but how they can interface with it without fear.
That which we are thinking about as software devs has already been invented and re-invented by teachers. The art is assessing knowledge, and then creating education and curriculum from that assessment. What we need is practice as educators, and the same education principles apply to drupal as apply to any other classroom. How much do they know? What else do they need to know? What might need to be un-learned? Are there different learners in the same group? Those questions get you close to having an assessment on which to found your curriculum.
Again, looking to the educators on curriculum, we should start by covering the concepts in the best logical order. That might not be in numerical sequence, but probably by associated concepts. One of the best parts of creating a plan like this is the exposition of concepts. This can increase confidence in knowing the right answer before a user would need to push a button. The last piece is, of course, cementing the lesson. Repetition is excellent to get you used to a new pattern of thought. Having 2 shorter trainings with time between is more effective than having a single day long training.
My hope is to bring fearlessness to software users through education. With the right tools, the hardest problems look easy. What is the worst we could do, break it? That'd be sweet!
Tagged as: Documentation, Drupal, Drupalcon, Drupalcon DC, training
This week, the Drupal team is out in Washington, DC for DrupalCon - an unconference for Drupal lovers getting together to share knowledge, exciting developments in the field, better practices, and actually meet face to face.
We're just back from the pre-parties and discussing the session topics, expect posts from me, Jonathan, Dylan and Stacy about what we're excited about, people we've met and good discussion.
Tagged as: conferences, Drupal, Drupalcon
Jonathan, Amye, Dylan, and Stacy are en route to DC as I write this, speeding toward the goodness that is DrupalCon DC. Immediately upon their return, OpenSourcery will host the March Drupal Meetup in order to squeeze every bit of smarts from the collective, exhausted, Drupal brains of PDX.
The Meetup begins with Tony Rasmussen, who will continue a discussion from the January meeting re. when to use Contemplate module vs. the Theme Layer.
We'll follow Tony's discussion with DrupalCon roundup, contemplation, and embellishment. AND IF YOU HAVE NOT HEARD, March is drewish's last Portland Drupal Meetup. That is, until he realizes that Portland is the greatest city on earth and that NYC, while it never sleeps, just doesn't stack up. So please join us and bid drewish a hearty adieu. Travel well, sir!
As always, we'll save plenty of time for questions and concerns. Bring your ideas and your thirst, because immediately following questions and answers we'll head to the Bridgeport Brew Pub for thoughtful libations. The Meetup is free and open to the public. OpenSourcery is located at 1636 NW Lovejoy between 16th and 17th streets. Contact thomas@opensourcery.com with questions.
Date: Wednesday, March 11
Time: 6pm - 8pm
Please note that OpenSourcery's developers work right up to meeting time, so please take care to arrive as close to 6pm as possible (5:55, perhaps?). We recommend public transportation and self propulsion; if you arrive a few minutes early, we can recommend a solid local bar where 30 minutes are easily passed.
Thank you for reading. We'll see you on March 11.
Tagged as: community events, Drupal, portland events