SlideShare a Scribd company logo
1 of 48
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

More Related Content

What's hot

Angular Promises and Advanced Routing
Angular Promises and Advanced RoutingAngular Promises and Advanced Routing
Angular Promises and Advanced RoutingAlexe Bogdan
 
Drupal Development (Part 2)
Drupal Development (Part 2)Drupal Development (Part 2)
Drupal Development (Part 2)Jeff Eaton
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patternsSamuel ROZE
 
Drupal Step-by-Step: How We Built Our Training Site, Part 1
Drupal Step-by-Step: How We Built Our Training Site, Part 1Drupal Step-by-Step: How We Built Our Training Site, Part 1
Drupal Step-by-Step: How We Built Our Training Site, Part 1Acquia
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
Introduction to CQRS and Event Sourcing
Introduction to CQRS and Event SourcingIntroduction to CQRS and Event Sourcing
Introduction to CQRS and Event SourcingSamuel ROZE
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Luka Zakrajšek
 
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...allilevine
 
Routing in Drupal 8
Routing in Drupal 8Routing in Drupal 8
Routing in Drupal 8kgoel1
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDAleix Vergés
 
Goodbye hook_menu() - Routing and Menus in Drupal 8
Goodbye hook_menu() - Routing and Menus in Drupal 8Goodbye hook_menu() - Routing and Menus in Drupal 8
Goodbye hook_menu() - Routing and Menus in Drupal 8Exove
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)brockboland
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 

What's hot (20)

Amp Up Your Admin
Amp Up Your AdminAmp Up Your Admin
Amp Up Your Admin
 
Angular Promises and Advanced Routing
Angular Promises and Advanced RoutingAngular Promises and Advanced Routing
Angular Promises and Advanced Routing
 
Drupal Development (Part 2)
Drupal Development (Part 2)Drupal Development (Part 2)
Drupal Development (Part 2)
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
Drupal Step-by-Step: How We Built Our Training Site, Part 1
Drupal Step-by-Step: How We Built Our Training Site, Part 1Drupal Step-by-Step: How We Built Our Training Site, Part 1
Drupal Step-by-Step: How We Built Our Training Site, Part 1
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
Introduction to CQRS and Event Sourcing
Introduction to CQRS and Event SourcingIntroduction to CQRS and Event Sourcing
Introduction to CQRS and Event Sourcing
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
 
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...
WordCamp Montreal 2015: Combining Custom Post Types, Fields, and Meta Boxes t...
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Routing in Drupal 8
Routing in Drupal 8Routing in Drupal 8
Routing in Drupal 8
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Decoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDDDecoupling the Ulabox.com monolith. From CRUD to DDD
Decoupling the Ulabox.com monolith. From CRUD to DDD
 
Goodbye hook_menu() - Routing and Menus in Drupal 8
Goodbye hook_menu() - Routing and Menus in Drupal 8Goodbye hook_menu() - Routing and Menus in Drupal 8
Goodbye hook_menu() - Routing and Menus in Drupal 8
 
201104 iphone navigation-based apps
201104 iphone navigation-based apps201104 iphone navigation-based apps
201104 iphone navigation-based apps
 
Drupal 8 Routing
Drupal 8 RoutingDrupal 8 Routing
Drupal 8 Routing
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)Drupal is Stupid (But I Love It Anyway)
Drupal is Stupid (But I Love It Anyway)
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 

Similar to First Steps in Drupal Code Driven Development

Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
Empowering users: modifying the admin experience
Empowering users: modifying the admin experienceEmpowering users: modifying the admin experience
Empowering users: modifying the admin experienceBeth Soderberg
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)arcware
 
Debugging in drupal 8
Debugging in drupal 8Debugging in drupal 8
Debugging in drupal 8Allie Jones
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperGary Hockin
 
Web applications with Catalyst
Web applications with CatalystWeb applications with Catalyst
Web applications with Catalystsvilen.ivanov
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Using the Features API
Using the Features APIUsing the Features API
Using the Features APIcgmonroe
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说Ting Lv
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery ApplicationsRebecca Murphey
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolGordon Forsythe
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowVrann Tulika
 
The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinNida Ismail Shah
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar SimovićJS Belgrade
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS ArchitectureEyal Vardi
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS InternalEyal Vardi
 

Similar to First Steps in Drupal Code Driven Development (20)

Extend sdk
Extend sdkExtend sdk
Extend sdk
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
 
Empowering users: modifying the admin experience
Empowering users: modifying the admin experienceEmpowering users: modifying the admin experience
Empowering users: modifying the admin experience
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
Debugging in drupal 8
Debugging in drupal 8Debugging in drupal 8
Debugging in drupal 8
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 Developer
 
Web applications with Catalyst
Web applications with CatalystWeb applications with Catalyst
Web applications with Catalyst
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Using the Features API
Using the Features APIUsing the Features API
Using the Features API
 
