Creating a Basic Feature for OpenAtrium

Nov 25 2009
In my "previous post": I explained how to get up and running with OpenAtrium. Once you've done that you're ready for the next step - creating a basic feature. Features Admin Features is one of the cooler contrib modules I've seen in a while. It probably ranks just below MenuTrails on my list of totally awesome modules. Features allows you to create what are in effect mini-modules which contain code to import CCK types and fields, views, imagecache preferences, blocks, panels settings - pretty much anything that has an export/import function. They also keep track of which modules are required in order for your feature to function and build those into the module's info file's dependencies section. Atrium is quite fond of Features. A big part of the Organic Groups implementation in OA uses Feature modules to provide for things like wikis. There's also a feature that creates a file sharing system. If you've ever used Basecamp, you'll be familiar with the file sharing/commenting functionality provided there. Our client needed this functionality to be replicated on their OA site, and while as I mentioned there is a basic file sharing feature provided by OA, it doesn't have the same feel as Basecamp's file sharing system. Specifically, OA's default file sharing functionality is based on the Book module, and because of this there's a lot of Book module "branding" - "Create a new book," for example, is one of the menu options. For a Drupal expert this wouldn't be a problem, but for people who might be new to Drupal this could be very, very confusing. So I created my own Feature, so that we would have more control over how things are described, how they function, etc. Here's how to do it:
  1. First, in order to get our feature working, we'll need to create everything that the feature will use. For our file sharing system, this means configuring CCK with a new content type and fields and configuring a view to display recent files. We'll also be doing some configuration around notification.
    • Go to admin/content/types and click "Add Content Type." Remember, if you're using OA as a subdomain you'll need your URL to be your atriumpath/admin/content/types. Fill in the relevant information for the content type. I used "File Upload"/"file_upload" as the name for my content type. I've also adjusted Workflow Settings to disable file attachments (we'll be using CCK uploads for the files) and renamed the Body field to "File Description." Since I'm using OG, and I want these files to be uploaded to specific groups, under the Organic Groups tab I've checked "Standard Group Post." Under Atrium I've checked "Show in recent activity views." I've set comments to read/write, and since we want to be able to notify people when a file has been uploaded or modified, I've set "Subscription Settings" to allow subscriptions. Click save.
    • Now add your fields - the only field I added was "File Attachment," using the "File" type and setting number of values to unlimited - we don't know for sure if a client would want to upload more than one file at a time, so we're going the safe route. Modify the other settings as you see fit, and then save.
    • Next up is views. We'll start with a basic page view to list our files. Set your filters to node type: (type you created) and node: published = yes. Sort by Node: Post date, and then if you want to add arguments, do that now. Save your view.
  2. Now the fun starts. You've got your content type created, you've got the view set up, now you need to create a new feature! This is pretty straightforward. Head to admin/build/features and click the "Create Feature" tab. Add features tab Enter the name, description, and version information for your feature. I believe the "URL of Update XML" is used in a manner similar to Drupal's module status system in that a feature can notify you if the base feature has been modified. You'll only be using this if you're using a feature already shared with the Drupal community.
  3. Click on the dropdown under "Add Components." Add Components screen We'll start by adding a "node" component, so select that. You should see a list of all the different content types available in the system, including the one we just created. Click on that one, and you should see a nice AJAX-y sidebar show up. Notice that it includes the field you created, as well as listing module dependencies for that particular CCK instance.
  4. We also need to include our view and our menu item, so go back to the "Add Components" dropdown and select views, then check the view you created.
  5. That's really about it for creating a feature! Click "Download Feature" and you should get a prompt to save or open a tarball. Save it, unpack it, and then move it over to your modules directory. In my case it's sites/all/modules.
  6. Head over to admin/build/features and, if everything went OK, you should now see your new feature! Click the checkbox next to the new feature and then click "Save Settings," and the feature should now be active. But wait, we're not done just yet. In order to get OA to play nicely with the Feature we've got to do a bit of tinkering.
    • First, since OA utilizes spaces for a lot of its functionality, we'll need to provide Spaces with info about this new feature. Go into your new feature's module directory and open up the .info file. We're going to now specify the spaces to which this feature is available. If you don't want any restrictions on this, you can just add this line below the main module information: spaces[types] = "all" Another option would be to specify each individual space. OA has spaces provided for User views and OG-based views, with designators of "user" and "og," respectively. To only enable the feature for these spaces, do this:spaces[types] = "og" spaces[types] = "user"In this example we want to provide a menu item for spaces as well, particularly for the dashboard, so I'll also add this: features[menu][] = "file_uploads" Now, save your .info file. Since we've modified basic module info we'll need to do another devel cache clear.
    • Almost there! We now need to give our view an additional filter based on the current "Space." To do this, go back to admin/build/views and edit your view. Add a filter, select the "Spaces" group, and then choose "Spaces: Node in current space." Now, select whatever default (not in space) action you prefer. I'm going to use "Hide all results." Save. Now go over to "Access" in the basic settings area and change that to "Spaces feature" and then select your feature.
    • Now that the view is finalized, we can make sure the feature is turned on for the spaces we want. To do this, go to admin/build/spaces and click 'edit' for whichever space you want your feature to be active. Scroll down and you should see a "Features" list. Select the dropdown next to your new feature and choose either public or private. Most of the time you'll want private. Save.
    • At this point your feature should be showing up in whatever spaces you configured earlier. We're really, really close to being done. However, in order to make this look great, we could really use an icon for our menu item. helps us out a bit here.
      Your feature can provide its own menu icon and any custom CSS by adding a stylesheet in hook_init():/** * Implementation of hook_init(). */ function imageboard_init() { drupal_add_css(drupal_get_path('module', 'imageboard') .'/imageboard.css'); }Icons should be 40x40 PNG-24 files. The CSS for your icon will look like this: #features-menu li a.icon-imageboard span.icon { background:url(images/icon.png) no-repeat; } Note that the class .icon-imageboard is generated based on the path of your menu items. If you have multiple menu items, you can specify a separate icon for each based on the path class.
      In order to provide a nice-looking icon (and spend as few design hours as possible) I hit up Google image search. If you feel like rolling your own icon, just make sure you use PNG 24, otherwise it won't be quite compatible with the OA theme.
    • One final note before we're finished - if you've created a feature which allows content to be created, you'll also want to specify an icon for the "Create Content" dropdown on, for example, a group page. This is pretty easy to do as well, although you may need to firebug a bit to get the right classes. For me, it was: span.spaces-feature.feature-file_uploads { background:url(images/icon_small.png) no-repeat; height:20px; width:20px; }
I hope this has been useful - please feel free to ask questions or comment on my methods. This has been a great learning experience for me, and I hope you've enjoyed it, too! Next time: Spaces, Features and Panels, oh my! A review of some really neat cutting-edge Drupal tech.