Code driven development: using Features effectively in Drupal 6 and 7

55
+967: ;/(; .96> ;/, >,) Antonio De Marco [email protected] Andrea Pescetti [email protected] Code-driven Development: Using Features Effectively in D6 and D7

description

 

Transcript of Code driven development: using Features effectively in Drupal 6 and 7

Page 1: Code driven development: using Features effectively in Drupal 6 and 7

Antonio De [email protected]

Andrea [email protected]

Code-driven Development:Using Features Effectively in D6 and D7

Page 2: Code driven development: using Features effectively in Drupal 6 and 7

Code SettingsContent

Filesystem Database

Page 3: Code driven development: using Features effectively in Drupal 6 and 7

CodeSettings Content

Filesystem Database

Page 4: Code driven development: using Features effectively in Drupal 6 and 7

How can multiple developers work together on the same project?

Page 5: Code driven development: using Features effectively in Drupal 6 and 7

Sharing database dumps?

Page 6: Code driven development: using Features effectively in Drupal 6 and 7
Page 7: Code driven development: using Features effectively in Drupal 6 and 7

Major drawbacks

• Not ideal for a distributed team

• Makes it difficult to push settings to production

• Content and settings are mixed in one db dump

• Easy to lose control

Page 8: Code driven development: using Features effectively in Drupal 6 and 7

Put everything in code

Page 9: Code driven development: using Features effectively in Drupal 6 and 7

Major benefits

• Code can be versioned

• Conflicts can be solved

• Content and settings are separated

• Easy to push changes to production

Page 10: Code driven development: using Features effectively in Drupal 6 and 7

Features: storing configuration in code

Page 11: Code driven development: using Features effectively in Drupal 6 and 7

core = "6.x"dependencies[] = "context"dependencies[] = "features"dependencies[] = "imagecache"dependencies[] = "imagefield"description = "Publish news."features[content][] = "news-field_news_image"features[context][] = "feature_news_list"features[ctools][] = "context:context:3"features[ctools][] = "strongarm:strongarm:1"features[imagecache][] = "news-badge"features[imagecache][] = "news-m"features[imagecache][] = "news-s"features[node][] = "news"...name = "Feature News"package = "Features"project = "feature_news"version = "6.x-1.0-dev"

feature_news.info

Page 12: Code driven development: using Features effectively in Drupal 6 and 7

$ # Dump your changes into code.$ drush features-update feature_name

$ # Restore your changes into the db.$ drush features-revert feature_name

From DB to code and vice versa

Page 13: Code driven development: using Features effectively in Drupal 6 and 7

Want to add a component to a feature?

1. add it to the .info file2. $ drush features-update feature_name

Page 14: Code driven development: using Features effectively in Drupal 6 and 7

Want to remove a component from a feature?

1. remove it from the .info file2. $ drush features-update feature_name

Page 15: Code driven development: using Features effectively in Drupal 6 and 7

Project bootstrap

Page 16: Code driven development: using Features effectively in Drupal 6 and 7

project.makeproject.profile

Page 17: Code driven development: using Features effectively in Drupal 6 and 7

project.make

core = "6.x"

; Contribprojects[features][version] = "1.0"projects[features][subdir] = "contrib"

projects[views][version] = "2.11"projects[views][subdir] = "contrib"

projects[inline][version] = "1.0"projects[inline][subdir] = "contrib"

...

Page 18: Code driven development: using Features effectively in Drupal 6 and 7

project.profile