前端MVC 豆瓣说
前端MVC 豆瓣说前端MVC 豆瓣说
前端MVC 豆瓣说
 
Building Large jQuery Applications
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
 
Magento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request FlowMagento Live Australia 2016: Request Flow
Magento Live Australia 2016: Request Flow
 
The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon Dublin
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
 

More from Nuvole

The OpenEuropa Initiative
The OpenEuropa InitiativeThe OpenEuropa Initiative
The OpenEuropa InitiativeNuvole
 
CMI 2.0 session at Drupal DevDays in Cluj-Napoca
CMI 2.0 session at Drupal DevDays in Cluj-NapocaCMI 2.0 session at Drupal DevDays in Cluj-Napoca
CMI 2.0 session at Drupal DevDays in Cluj-NapocaNuvole
 
Advanced Configuration Management with Config Split et al.
Advanced Configuration Management with Config Split et al.Advanced Configuration Management with Config Split et al.
Advanced Configuration Management with Config Split et al.Nuvole
 
Introducing the UI Patterns module: use atomic UI components everywhere in Dr...
Introducing the UI Patterns module: use atomic UI components everywhere in Dr...Introducing the UI Patterns module: use atomic UI components everywhere in Dr...
Introducing the UI Patterns module: use atomic UI components everywhere in Dr...Nuvole
 
Drupal 8 Configuration Management with Features
Drupal 8 Configuration Management with FeaturesDrupal 8 Configuration Management with Features
Drupal 8 Configuration Management with FeaturesNuvole
 
Configuration Management in Drupal 8: A preview (DrupalCamp Alpe Adria 2014)
Configuration Management in Drupal 8: A preview (DrupalCamp Alpe Adria 2014)Configuration Management in Drupal 8: A preview (DrupalCamp Alpe Adria 2014)
Configuration Management in Drupal 8: A preview (DrupalCamp Alpe Adria 2014)Nuvole
 
Configuration Management in Drupal 8: A preview (DrupalDays Milano 2014)
Configuration Management in Drupal 8: A preview (DrupalDays Milano 2014)Configuration Management in Drupal 8: A preview (DrupalDays Milano 2014)
Configuration Management in Drupal 8: A preview (DrupalDays Milano 2014)Nuvole
 
Automating Drupal Development: Makefiles, features and beyond
Automating Drupal Development: Makefiles, features and beyondAutomating Drupal Development: Makefiles, features and beyond
Automating Drupal Development: Makefiles, features and beyondNuvole
 
Building and Maintaining a Distribution in Drupal 7 with Features
Building and Maintaining a  Distribution in Drupal 7 with FeaturesBuilding and Maintaining a  Distribution in Drupal 7 with Features
Building and Maintaining a Distribution in Drupal 7 with FeaturesNuvole
 
Remote Collaboration and Institutional Intranets with Drupal and Open Atrium
Remote Collaboration and Institutional Intranets with Drupal and Open AtriumRemote Collaboration and Institutional Intranets with Drupal and Open Atrium
Remote Collaboration and Institutional Intranets with Drupal and Open AtriumNuvole
 
Public Works Monitoring
Public Works MonitoringPublic Works Monitoring
Public Works MonitoringNuvole
 
Extending and Customizing Open Atrium
Extending and Customizing Open AtriumExtending and Customizing Open Atrium
Extending and Customizing Open AtriumNuvole
 
Code driven development: using Features effectively in Drupal 6 and 7
Code driven development: using Features effectively in Drupal 6 and 7Code driven development: using Features effectively in Drupal 6 and 7
Code driven development: using Features effectively in Drupal 6 and 7Nuvole
 
Features based development workflow
Features based development workflowFeatures based development workflow
Features based development workflowNuvole
 

More from Nuvole (14)

The OpenEuropa Initiative
The OpenEuropa InitiativeThe OpenEuropa Initiative
The OpenEuropa Initiative
 
CMI 2.0 session at Drupal DevDays in Cluj-Napoca
CMI 2.0 session at Drupal DevDays in Cluj-NapocaCMI 2.0 session at Drupal DevDays in Cluj-Napoca
CMI 2.0 session at Drupal DevDays in Cluj-Napoca
 
Advanced Configuration Management with Config Split et al.
Advanced Configuration Management with Config Split et al.Advanced Configuration Management with Config Split et al.
Advanced Configuration Management with Config Split et al.
 
Introducing the UI Patterns module: use atomic UI components everywhere in Dr...
Introducing the UI Patterns module: use atomic UI components everywhere in Dr...Introducing the UI Patterns module: use atomic UI components everywhere in Dr...
Introducing the UI Patterns module: use atomic UI components everywhere in Dr...
 
Drupal 8 Configuration Management with Features
Drupal 8 Configuration Management with FeaturesDrupal 8 Configuration Management with Features
Drupal 8 Configuration Management with Features
 
