SlideShare uma empresa Scribd logo
1 de 48
Baixar para ler offline
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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Semelhante a 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
 

Semelhante a 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
 

Mais de 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
 

Mais de 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
 

Último

Which standard is best for your content?
Which standard is best for your content?Which standard is best for your content?
Which standard is best for your content?Rustici Software
 
Bridge to the Future: Migrating to KRaft
Bridge to the Future: Migrating to KRaftBridge to the Future: Migrating to KRaft
Bridge to the Future: Migrating to KRaftHostedbyConfluent
 
How Do You Query a Stream? | Kafka Summit London
How Do You Query a Stream? | Kafka Summit LondonHow Do You Query a Stream? | Kafka Summit London
How Do You Query a Stream? | Kafka Summit LondonHostedbyConfluent
 
Error Handling with Kafka: From Patterns to Code
Error Handling with Kafka: From Patterns to CodeError Handling with Kafka: From Patterns to Code
Error Handling with Kafka: From Patterns to CodeHostedbyConfluent
 
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023Joshua Flannery
 
Event Modeling Anti-patterns | Kafka Summit London
Event Modeling Anti-patterns | Kafka Summit LondonEvent Modeling Anti-patterns | Kafka Summit London
Event Modeling Anti-patterns | Kafka Summit LondonHostedbyConfluent
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentMahmoud Rabie
 
CERN IoT Kafka Pipelines | Kafka Summit London
CERN IoT Kafka Pipelines | Kafka Summit LondonCERN IoT Kafka Pipelines | Kafka Summit London
CERN IoT Kafka Pipelines | Kafka Summit LondonHostedbyConfluent
 
Book industry state of the nation 2024 - Tech Forum 2024
Book industry state of the nation 2024 - Tech Forum 2024Book industry state of the nation 2024 - Tech Forum 2024
Book industry state of the nation 2024 - Tech Forum 2024BookNet Canada
 
Beyond Tiered Storage: Serverless Kafka with No Local Disks
Beyond Tiered Storage: Serverless Kafka with No Local DisksBeyond Tiered Storage: Serverless Kafka with No Local Disks
Beyond Tiered Storage: Serverless Kafka with No Local DisksHostedbyConfluent
 
Data Contracts In Practice With Debezium and Apache Flink
Data Contracts In Practice With Debezium and Apache FlinkData Contracts In Practice With Debezium and Apache Flink
Data Contracts In Practice With Debezium and Apache FlinkHostedbyConfluent
 
Automation Ops Series: Session 3 - Solutions management
Automation Ops Series: Session 3 - Solutions managementAutomation Ops Series: Session 3 - Solutions management
Automation Ops Series: Session 3 - Solutions managementDianaGray10
 
Build Copilots on Streaming Data with Generative AI, Kafka Streams and Flink SQL
Build Copilots on Streaming Data with Generative AI, Kafka Streams and Flink SQLBuild Copilots on Streaming Data with Generative AI, Kafka Streams and Flink SQL
Build Copilots on Streaming Data with Generative AI, Kafka Streams and Flink SQLHostedbyConfluent
 
Aggregating Ad Events with Kafka Streams and Interactive Queries at Invidi
Aggregating Ad Events with Kafka Streams and Interactive Queries at InvidiAggregating Ad Events with Kafka Streams and Interactive Queries at Invidi
Aggregating Ad Events with Kafka Streams and Interactive Queries at InvidiHostedbyConfluent
 
Real-time Geospatial Aircraft Monitoring Using Apache Kafka
Real-time Geospatial Aircraft Monitoring Using Apache KafkaReal-time Geospatial Aircraft Monitoring Using Apache Kafka
Real-time Geospatial Aircraft Monitoring Using Apache KafkaHostedbyConfluent
 
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...Transcript: Green paths: Learning from publishers’ sustainability journeys - ...
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...BookNet Canada
 
Transcript: Book industry state of the nation 2024 - Tech Forum 2024
Transcript: Book industry state of the nation 2024 - Tech Forum 2024Transcript: Book industry state of the nation 2024 - Tech Forum 2024
Transcript: Book industry state of the nation 2024 - Tech Forum 2024BookNet Canada
 
Bitdefender-CSG-Report-creat7534-interactive
Bitdefender-CSG-Report-creat7534-interactiveBitdefender-CSG-Report-creat7534-interactive
Bitdefender-CSG-Report-creat7534-interactivestartupro
 
Tecnogravura, Cylinder Engraving for Rotogravure
Tecnogravura, Cylinder Engraving for RotogravureTecnogravura, Cylinder Engraving for Rotogravure
Tecnogravura, Cylinder Engraving for RotogravureAntonio de Llamas
 
