Blog
  • Drupal YouTube Module on the YouTube Developer Blog

    This summer Brad released an API module that provides a toolkit to help Drupal module developers interact with YouTube. Yesterday there was a post about the module by Jochen Hartmann, of the YouTube APIs and Tools Team, on the YouTube Developer API Blog.

    The YouTube API module was originally created to dynamically publish uploaded video from iCitzenForum.com to YouTube. We’re glad to see it getting more use!

    Read Jochen’s post here.

  • Fresh Paint

    The Aten Design Group website has a new look. Well, maybe not an altogether new look, but a revised look. We’ve modified the typography, adjusted the layout, and made some color changes. The blog sports a reversed color scheme, with syntax highlighting for code examples.

    The copy has changed, too. We’ve added projects to the portfolio, added text about our technical proficiencies and our iterative process, and added a couple employee profiles.

    And then there is the technical platform - you guessed it, that changed also. We moved from a hybrid combination of custom PHP plus WordPress to a shiny clean installation of Drupal. The new framework provides a more robust environment for potential changes in the future, offers site-wide categorization, and provides better user management for delegating content development internally. It’s easier to publish content, faster.

    So maybe “Fresh Paint” is a bit of an understatement — it’s more like “New Foundation, New Walls, New Furniture and Fresh Paint.” But what a mouthful.

  • Drupalcamp Colorado a Success!

    This past weekend we had the pleasure of being platinum sponsors at DrupalCamp Colorado. I think we're all in agreement that the event was a great success, and getting to spend the weekend getting to know the rest of Colorado's active Drupal community better was a great experience. Justin and Eric gave a presentation entitled "More Miles, Less Gas" which covered how we're using Drupal within all stages of our design and development process. In addition, I had the enjoyment of presenting on some of my recent work on the YouTube API module.

    We're excited to have been involved in this year's event, which grew over 300% when compared to last year's event, and are already looking forward to helping make next year's event even bigger and better!

    For those of you interested in photos from the event, you can check them out on flickr.

  • YouTube API Module in the Wild

    Earlier this week I was able to release the first supported version of the YouTube API module I've been working on for the last couple months. Initially I thought I'd be releasing the beta in early July, but instead decided to hold out until I could find some time to work on feedapi integration.

    An overview of features in this initial release:

    • Video Management
      • Creating (uploading)
      • Editing
      • Deleting
    • FeedAPI Integration (think views...)
    • Video Feeds
    • Commenting - reading and submitting.
    • Other
      • Authentication
      • Video Rating
      • Favorites

    ..and a handful of others. Besides the feedapi integration offered by the module, all of the other features require a bit of coding on the end users side. My goal is not to make integration decisions for end users, but to give them all the features necessary to be able to take full advantage of the YouTube public API in just a few lines of code.

    Better documentation is on the way™, but for now you can get started by checking out the examples on the modules project page, taking a look at the modules function reference, and getting familiar with the YouTube API Developer's Guide wouldn't be a bad idea either.

    Enjoy!

  • Taming the Drupal 5 Permissions System

    A few weeks ago I wrote a short how-to on allowing various roles to view unpublished content without having the ‘administer nodes’ permission in Drupal 5. At that time I promised to write a follow-up article on taming the Drupal 5 permissions system, allowing for additional circumvention of the monolithic ‘administer nodes’ permission. A few weeks, and one cramped cross-country flight later, that article (and the code behind it for that matter!) has finally ‘landed’ as it were.

    The first step is once again to query the database for a list of all content types in the system, and then loop through them and output appropriately granular permissions for the various publishing options we want to support.

    /**
     * Build a list of permissions for publishing, promoting, making
     * sticky, and creating revisions for each content type in the system.
     */
    function publisher_perm() {
      $perms = array();
      //get a list of all content types in the system
      $types = db_query("select type from {node_type} order by type");
      $i=0;
      //loop through and add permissions the perms array.
      while ($type = db_result($types, $i++)) {
        $perms[] = 'Publish '. $type .' nodes';
        $perms[] = 'Promote '. $type .' nodes to front page';
        $perms[] = 'Make '. $type .' nodes sticky';
        //it's recommended you turn on 'view revisions' for roles using this permission
        //to get  the full 'revision' effect. Otherwise there is no hope of feedback for
        //users when creating new revisions.
        $perms[] = 'Create new revisions for '. $type .' nodes';
      }
     
      return $perms;
    }

    Once we’ve done that we have the ability to assign these permissions on a per-role basis. However, this does nothing for making the permissions to show up on the node editing form, so we’ll have to create a implementation of hook_form_alter to add the checkboxes into the node edit forms where appropriate. That’s going to look like this:

    function publisher_form_alter($form_id, &$form) {
      //determine if the form being created is a node creation/edit form
      if (arg(0) == 'node' && (arg(2) == 'edit' || arg(1) == 'add')) {
        $node = $form['#node'];
        //determine if the current user has rights to publish, promote, create revisions, or make a node of this type sticky.
        if (!user_access('administer nodes') && (user_access('Publish '. $node->type .' nodes') || user_access('Promote '. $node->type .' nodes to front page') || user_access('Make '. $node->type .' nodes sticky') || user_access('Create new revisions for '. $node->type .' nodes'))) {
     
          //Now we'll steal some code from node.module, wrapping the various options in our user_access callback.
          //I've left the '#access' key in place, but commented it out, for easy comparison to the original node.module code.
          $form['options'] = array(
            '#type' => 'fieldset',
            //'#access' => user_access('administer nodes'),
            '#title' => t('Publishing options'),
            '#collapsible' => TRUE,
            '#collapsed' => TRUE,
            '#weight' => 25,
          );
     
     
          if (user_access('Publish '. $node->type .' nodes')) {
            $form['options']['status']   = array('#type' => 'checkbox', '#title' => t('Published'), '#default_value' => $node->status);
          }
     
          if (user_access('Promote '. $node->type .' nodes to front page')) {
            $form['options']['promote']  = array('#type' => 'checkbox', '#title' => t('Promoted to front page'), '#default_value' => $node->promote);
          }
     
          if (user_access('Make '. $node->type .' nodes sticky')) {
            $form['options']['sticky']   = array('#type' => 'checkbox', '#title' => t('Sticky at top of lists'), '#default_value' => $node->sticky);
          }
     
          if (user_access('Create new revisions for '. $node->type .' nodes')) {
            $form['options']['revision'] = array('#type' => 'checkbox', '#title' => t('Create new revision'), '#default_value' => $node->revision);
          }
        }
      }
    }

    Now we just need to add in a submit callback to set these values on the node object, or we can write some ugly queries which set these values in the database direc… wait, what?! we don’t? Nope, we don’t. We’re done. The beauty of this method is that the forms submit handler, node_form_submit(), will still do all the hard work for us. Node.module does it’s access control for this functionality by adding a ‘#access’ key to the ‘Publishing Options’ fieldset when creating a node add/edit form, meaning in form node.module originally built gets processed by the Forms API it will omit the publishing options if the current user doesn’t have sufficient privileges. There’s no reason for it to do a follow-up permissions check after the form is submitted, since the built in security in the Forms API will disregard any values submitted which weren’t in the form after it was originally built (preventing malicious users from adding additional fields to the form). What that boils down to in less-nerdy terminology is this; if these values show up in a form after it’s submitted then the fields were put there by a module, and node.module isn’t concerned with whether it created the form fields, or whether they come from another module.

    It’s interesting to compare this to the method I wrote about to allow users to view unpublished content. In both cases we’re modifying access rules to functionality that core provides. With the view_unpublished module we were able to selectively override the menu items responsible for displaying nodes. With this module, we selectively override elements in the node forms to display when conditions we set are met. In both cases, the Drupal core provided a great road-map for how to properly achieve our goals, and our modifications boil down to overriding the default access checks core uses. It’s a testament to the Drupal core that it’s flexible enough to allow these modifications from the outside-in, without requiring developers to destroy their upgrade path to get the features they need.

previous1234