/** * Implementation of hook_profile_details(). */function project_profile_details() { return array( 'name' => 'Project', 'description' => 'Project Description’, );}

/** * Implementation of hook_profile_modules(). */function project_profile_modules() {

$modules = array( 'cck', 'views', 'features', 'feature_controller', ...

Page 19: Code driven development: using Features effectively in Drupal 6 and 7

Use the controller featureto keep track of development

Enable/disable other features, store sitewide configuration, share changes, etc...

Page 20: Code driven development: using Features effectively in Drupal 6 and 7

Code-driven workflow

Page 21: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

Start: both Developers run installation, Controller Feature is enabled.

Page 22: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

Developer A enables Rules module, Developer B does other work on the project.

Page 23: Code driven development: using Features effectively in Drupal 6 and 7

Features are modules.Modules can be updated via hook_update_N()

Page 24: Code driven development: using Features effectively in Drupal 6 and 7

hook_update_N()

/** * Enabling Rules module */function feature_controller_update_6001() { $return = array(); $modules = array('rules'); drupal_install_modules($modules); $return[] = array('success' => TRUE, 'query' => 'Enabling Rules module'); return $return;}

feature_controller.install

Page 25: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

DevA$ svn ci -m “Enable Rules module.”Developer A commits his changes.

6001

Page 26: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

DevB$ svn up && dr updatedb -y && dr cc all Developer B updates his local copyand wants to remove a user role.

6001

Page 27: Code driven development: using Features effectively in Drupal 6 and 7

/** * 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_update_N()

feature_controller.install

Page 28: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

DevB$ svn ci -m “Removed contributor role.”Developer B commits his changes.

6001

6002

Page 29: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

Click. Click. Click. DevB$ patch -p0 < inline.patchClick. Click. Click.Developer B adds an OpenID account for adminand patches the Inline module.

6001

6002

Page 30: Code driven development: using Features effectively in Drupal 6 and 7

hook_update_N()

/** * Adding Nuvole OpenID to admin account */function feature_controller_update_6003() { $return = array(); $uid = 1; $claimed_id = 'http://admin.myopenid.com/'; $return[] = update_sql("DELETE FROM {authmap} WHERE authname = '$claimed_id'"); $return[] = update_sql("INSERT INTO {authmap}(uid, authname, module) VALUES($uid, '$claimed_id', 'openid')"); return $return;}

feature_controller.install

Page 31: Code driven development: using Features effectively in Drupal 6 and 7

project.make

...

projects[inline][type] = "module"projects[inline][download][type] = "cvs"projects[inline][download][module] = "contributions/modules/inline"projects[inline][download][revision] = "HEAD:2010-03-06"projects[inline][subdir] = "contrib"

...

;; Patches;projects[inline][patch][] = "http://drupal.org/files/issues/inline.patch"

Page 32: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

DevB$ svn ci -m “Add OpenID for admin. Patching Inline”Developer B commits his changes.

6001

6002 6003

Page 33: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

DevC$ svn co http://svn.nuvole.org/projectDeveloper C joins.

6001

6002 6003

Dev

elop

er C

Time

Page 34: Code driven development: using Features effectively in Drupal 6 and 7

hook_update_N() is not enough.Structural updates go in hook_install() too

Page 35: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

6001

6002 6003

Dev

elop

er C

Time

feature_controller_install()

Page 36: Code driven development: using Features effectively in Drupal 6 and 7

/** * Implementation of hook_install() */function feature_controller_install() { $return = array(); $modules = array('rules'); drupal_install_modules($modules); $return[] = array('success' => TRUE, 'query' => 'Enable Rules module.'); $uid = 1; $claimed_id = 'http://nuvole.myopenid.com/'; $return[] = update_sql("INSERT INTO {authmap}(uid, authname, module) VALUES($uid, '$claimed_id', 'openid')"); return $return;}

hook_install()

feature_controller.install

Page 37: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

Click. Click. Click. Developer C installs the project.

6001

6002 6003

Dev

elop

er C

Time

Page 38: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

Click. Click. Click. Developer C creates and enables a new feature.

6001

6002 6003

Dev

elop

er C

Time

Page 39: Code driven development: using Features effectively in Drupal 6 and 7

hook_update_N()

/** * Enabling News feature */function feature_controller_update_6004() { $return = array(); $modules = array('feature_news'); features_install_modules($modules); $return[] = array('success' => TRUE, 'query' => 'Enabling News'); return $return;}

feature_controller.install

Page 40: Code driven development: using Features effectively in Drupal 6 and 7

/** * Implementation of hook_install() */function feature_controller_install() { $return = array(); $modules = array('rules'); drupal_install_modules($modules); $return[] = array('success' => TRUE, 'query' => 'Enable Rules module.'); $uid = 1; $claimed_id = 'http://nuvole.myopenid.com/'; $return[] = update_sql("INSERT INTO {authmap}(uid, authname, module) VALUES($uid, '$claimed_id', 'openid')");

$modules = array('feature_news'); features_install_modules($modules); $return[] = array('success' => TRUE, 'query' => 'Enabling News');

return $return;}

feature_controller.install

Page 41: Code driven development: using Features effectively in Drupal 6 and 7

Dev

elop

er A

Dev

elop

er B

Controller Feature Workflow

Time

Time

DevC$ svn ci -m “News Feature.”Developer C commits his changes.

6001

6002 6003

Dev

elop

er C

Time

6004

Page 42: Code driven development: using Features effectively in Drupal 6 and 7

Code conventions for a better world.

Page 43: Code driven development: using Features effectively in Drupal 6 and 7
Page 44: Code driven development: using Features effectively in Drupal 6 and 7

# 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

Feature namespace

Page 45: Code driven development: using Features effectively in Drupal 6 and 7

Content type namespace

# News (news)

CCK Fields field_news_pictures field_news_links

Imagecache Presets news-s news-m news-l news-portrait

Page 46: Code driven development: using Features effectively in Drupal 6 and 7

Features BoundariesPackage functionalities in a logical way

Page 47: Code driven development: using Features effectively in Drupal 6 and 7

Features InheritanceRe-use and extend features

Page 48: Code driven development: using Features effectively in Drupal 6 and 7

Drupal 7

Page 49: Code driven development: using Features effectively in Drupal 6 and 7

Installation profiles are like modulesproject.info

project.installproject.profile

Page 50: Code driven development: using Features effectively in Drupal 6 and 7

name = Projectdescription = Project Description.core = 7.x

dependencies[] = "context"dependencies[] = "features"dependencies[] = "feature_controller"...files[] = project.profile

project.info

Page 51: Code driven development: using Features effectively in Drupal 6 and 7

/** * Enabling Rules module */function project_update_6001() { $return = array(); $modules = array('rules'); drupal_install_modules($modules); $return[] = array('success' => TRUE, 'query' => 'Enabling Rules module'); return $return;}

/** * Removing contributor role */function project_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;}

project.install

Page 52: Code driven development: using Features effectively in Drupal 6 and 7

project.profile

/** * Implementation of hook_install_tasks() */function project_install_tasks($install_state) {

...

}

/** * Implementation of hook_form_FORM_ID_alter() */function project_form_install_configure_form_alter(&$form, $form_state) {

...

}

Page 54: Code driven development: using Features effectively in Drupal 6 and 7

Installation Profiles As A Development Toolby Florian Loretan

http://bxl2011.drupaldays.org/node/280

See also:

Page 55: Code driven development: using Features effectively in Drupal 6 and 7

Thank You.

http://nuvole.org

@nuvoleweb