First Steps in Drupal Code Driven Development
Upcoming SlideShare
Loading in...5
×
 

First Steps in Drupal Code Driven Development

on

  • 9,925 views

"First Steps in Code Driven Development" covers basic techniques and good practices. Presented during the "Developer Session" at Krimson office, Antwerp (BE), the 27th of May 2010.

"First Steps in Code Driven Development" covers basic techniques and good practices. Presented during the "Developer Session" at Krimson office, Antwerp (BE), the 27th of May 2010.

Statistics

Views

Total Views
9,925
Views on SlideShare
9,365
Embed Views
560

Actions

Likes
12
Downloads
194
Comments
1

11 Embeds 560

http://www.slideshare.net 372
http://nuvole.org 171
http://demo.nuvole.org 4
http://www.lmodules.com 3
http://us-w1.rockmelt.com 3
http://thinkery.me 2
http://www.casamentocuritiba.com.br 1
http://translate.googleusercontent.com 1
http://static.slidesharecdn.com 1
http://feeds.feedburner.com 1
http://eq6.nuvole.org 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />

First Steps in Drupal Code Driven Development First Steps in Drupal Code Driven Development Presentation Transcript

  • DROPS THAT GROW THE WEB. First Steps in Code Driven Development A 100% database-free development workflow. Antonio De Marco antonio@nuvole.org
  • Database Driven Development
  • Major pitfalls • Not ideal for a distributed team • Makes difficult to push settings to production • Content and settings are mixed in one db dump • Easy to lose control
  • Power to code
  • Major benefit • Code can be versioned • Conflicts can be solved • Content and settings are separated • Easy to push updates to production
  • What the Features module is all about?
  • Have you noticed that your features don't necessarily depend from the Features module?
  • Features is a “hook_default()” generator. CCK: hook_content_default_fields() Contexts: hook_context_default_contexts() Fieldgroups: hook_fieldgroup_default_groups() Filters: hook_filter_default_formats() Imagecache: hook_imagecache_default_presets() Menu: hook_menu_default_items() Node type: hook_node_info() Permissions: hook_user_default_permissions() Views: hook_views_default_views()
  • /** * Helper to implementation of hook_views_default_views(). */ function _atrium_views_default_views() { $views = array(); // Exported view: atrium_book_current $view = new view; $view->name = 'atrium_book_current'; $view->description = 'Atrium: book: helper'; $view->tag = 'atrium'; ...
  • /** * Helper to implementation of hook_content_default_fields(). */ function _atrium_blog_content_default_fields() { $fields = array(); // Exported field: field_referenced_book_page $fields[] = array( 'field_name' => 'field_referenced_book_page', 'type_name' => 'blog', 'display_settings' => array( ...
  • Hook helpers are then called from within your feature’s hooks. /** * Implementation of hook_content_default_fields(). */ function atrium_blog_content_default_fields() { module_load_include('inc', 'atrium_blog', 'atrium_blog.defaults'); $args = func_get_args(); return call_user_func_array('_atrium_blog_content_default_fields', $args); } /** * Implementation of hook_views_default_views(). */ function atrium_views_default_views() { module_load_include('inc', 'atrium', 'atrium.features.views'); $args = func_get_args(); return call_user_func_array('_atrium_views_default_views', $args); }
  • What about the rest?
  • Do your tables use strings as primary keys?
  • Do your tables use strings as primary keys? Yes?
  • Do your tables use strings as primary keys? Yes? Really?
  • Do your tables use strings as primary keys? Yes? Really? Great! Then...
  • Meet CTools Export plugin a.k.a. Get magic by altering your module's schema
  • An example: Strongarm and variables export.
  • /** * Implementation of hook_schema_alter(). * Makes the variables table usable by ctools' export.inc. */ function strongarm_schema_alter(&$schema) { $schema['variable']['export'] = array( 'key' => 'name', 'identifier' => 'strongarm', 'default hook' => 'strongarm', 'api' => array( 'owner' => 'strongarm', 'api' => 'strongarm', 'minimum_version' => 1, 'current_version' => 1, ), ); $schema['variable']['fields']['value']['serialize'] = TRUE; }
  • In your .info file add: features[variable][] = "theme_default"
  • And you will get:
  • And you will get: /** * Helper to implementation of hook_strongarm(). */ function _your_module_strongarm() { $export = array(); $strongarm = new stdClass; $strongarm->disabled = FALSE; $strongarm->api_version = 1; $strongarm->name = 'theme_default'; $strongarm->value = 'ginkgo'; $export['theme_default'] = $strongarm; return $export; }
  • Features keeps track of DB changes.
  • $ # Dump your changes into code. $ drush features-update feature_name $ # Restore your changes into the db. $ drush features-revert feature_name
  • Want to add a component to the a feature?
  • Want to add a component to the a feature? 1. add it to your feature_name.info 2. $ drush features-update feature_name
  • Want to remove a component to the a feature?
  • Want to remove a component to the a feature? 1. remove it from your feature_name.info 2. $ drush features-update feature_name
  • Code conventions for a better world.
  • Feature namespace # Feature News (feature_news) Views feature_news_blocks feature_news_list feature_news_node feature_news_taxonomy Contexts feature_news_front feature_news_list Openlayers Presets feature_news_small_map feature_news_big_map
  • Content type namespace # News (news) CCK Fields field_news_pictures field_news_links Imagecache Presets news-s news-m news-l news-portrait
  • Tip: Never share fields across several content types unless you have really good reasons to do so. If you do so you will make your features hardly re-usable.
  • Meet your friends hook_install() and hook_update_N()
  • The Controller Feature a.k.a. a feature to rule them all
  • Create Menus /** * Implementation of hook_install() */ function feature_controller_install() { db_query("INSERT INTO {menu_custom} (menu_name, title, description) VALUES ('%s', '%s', '%s')", 'menu-content', 'Content', 'Manage your site content.'); }
  • Create Menu Items /** * Implementation of hook_install() */ function feature_controller_install() { $item['link_title'] = t('Home'); $item['link_path'] = '<front>'; $item['menu_name'] = 'primary-links'; $item['weight'] = -10; menu_link_save($item); }
  • Do all kind of dirty things... /** * Implementation of hook_install() */ function feature_controller_install() { // Add OpenID to admin user db_query("INSERT INTO {authmap} (uid, authname, module) VALUES(1, 'http://nuvole.myopenid.com/', 'openid')"); // Weight feature_controller to come after other modules -- in particular, admin. db_query("UPDATE {system} SET weight = 1 WHERE name = 'feature_controller' AND type = 'module'"); }
  • hook_update_N() /** * Disabling comment module */ function feature_controller_update_6001() { $return = array(); $modules = array('comment'); module_disable($modules); $return[] = array('success' => TRUE, 'query' => 'Disabling modules: '. implode(', ', $modules)); return $return; }
  • hook_update_N() /** * Removing contributor role */ function feature_controller_update_6002() { $return = array(); $role_name = 'contributor'; $result = db_query("SELECT rid FROM {role} WHERE name='%s'", $role_name); while ($role = db_fetch_object($result)) { $rid = $role->rid; $return[] = update_sql("DELETE FROM {role} WHERE rid = '$rid'"); $return[] = update_sql("DELETE FROM {users_roles} WHERE rid = '$rid'"); } return $return; }
  • hook_install() /** * Implementation of hook_install() */ function feature_controller_install() { feature_controller_update_6001(); feature_controller_update_6002(); }
  • Features architecture: what goes where.
  • Views GROUP BY Arguments, Filters.
  • Context Same context different reactions. feature_controller_frontpage: News block, Events block That’s bad...
  • Context Different contexts share the same conditions. feature_news_frontpage: News block feature_events_frontpage: Events block That’s Good!
  • Extending features Are we ready? Does it make sense?
  • DROPS THAT GROW THE WEB. Thank You. http://nuvole.org @nuvoleweb #codepower