Configuration Management in Drupal 8: A preview (DrupalCamp Alpe Adria 2014)
Configuration Management in Drupal 8: A preview (DrupalCamp Alpe Adria 2014)Configuration Management in Drupal 8: A preview (DrupalCamp Alpe Adria 2014)
Configuration Management in Drupal 8: A preview (DrupalCamp Alpe Adria 2014)
 
Configuration Management in Drupal 8: A preview (DrupalDays Milano 2014)
Configuration Management in Drupal 8: A preview (DrupalDays Milano 2014)Configuration Management in Drupal 8: A preview (DrupalDays Milano 2014)
Configuration Management in Drupal 8: A preview (DrupalDays Milano 2014)
 
Automating Drupal Development: Makefiles, features and beyond
Automating Drupal Development: Makefiles, features and beyondAutomating Drupal Development: Makefiles, features and beyond
Automating Drupal Development: Makefiles, features and beyond
 
Building and Maintaining a Distribution in Drupal 7 with Features
Building and Maintaining a  Distribution in Drupal 7 with FeaturesBuilding and Maintaining a  Distribution in Drupal 7 with Features
Building and Maintaining a Distribution in Drupal 7 with Features
 
Remote Collaboration and Institutional Intranets with Drupal and Open Atrium
Remote Collaboration and Institutional Intranets with Drupal and Open AtriumRemote Collaboration and Institutional Intranets with Drupal and Open Atrium
Remote Collaboration and Institutional Intranets with Drupal and Open Atrium
 
Public Works Monitoring
Public Works MonitoringPublic Works Monitoring
Public Works Monitoring
 
Extending and Customizing Open Atrium
Extending and Customizing Open AtriumExtending and Customizing Open Atrium
Extending and Customizing Open Atrium
 
Code driven development: using Features effectively in Drupal 6 and 7
Code driven development: using Features effectively in Drupal 6 and 7Code driven development: using Features effectively in Drupal 6 and 7
Code driven development: using Features effectively in Drupal 6 and 7
 
Features based development workflow
Features based development workflowFeatures based development workflow
Features based development workflow
 

Recently uploaded

New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 

Recently uploaded (20)

New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 

First Steps in Drupal Code Driven Development

  • 1. DROPS THAT GROW THE WEB. First Steps in Code Driven Development A 100% database-free development workflow. Antonio De Marco antonio@nuvole.org
  • 3.
  • 4. 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
  • 6. Major benefit • Code can be versioned • Conflicts can be solved • Content and settings are separated • Easy to push updates to production
  • 7. What the Features module is all about?
  • 8. Have you noticed that your features don't necessarily depend from the Features module?
  • 9. 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()
  • 10. /** * 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'; ...
  • 11. /** * 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( ...
  • 12. 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); }
  • 13. What about the rest?
  • 14. Do your tables use strings as primary keys?
  • 15. Do your tables use strings as primary keys? Yes?
  • 16. Do your tables use strings as primary keys? Yes? Really?
  • 17. Do your tables use strings as primary keys? Yes? Really? Great! Then...
  • 18. Meet CTools Export plugin a.k.a. Get magic by altering your module's schema
  • 19. An example: Strongarm and variables export.
  • 20. /** * 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; }
  • 21. In your .info file add: features[variable][] = "theme_default"
  • 22.
  • 23. And you will get:
  • 24. 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; }
  • 25. Features keeps track of DB changes.
  • 26. $ # Dump your changes into code. $ drush features-update feature_name $ # Restore your changes into the db. $ drush features-revert feature_name
  • 27. Want to add a component to the a feature?
  • 28. Want to add a component to the a feature? 1. add it to your feature_name.info 2. $ drush features-update feature_name
  • 29. Want to remove a component to the a feature?
  • 30. Want to remove a component to the a feature? 1. remove it from your feature_name.info 2. $ drush features-update feature_name
  • 31. Code conventions for a better world.
  • 32. 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
  • 33. Content type namespace # News (news) CCK Fields field_news_pictures field_news_links Imagecache Presets news-s news-m news-l news-portrait
  • 34. 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.
  • 35. Meet your friends hook_install() and hook_update_N()
  • 36. The Controller Feature a.k.a. a feature to rule them all
  • 37. 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.'); }
  • 38. 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); }
  • 39. 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'"); }
  • 40. 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; }
  • 41. 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; }
  • 42. hook_install() /** * Implementation of hook_install() */ function feature_controller_install() { feature_controller_update_6001(); feature_controller_update_6002(); }
  • 45. Context Same context different reactions. feature_controller_frontpage: News block, Events block That’s bad...
  • 46. Context Different contexts share the same conditions. feature_news_frontpage: News block feature_events_frontpage: Events block That’s Good!
  • 47. Extending features Are we ready? Does it make sense?
  • 48. DROPS THAT GROW THE WEB. Thank You. http://nuvole.org @nuvoleweb #codepower

Editor's Notes