Web Development Solutions 2024 A Beginner's Comprehensive Handbook.pdf
Web Development Solutions 2024 A Beginner's Comprehensive Handbook.pdfWeb Development Solutions 2024 A Beginner's Comprehensive Handbook.pdf
Web Development Solutions 2024 A Beginner's Comprehensive Handbook.pdfSeasia Infotech
 

Último (20)

Which standard is best for your content?
Which standard is best for your content?Which standard is best for your content?
Which standard is best for your content?
 
Bridge to the Future: Migrating to KRaft
Bridge to the Future: Migrating to KRaftBridge to the Future: Migrating to KRaft
Bridge to the Future: Migrating to KRaft
 
How Do You Query a Stream? | Kafka Summit London
How Do You Query a Stream? | Kafka Summit LondonHow Do You Query a Stream? | Kafka Summit London
How Do You Query a Stream? | Kafka Summit London
 
Error Handling with Kafka: From Patterns to Code
Error Handling with Kafka: From Patterns to CodeError Handling with Kafka: From Patterns to Code
Error Handling with Kafka: From Patterns to Code
 
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023
THE STATE OF STARTUP ECOSYSTEM - INDIA x JAPAN 2023
 
Event Modeling Anti-patterns | Kafka Summit London
Event Modeling Anti-patterns | Kafka Summit LondonEvent Modeling Anti-patterns | Kafka Summit London
Event Modeling Anti-patterns | Kafka Summit London
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career Development
 
CERN IoT Kafka Pipelines | Kafka Summit London
CERN IoT Kafka Pipelines | Kafka Summit LondonCERN IoT Kafka Pipelines | Kafka Summit London
CERN IoT Kafka Pipelines | Kafka Summit London
 
Book industry state of the nation 2024 - Tech Forum 2024
Book industry state of the nation 2024 - Tech Forum 2024Book industry state of the nation 2024 - Tech Forum 2024
Book industry state of the nation 2024 - Tech Forum 2024
 
Beyond Tiered Storage: Serverless Kafka with No Local Disks
Beyond Tiered Storage: Serverless Kafka with No Local DisksBeyond Tiered Storage: Serverless Kafka with No Local Disks
Beyond Tiered Storage: Serverless Kafka with No Local Disks
 
Data Contracts In Practice With Debezium and Apache Flink
Data Contracts In Practice With Debezium and Apache FlinkData Contracts In Practice With Debezium and Apache Flink
Data Contracts In Practice With Debezium and Apache Flink
 
Automation Ops Series: Session 3 - Solutions management
Automation Ops Series: Session 3 - Solutions managementAutomation Ops Series: Session 3 - Solutions management
Automation Ops Series: Session 3 - Solutions management
 
Build Copilots on Streaming Data with Generative AI, Kafka Streams and Flink SQL
Build Copilots on Streaming Data with Generative AI, Kafka Streams and Flink SQLBuild Copilots on Streaming Data with Generative AI, Kafka Streams and Flink SQL
Build Copilots on Streaming Data with Generative AI, Kafka Streams and Flink SQL
 
Aggregating Ad Events with Kafka Streams and Interactive Queries at Invidi
Aggregating Ad Events with Kafka Streams and Interactive Queries at InvidiAggregating Ad Events with Kafka Streams and Interactive Queries at Invidi
Aggregating Ad Events with Kafka Streams and Interactive Queries at Invidi
 
Real-time Geospatial Aircraft Monitoring Using Apache Kafka
Real-time Geospatial Aircraft Monitoring Using Apache KafkaReal-time Geospatial Aircraft Monitoring Using Apache Kafka
Real-time Geospatial Aircraft Monitoring Using Apache Kafka
 
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...Transcript: Green paths: Learning from publishers’ sustainability journeys - ...
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...
 
Transcript: Book industry state of the nation 2024 - Tech Forum 2024
Transcript: Book industry state of the nation 2024 - Tech Forum 2024Transcript: Book industry state of the nation 2024 - Tech Forum 2024
Transcript: Book industry state of the nation 2024 - Tech Forum 2024
 
Bitdefender-CSG-Report-creat7534-interactive
Bitdefender-CSG-Report-creat7534-interactiveBitdefender-CSG-Report-creat7534-interactive
Bitdefender-CSG-Report-creat7534-interactive
 
Tecnogravura, Cylinder Engraving for Rotogravure
Tecnogravura, Cylinder Engraving for RotogravureTecnogravura, Cylinder Engraving for Rotogravure
Tecnogravura, Cylinder Engraving for Rotogravure
 
Web Development Solutions 2024 A Beginner's Comprehensive Handbook.pdf
Web Development Solutions 2024 A Beginner's Comprehensive Handbook.pdfWeb Development Solutions 2024 A Beginner's Comprehensive Handbook.pdf
Web Development Solutions 2024 A Beginner's Comprehensive Handbook.pdf
 

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

Notas do Editor