SlideShare ist ein Scribd-Unternehmen logo
1 von 58
Downloaden Sie, um offline zu lesen
Staying Sane with Drupal
A Developer's Survival Guide
Oscar Merida, @omerida
Drupal GovCon
July 2015
80% of building sites with
Drupal is configuration (easy)
Credit: https://www.flickr.com/photos/jeepersmedia/12953571545/
The hard part is the final
20% of customization
• Functionality that is
new to Drupal
• or different than
assumptions
• Integration with
external systems
Credit: https://www.flickr.com/photos/jurvetson/15393495039
Drupal is procedural
• Not Object Oriented
• Many structures like nodes, forms, users, etc use StdClass
objects or arrays
• Not MVC like other PHP frameworks
• but there is separation of concerns between menu callbacks
& theme layers
• Hooks afford a way to alter existing functionality or implement
new features.
• Leverage hooks
Play Well with Others
• Don’t short circuit how
things work.
• If you're stuck, ask for help.
• "Always code as if the
person who ends up
maintaining your code is a
violent psychopath who
knows where you live."
• http://c2.com/cgi/wiki?
CodeForTheMaintainer
Use Existing APIs
• EntityFieldQuery
• Form API
• node_load(), node_presave(), node_* hooks
• Node Access System
Dig into the Documentation
• api.drupal.org has function definitions and
examples.
• Security - 

https://www.drupal.org/writing-secure-code
• Issue Queues
Best Practices
Rule 0: Use VCS
• If you're not already using a Version Control
System STOP
• start using one ASP
• Git, Subversion, etc..
• Rule 0.1 - never edit files on live
Follow Drupal's coding standard.
• Everyone on the team must follow it.
• https://www.drupal.org/coding-standards
• Don't waste cycles arguing about which
standard to follow.
• Can use your IDE to follow a standard.
• BONUS: Use PHP CodeSniffer to enforce it.
Use a Virtual Machine
• Use Vagrant to setup a VM for your project
• All developers use the same VM (no more "works
on my machine)
• VM should match stage and production
environments.
• Same OS, same PHP, same Mysql, etc.
• Avoids bugs that only happen on production.
Use Features
• Drupal saves a lot of configuration to the database,
making deployments difficult.
• Use Features + Strongarm modules to export settings to
Features modules.
• Create one Feature module for each Content Type
• Include related fields, Views, Display Suite settings,
Panels & Pages or Contexts, Path aliases, Rules,etc.
• Have a Base module with shared fields and global
settings like input formats.
Share Features
• Track your modules in VCS
• When you update codebase, check Features UI for
Overrides and resolve them.
Use VCS Branches
• Isolate new work on new
branches.
• Merge to master/trunk when
ready for testing.
• Merge to a stable branch
when ready to deploy.
• http://www.mediacurrent.com/
blog/git-flow-daily-use
https://www.flickr.com/photos/malcolmtredinnick/1516857444
Automate Deployments
• As simple as having a simple script to sync files
to your environments
• Or automagically update dev, stage, production
by pushing to the correct VCS branch
• https://www.freelock.com/node/1108
• BUT remember to keep sensitive information out
of VCS (like database credentials).
Don't Fear the Command Line
• Drush is faster and easier to automate than
going through the UI.
• Clearing caches - drush cc all
• DB Snapshot - drush sql-dump > ../mydb.sql
• Creating a user - drush user-create
• Reindexing search - drush search-index
Contrib makes life
easy
…except when it doesn’t.
Focus on building new solutions.
• Avoid “Not-invented-here” syndrome
• There's a module for that. In fact, there's
probably several …
http://dilbert.com/strip/2014-08-11
But with great power…
• Inherit technical debt
of a module
• Keep up-to-date with
new releases,
especially security
releases.
• Sometimes you don't
need a module to
change things.
Evaluating a module
• Does the maintainer have other modules?
• Does it have a stable release?
• Does it have recent commits?
• Is the issue queue active?
• Does it have good documentation?
Practically core…
• Views (is in D8)
• Views Bulk Operations
• Features & Strongarm
• Pathauto & Token
• Webform
• Rules
• Email
• Link
• Smart Trim
• Redirect
• Entity Reference
• Entity API
• Entity Cache
Nice to Have
• Bean (better Blocks)
• Administration Views
• Display Suite
• Backup & Migrate
• Content Locking
• Menu Block
• Revisioning
• Add Another
Migration tools
• Feeds
• or Migrate
• Pathologic
• Views Data Export
Views
• GUI based Query Builder
• Has its own terminology
• Excels at building
display output.
• Not limited to HTML.
https://commons.wikimedia.org/wiki/File:Tower_Optical_Binoculars.jpg
Fields & Filters
• Fields - the fields to return from the query
• SELECT id, name, birthdate
• Filters - conditions to select items
• WHERE name=“smith”
Contextual Filters
• Apply filters based on external arguments.
• Filter values usually come from the URL path.
• Node ID
• User ID
• Term ID
Relationships
• Add a related table to the base query
• JOIN groups ON (groups.id=users.group_id)
• Can then pull in fields from other entites into
Fields, Filters, and Contexts.
Use an Existing View Programatically.
• views_embed_view(): Useful for building custom blocks
with logic while keeping them configurable in the Views UI.
function mymodule_view() {
$tid = (int) arg(2);
$preferred = views_embed_view('dept_resources', 'block_1', $tid);
// test if the view is empty by looking for view-empty class
if (false !== strpos($preferred, 'class="view-empty"')) {
$all = views_embed_view('dept_resources', 'block_2', $tid);
$block['content'] = $all;
} else {
$block['content'] = $preferred;
}
return $block;
}
Views Hooks
• Views API provides a number of hooks for
changing a view.
• hook_views_pre_view()
• hook_views_pre_ender()
• hook_views_query_alter()
• and more! 

https://api.drupal.org/api/views/views.api.php/group/views_hooks/7
hook_views_pre_view()
• Runs at start of processing. Useful for changing
or cleaning up arguments.
function foo_views_pre_view(&$view, &$display_id, &$args) {
if ('map_legend' == $view->name) {
// get location short name from aliased view pat
// ex. "campus/fairfax-va"
$shortname = parse_path_shortname();
// get the campus node with the matching shortname
$node = foo_campus_lookup_shortname($shortname);
$args[0] = $node->nid;
}
}
hook_views_pre_render()
• Runs at start of rendering.
• Useful for changing titles, adding headers & footers,
replacing placeholders.
function foo_views_pre_render(&$view) {
if ('campus_map' == $view->name) {
if (isset($view->result[0]->nid)) {
$node = $view->result[0]->_field_data['nid']['entity'];
$view->set_title('Campuses for ' . $node->title);
}
return;
}
hook_views_query_alter()
• Alter a query before it runs.
• Helps deal with input edge cases.
function foo_views_query_alter(&$view, &$query) {
if ('campus_contacts' == $view->name) {
if ('mid-state' == arg(2)) {
$query->where[0]['conditions'][0]['value'] = 'Mid-State';
}
}
}
…but Sometimes
• You need to query for a collection of Entities
• In that case, use EntityFieldQuery
• Unless you're reading & writing your own custom
tables, don't use db_query.
function foo_lookup_shortname($short)
{
// now look up the node for this short to make sure it exists
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'campus')
->propertyCondition('status', 1)
->fieldCondition('field_short_name', 'value', $short, '=')
->range(0, 1);
$result = $query->execute();
if (!$result || empty($result)) {
return false;
}
$ids = array_keys($result['node']);
$nodes = node_load_multiple($ids);
$node = array_pop($nodes); // return first
return $node;
}
Writing Custom
Modules
Custom modules for:
• Implementing hooks
• Integration with 3rd party systems
• Custom entities
Use Permissions
• hook_perm defines permissions
• Check for custom permission in routes, views, etc.
• Avoid checking for one or more roles.
/**
* Implements hook_permission().
*/
function foo_email_digest_permission() {
return array(
'administer foo digest' => array(
'title' => t('Administer FOO Digest'),
'description' => t('Manage Digest settings.'),
),
);
}
Use Node Grants
• hook_node_grants
control access to
nodes.
• Control user
access for viewing,
updating, deleting
at the node-level.
• Integrates with
views and search
results.
• https://
www.phase2technolog
y.com/drupal-7-node-
access-grants-locks-
and-keys/
function foo_node_grants($account, $op)
{
$grants = array();
// If a user is an admin then grant access to all
if (user_has_role('Site Admin', $account)) {
$admin_nids = foo_get_workspace_nids();
$grants['workspace_member'] = $admin_nids;
} else {
$ws_nids = foo_get_users_workspace_nids($account);
// add the workspace nodes that the user
// is an owner of too.
$owner_nids = foo_get_owner_workspace_nids($account);
$grants['workspace_member']
= array_merge($ws_nids, $owner_nids);
}
return $grants;
}
Use Node Grants
• hook_node_grants
control access to
nodes.
• Control "realms" that
have access.
• Integrates with
views and search
results.
• https://
www.phase2technology.
com/drupal-7-node-
access-grants-locks-
and-keys/
function foo_node_grants($account, $op)
{
$grants = array();
// If a user is an admin then grant access to all
if (user_has_role('Site Admin', $account)) {
$admin_nids = foo_get_workspace_nids();
$grants['workspace_member'] = $admin_nids;
} else {
$ws_nids = foo_get_users_workspace_nids($account);
// add the workspace nodes that the user
// is an owner of too.
$owner_nids = foo_get_owner_workspace_nids($account);
$grants['workspace_member']
= array_merge($ws_nids, $owner_nids);
}
return $grants;
}
Use Node Grants, pt 2
• hook_node_access
_records control
access to nodes.
• Control user
access for viewing,
updating, deleting
at the node-level.
• Integrates with
views and search
results.
• https://
www.phase2technolog
y.com/drupal-7-node-
access-grants-locks-
and-keys/
function foo_node_access_records($node)
{
// don't clutter grants
if ('resource' !== $node->type) {
return;
}
$ws_nid = $node->field_workspace[LANGUAGE_NONE][0]['target_id'];
if (empty($ws_nid)) {
return;
}
$grants = array();
$grants[] = array (
'realm' => 'workspace_member',
'gid' => $ws_nid,
'grant_view' => 1,
'grant_update' => 0,
'grant_delete' => 0,
'priority' => 0,
);
return $grants;
}
Define custom pages for
your module
/**
* Implements hook_menu().
*/
function foo_email_digest_menu() {
$items['admin/config/system/foo_digest'] = array(
'title' => 'FOO Daily Digest',
'description' => 'Administer FOO Digest settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array('foo_digest_admin'),
'access arguments' => array('administer foo digest'),
'file' => 'foo_email_digest.admin.php',
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
Check Requirements
Use hook_requirements
to check installation
requirements or report
status.
/**
* Implements hook_requirements().
*/
function foo_email_digest_requirements($phase) {
if ('runtime' == $phase) {
$toggle = variable_get('foo_digest_toggle', 'off');
if ('on' == $toggle) {
$requirements['foo_digest_toggle'] = array(
'title' => 'FOO Digest Status',
'value' => check_plain($toggle),
'severity' => REQUIREMENT_OK,
);
} else {
$requirements['foo_digest_toggle'] = array(
'title' => 'FOO Digest Status',
'value' => check_plain($toggle),
'severity' => REQUIREMENT_WARNING,
);
}
Expose tasks via Drush
• Make functionality
available via drush
• http://www.drush.org/en/
master/commands/
• Can then execute
them in Terminal
• easier to schedule
via cron too
/**
* Implements hook_drush_command().
*/
function foo_email_digest_drush_command() {
$items['foo-digest-send'] = array(
'description' => 'Send email digest.',
'aliases' => array('foodig'),
);
return $items;
}
function drush_foo_email_digest_foo_digest_send() {
foo_digest_send();
}
Best Practices
• Create an admin settings form
• Keep editable settings outside of code
• Consider having switches to toggle functionality
on/off
• Provide theme functions
• Themes and other modules can override
rendered display
Key Global Functions
• t()
• check_plain()
• filter_xss
• arg()
• current_path()
• menu_get_item()
• drupal_goto()
• drupal_deny_access()
• get_current_user()
• drupal_message()
t()
• Output a translatable string with replacements
echo t(
"Hello @fname",
array('@fname' => $first_name)
);
check_plain()
• Output sanitized text. Important if you’re taking
user input and displaying it.
echo check_plain(
'<script type="text/javascript">alert("XSS")</script>'
);
filter_xss()
• Output sanitized text, allow some HTML tags. Important if you’re taking user
input and displaying it.
• See also filter_admin_xss()
echo filter_xss(
'<strong>Danger ahead!</strong>
<script type="text/javascript">alert("XSS")</script>'
);
arg()
• Get an argument from the URL path. Remember
to filter input!
// path is "node/$nid"
// first element is arg(0), second is arg(1), etc...
$nid = (int) arg(1);
if (empty($nid) {
trigger_error('NID should be an integer', E_USER_ERROR);
}
current_path()
• Returns the current unaliased path. Useful if a
hook should only run on one or more specific
pages.
if ('node/15' == current_path()) {
// customize this node
}
current_path()
• Returns the current unaliased path or the aliased path for an
internal one.
• Useful if a hook should only run on one or more specific pages.
if ('about' == drupal_get_path_alias()) {
// customize the 'About Us' page
}
$alias = drupal_get_path_alias('node/15');
menu_get_item()
• Returns the currents menu item path. Similar to
current_path, easier to test if something should
only run on a set of pages.
$menu = menu_get_item();
// make sure we're on a user profile page
if ('user/%' !== $menu['path']) {
return
}
drupal_goto()
• Redirect client to another URL. Allows other
modules to rewrite paths.
if (0 == $user->uid) {
drupal_goto('user/login');
}
drupal_deny_access()
• Show an access denied message.if (0 == $user->uid) {
drupal_deny_access();
}
get_current_user()
• Retrieve the user object for the current user.
function foo() {
$user = get_current_user();
if (0 == $user->uid) {
drupal_goto(‘user/login’);
}
}
get_current_user()
• Dont’s use global $user!
function foo() {
ger of overwriting or changing $user
global $user;
$user->uid = 0;
// rest of function continues
}
drupal_messager()
• Display success, warning, or error messages to
client (web or Drush).
function foo() {
= node_load(‘node/‘ . $nid);
… do some stuff to $node
something went wrong
drupal_set_message(
‘Could not use node’,
ning’, // status|warning|error
);
}
Thank You. Questions?
• Follow me @omerida
• Will post slides on slideshare.net
• Editor-in-chief of php[architect]
• Like to write? I want to talk to you!
• Check out http://world.phparch.com

Weitere ähnliche Inhalte

Was ist angesagt?

D2W Stateful Controllers
D2W Stateful ControllersD2W Stateful Controllers
D2W Stateful ControllersWO Community
 
Working with the django admin
Working with the django admin Working with the django admin
Working with the django admin flywindy
 
Web Components v1
Web Components v1Web Components v1
Web Components v1Mike Wilcox
 
Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8Brian Ward
 
The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)Paul Jones
 
Two scoops of django 1.6 - Ch7, Ch8
Two scoops of django 1.6  - Ch7, Ch8Two scoops of django 1.6  - Ch7, Ch8
Two scoops of django 1.6 - Ch7, Ch8flywindy
 
Backbone.js
Backbone.jsBackbone.js
Backbone.jsVO Tho
 
Build Amazing Add-ons for Atlassian JIRA and Confluence
Build Amazing Add-ons for Atlassian JIRA and ConfluenceBuild Amazing Add-ons for Atlassian JIRA and Confluence
Build Amazing Add-ons for Atlassian JIRA and ConfluenceK15t
 
Building and Managing Projects with Maven
Building and Managing Projects with MavenBuilding and Managing Projects with Maven
Building and Managing Projects with MavenKhan625
 
Angular or Backbone: Go Mobile!
Angular or Backbone: Go Mobile!Angular or Backbone: Go Mobile!
Angular or Backbone: Go Mobile!Doris Chen
 
Organinzing Your PHP Projects (2010 Memphis PHP)
Organinzing Your PHP Projects (2010 Memphis PHP)Organinzing Your PHP Projects (2010 Memphis PHP)
Organinzing Your PHP Projects (2010 Memphis PHP)Paul Jones
 
Unit Testing with WOUnit
Unit Testing with WOUnitUnit Testing with WOUnit
Unit Testing with WOUnitWO Community
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-IIIprinceirfancivil
 
jQuery and_drupal
jQuery and_drupaljQuery and_drupal
jQuery and_drupalBlackCatWeb
 
Becoming A Drupal Master Builder
Becoming A Drupal Master BuilderBecoming A Drupal Master Builder
Becoming A Drupal Master BuilderPhilip Norton
 
The Art of AngularJS in 2015 - Angular Summit 2015
The Art of AngularJS in 2015 - Angular Summit 2015The Art of AngularJS in 2015 - Angular Summit 2015
The Art of AngularJS in 2015 - Angular Summit 2015Matt Raible
 
Client-side JavaScript
Client-side JavaScriptClient-side JavaScript
Client-side JavaScriptLilia Sfaxi
 
Learn about Eclipse e4 from Lars Vogel at SF-JUG
Learn about Eclipse e4 from Lars Vogel at SF-JUGLearn about Eclipse e4 from Lars Vogel at SF-JUG
Learn about Eclipse e4 from Lars Vogel at SF-JUGMarakana Inc.
 
Drupal Javascript for developers
Drupal Javascript for developersDrupal Javascript for developers
Drupal Javascript for developersDream Production AG
 

Was ist angesagt? (20)

D2W Stateful Controllers
D2W Stateful ControllersD2W Stateful Controllers
D2W Stateful Controllers
 
Working with the django admin
Working with the django admin Working with the django admin
Working with the django admin
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
 
Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8
 
Backbone js
Backbone jsBackbone js
Backbone js
 
The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)
 
Two scoops of django 1.6 - Ch7, Ch8
Two scoops of django 1.6  - Ch7, Ch8Two scoops of django 1.6  - Ch7, Ch8
Two scoops of django 1.6 - Ch7, Ch8
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Build Amazing Add-ons for Atlassian JIRA and Confluence
Build Amazing Add-ons for Atlassian JIRA and ConfluenceBuild Amazing Add-ons for Atlassian JIRA and Confluence
Build Amazing Add-ons for Atlassian JIRA and Confluence
 
Building and Managing Projects with Maven
Building and Managing Projects with MavenBuilding and Managing Projects with Maven
Building and Managing Projects with Maven
 
Angular or Backbone: Go Mobile!
Angular or Backbone: Go Mobile!Angular or Backbone: Go Mobile!
Angular or Backbone: Go Mobile!
 
Organinzing Your PHP Projects (2010 Memphis PHP)
Organinzing Your PHP Projects (2010 Memphis PHP)Organinzing Your PHP Projects (2010 Memphis PHP)
Organinzing Your PHP Projects (2010 Memphis PHP)
 
Unit Testing with WOUnit
Unit Testing with WOUnitUnit Testing with WOUnit
Unit Testing with WOUnit
 
Building and managing java projects with maven part-III
Building and managing java projects with maven part-IIIBuilding and managing java projects with maven part-III
Building and managing java projects with maven part-III
 
jQuery and_drupal
jQuery and_drupaljQuery and_drupal
jQuery and_drupal
 
Becoming A Drupal Master Builder
Becoming A Drupal Master BuilderBecoming A Drupal Master Builder
Becoming A Drupal Master Builder
 
The Art of AngularJS in 2015 - Angular Summit 2015
The Art of AngularJS in 2015 - Angular Summit 2015The Art of AngularJS in 2015 - Angular Summit 2015
The Art of AngularJS in 2015 - Angular Summit 2015
 
Client-side JavaScript
Client-side JavaScriptClient-side JavaScript
Client-side JavaScript
 
Learn about Eclipse e4 from Lars Vogel at SF-JUG
Learn about Eclipse e4 from Lars Vogel at SF-JUGLearn about Eclipse e4 from Lars Vogel at SF-JUG
Learn about Eclipse e4 from Lars Vogel at SF-JUG
 
Drupal Javascript for developers
Drupal Javascript for developersDrupal Javascript for developers
Drupal Javascript for developers
 

Andere mochten auch

Integration Testing with Behat drupal
Integration Testing with Behat drupalIntegration Testing with Behat drupal
Integration Testing with Behat drupalOscar Merida
 
Publishing alchemy with markdown and pandoc
Publishing alchemy with markdown and pandocPublishing alchemy with markdown and pandoc
Publishing alchemy with markdown and pandocOscar Merida
 
Migrate without migranes
Migrate without migranesMigrate without migranes
Migrate without migranesOscar Merida
 
Piper Oilfield Products
Piper Oilfield ProductsPiper Oilfield Products
Piper Oilfield ProductsChampion5
 
Megan F. Chiriani Portfolio
Megan F. Chiriani PortfolioMegan F. Chiriani Portfolio
Megan F. Chiriani Portfoliomfchiriani
 
台灣人不知道的台灣
台灣人不知道的台灣台灣人不知道的台灣
台灣人不知道的台灣joanlin
 
Logo Design & Identity Package
Logo Design & Identity PackageLogo Design & Identity Package
Logo Design & Identity Packagevirtualchaos
 
How to Evaluate your Technical Partner
How to Evaluate your Technical PartnerHow to Evaluate your Technical Partner
How to Evaluate your Technical PartnerOscar Merida
 
Building with Virtual Development Environments
Building with Virtual Development EnvironmentsBuilding with Virtual Development Environments
Building with Virtual Development EnvironmentsOscar Merida
 
XRL West Kowloon Terminus Construction Photos
XRL West Kowloon Terminus Construction PhotosXRL West Kowloon Terminus Construction Photos
XRL West Kowloon Terminus Construction PhotosRonan Collins
 
Building with Virtual Development Environments
Building with Virtual Development EnvironmentsBuilding with Virtual Development Environments
Building with Virtual Development EnvironmentsOscar Merida
 
Edward de Bono quotes
Edward de Bono quotesEdward de Bono quotes
Edward de Bono quotesErida Prifti
 

Andere mochten auch (16)

Integration Testing with Behat drupal
Integration Testing with Behat drupalIntegration Testing with Behat drupal
Integration Testing with Behat drupal
 
Publishing alchemy with markdown and pandoc
Publishing alchemy with markdown and pandocPublishing alchemy with markdown and pandoc
Publishing alchemy with markdown and pandoc
 
Mit
MitMit
Mit
 
Migrate without migranes
Migrate without migranesMigrate without migranes
Migrate without migranes
 
Piper Oilfield Products
Piper Oilfield ProductsPiper Oilfield Products
Piper Oilfield Products
 
Megan F. Chiriani Portfolio
Megan F. Chiriani PortfolioMegan F. Chiriani Portfolio
Megan F. Chiriani Portfolio
 
台灣人不知道的台灣
台灣人不知道的台灣台灣人不知道的台灣
台灣人不知道的台灣
 
Project
ProjectProject
Project
 
Logo Design & Identity Package
Logo Design & Identity PackageLogo Design & Identity Package
Logo Design & Identity Package
 
How to Evaluate your Technical Partner
How to Evaluate your Technical PartnerHow to Evaluate your Technical Partner
How to Evaluate your Technical Partner
 
Building with Virtual Development Environments
Building with Virtual Development EnvironmentsBuilding with Virtual Development Environments
Building with Virtual Development Environments
 
Hitch yourwagon
Hitch yourwagonHitch yourwagon
Hitch yourwagon
 
XRL West Kowloon Terminus Construction Photos
XRL West Kowloon Terminus Construction PhotosXRL West Kowloon Terminus Construction Photos
XRL West Kowloon Terminus Construction Photos
 
Building with Virtual Development Environments
Building with Virtual Development EnvironmentsBuilding with Virtual Development Environments
Building with Virtual Development Environments
 
Edward de Bono quotes
Edward de Bono quotesEdward de Bono quotes
Edward de Bono quotes
 
Self Review Framework
Self Review FrameworkSelf Review Framework
Self Review Framework
 

Ähnlich wie Staying Sane with Drupal (A Develper's Survival Guide)

Staging Drupal 8 31 09 1 3
Staging Drupal 8 31 09 1 3Staging Drupal 8 31 09 1 3
Staging Drupal 8 31 09 1 3Drupalcon Paris
 
Drupal security
Drupal securityDrupal security
Drupal securityJozef Toth
 
Drupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesDrupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesShabir Ahmad
 
Drupal Security from Drupalcamp Bratislava
Drupal Security from Drupalcamp BratislavaDrupal Security from Drupalcamp Bratislava
Drupal Security from Drupalcamp BratislavaGábor Hojtsy
 
Doing Drupal security right
Doing Drupal security rightDoing Drupal security right
Doing Drupal security rightGábor Hojtsy
 
Your first d8 module
Your first d8 moduleYour first d8 module
Your first d8 moduletedbow
 
13th Sep, Drupal 7 advanced training by TCS
13th Sep, Drupal 7 advanced training by TCS 13th Sep, Drupal 7 advanced training by TCS
13th Sep, Drupal 7 advanced training by TCS DrupalMumbai
 
Creating Modular Test-Driven SPAs with Spring and AngularJS
Creating Modular Test-Driven SPAs with Spring and AngularJSCreating Modular Test-Driven SPAs with Spring and AngularJS
Creating Modular Test-Driven SPAs with Spring and AngularJSGunnar Hillert
 
Top 8 Improvements in Drupal 8
Top 8 Improvements in Drupal 8Top 8 Improvements in Drupal 8
Top 8 Improvements in Drupal 8Angela Byron
 
Doing Drupal security right from Drupalcon London
Doing Drupal security right from Drupalcon LondonDoing Drupal security right from Drupalcon London
Doing Drupal security right from Drupalcon LondonGábor Hojtsy
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingSteven Smith
 
20111110 how puppet-fits_into_your_existing_infrastructure_and_change_managem...
20111110 how puppet-fits_into_your_existing_infrastructure_and_change_managem...20111110 how puppet-fits_into_your_existing_infrastructure_and_change_managem...
20111110 how puppet-fits_into_your_existing_infrastructure_and_change_managem...garrett honeycutt
 
How You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in ProductionHow You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in ProductionBoldRadius Solutions
 
ASP.NET MVC 5 - EF 6 - VS2015
ASP.NET MVC 5 - EF 6 - VS2015ASP.NET MVC 5 - EF 6 - VS2015
ASP.NET MVC 5 - EF 6 - VS2015Hossein Zahed
 
Nagios Conference 2014 - Mike Merideth - The Art and Zen of Managing Nagios w...
Nagios Conference 2014 - Mike Merideth - The Art and Zen of Managing Nagios w...Nagios Conference 2014 - Mike Merideth - The Art and Zen of Managing Nagios w...
Nagios Conference 2014 - Mike Merideth - The Art and Zen of Managing Nagios w...Nagios
 
Get things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplicationsGet things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplicationsGiuliano Iacobelli
 
MVC & SQL_In_1_Hour
MVC & SQL_In_1_HourMVC & SQL_In_1_Hour
MVC & SQL_In_1_HourDilip Patel
 
Magento performance feat. core Hacks
Magento performance feat. core HacksMagento performance feat. core Hacks
Magento performance feat. core HacksDaniel Niedergesäß
 

Ähnlich wie Staying Sane with Drupal (A Develper's Survival Guide) (20)

Staging Drupal 8 31 09 1 3
Staging Drupal 8 31 09 1 3Staging Drupal 8 31 09 1 3
Staging Drupal 8 31 09 1 3
 
Drupal security
Drupal securityDrupal security
Drupal security
 
Drupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesDrupal 8 - Core and API Changes
Drupal 8 - Core and API Changes
 
Drupal Security from Drupalcamp Bratislava
Drupal Security from Drupalcamp BratislavaDrupal Security from Drupalcamp Bratislava
Drupal Security from Drupalcamp Bratislava
 
Doing Drupal security right
Doing Drupal security rightDoing Drupal security right
Doing Drupal security right
 
Your first d8 module
Your first d8 moduleYour first d8 module
Your first d8 module
 
13th Sep, Drupal 7 advanced training by TCS
13th Sep, Drupal 7 advanced training by TCS 13th Sep, Drupal 7 advanced training by TCS
13th Sep, Drupal 7 advanced training by TCS
 
Creating Modular Test-Driven SPAs with Spring and AngularJS
Creating Modular Test-Driven SPAs with Spring and AngularJSCreating Modular Test-Driven SPAs with Spring and AngularJS
Creating Modular Test-Driven SPAs with Spring and AngularJS
 
Top 8 Improvements in Drupal 8
Top 8 Improvements in Drupal 8Top 8 Improvements in Drupal 8
Top 8 Improvements in Drupal 8
 
Doing Drupal security right from Drupalcon London
Doing Drupal security right from Drupalcon LondonDoing Drupal security right from Drupalcon London
Doing Drupal security right from Drupalcon London
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit Testing
 
20111110 how puppet-fits_into_your_existing_infrastructure_and_change_managem...
20111110 how puppet-fits_into_your_existing_infrastructure_and_change_managem...20111110 how puppet-fits_into_your_existing_infrastructure_and_change_managem...
20111110 how puppet-fits_into_your_existing_infrastructure_and_change_managem...
 
Angular js
Angular jsAngular js
Angular js
 
How You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in ProductionHow You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in Production
 
ASP.NET MVC 5 - EF 6 - VS2015
ASP.NET MVC 5 - EF 6 - VS2015ASP.NET MVC 5 - EF 6 - VS2015
ASP.NET MVC 5 - EF 6 - VS2015
 
Nagios Conference 2014 - Mike Merideth - The Art and Zen of Managing Nagios w...
Nagios Conference 2014 - Mike Merideth - The Art and Zen of Managing Nagios w...Nagios Conference 2014 - Mike Merideth - The Art and Zen of Managing Nagios w...
Nagios Conference 2014 - Mike Merideth - The Art and Zen of Managing Nagios w...
 
Get things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplicationsGet things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplications
 
MVC & SQL_In_1_Hour
MVC & SQL_In_1_HourMVC & SQL_In_1_Hour
MVC & SQL_In_1_Hour
 
Magento performance feat. core Hacks
Magento performance feat. core HacksMagento performance feat. core Hacks
Magento performance feat. core Hacks
 
Angular js
Angular jsAngular js
Angular js
 

Kürzlich hochgeladen

WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benonimasabamasaba
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...chiefasafspells
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...masabamasaba
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...masabamasaba
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburgmasabamasaba
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in sowetomasabamasaba
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationJuha-Pekka Tolvanen
 

Kürzlich hochgeladen (20)

WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 

Staying Sane with Drupal (A Develper's Survival Guide)

  • 1. Staying Sane with Drupal A Developer's Survival Guide Oscar Merida, @omerida Drupal GovCon July 2015
  • 2. 80% of building sites with Drupal is configuration (easy) Credit: https://www.flickr.com/photos/jeepersmedia/12953571545/
  • 3. The hard part is the final 20% of customization • Functionality that is new to Drupal • or different than assumptions • Integration with external systems Credit: https://www.flickr.com/photos/jurvetson/15393495039
  • 4. Drupal is procedural • Not Object Oriented • Many structures like nodes, forms, users, etc use StdClass objects or arrays • Not MVC like other PHP frameworks • but there is separation of concerns between menu callbacks & theme layers • Hooks afford a way to alter existing functionality or implement new features. • Leverage hooks
  • 5. Play Well with Others • Don’t short circuit how things work. • If you're stuck, ask for help. • "Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live." • http://c2.com/cgi/wiki? CodeForTheMaintainer
  • 6. Use Existing APIs • EntityFieldQuery • Form API • node_load(), node_presave(), node_* hooks • Node Access System
  • 7. Dig into the Documentation • api.drupal.org has function definitions and examples. • Security - 
 https://www.drupal.org/writing-secure-code • Issue Queues
  • 9. Rule 0: Use VCS • If you're not already using a Version Control System STOP • start using one ASP • Git, Subversion, etc.. • Rule 0.1 - never edit files on live
  • 10. Follow Drupal's coding standard. • Everyone on the team must follow it. • https://www.drupal.org/coding-standards • Don't waste cycles arguing about which standard to follow. • Can use your IDE to follow a standard. • BONUS: Use PHP CodeSniffer to enforce it.
  • 11. Use a Virtual Machine • Use Vagrant to setup a VM for your project • All developers use the same VM (no more "works on my machine) • VM should match stage and production environments. • Same OS, same PHP, same Mysql, etc. • Avoids bugs that only happen on production.
  • 12. Use Features • Drupal saves a lot of configuration to the database, making deployments difficult. • Use Features + Strongarm modules to export settings to Features modules. • Create one Feature module for each Content Type • Include related fields, Views, Display Suite settings, Panels & Pages or Contexts, Path aliases, Rules,etc. • Have a Base module with shared fields and global settings like input formats.
  • 13. Share Features • Track your modules in VCS • When you update codebase, check Features UI for Overrides and resolve them.
  • 14. Use VCS Branches • Isolate new work on new branches. • Merge to master/trunk when ready for testing. • Merge to a stable branch when ready to deploy. • http://www.mediacurrent.com/ blog/git-flow-daily-use https://www.flickr.com/photos/malcolmtredinnick/1516857444
  • 15. Automate Deployments • As simple as having a simple script to sync files to your environments • Or automagically update dev, stage, production by pushing to the correct VCS branch • https://www.freelock.com/node/1108 • BUT remember to keep sensitive information out of VCS (like database credentials).
  • 16. Don't Fear the Command Line • Drush is faster and easier to automate than going through the UI. • Clearing caches - drush cc all • DB Snapshot - drush sql-dump > ../mydb.sql • Creating a user - drush user-create • Reindexing search - drush search-index
  • 17. Contrib makes life easy …except when it doesn’t.
  • 18. Focus on building new solutions. • Avoid “Not-invented-here” syndrome • There's a module for that. In fact, there's probably several … http://dilbert.com/strip/2014-08-11
  • 19. But with great power… • Inherit technical debt of a module • Keep up-to-date with new releases, especially security releases. • Sometimes you don't need a module to change things.
  • 20. Evaluating a module • Does the maintainer have other modules? • Does it have a stable release? • Does it have recent commits? • Is the issue queue active? • Does it have good documentation?
  • 21. Practically core… • Views (is in D8) • Views Bulk Operations • Features & Strongarm • Pathauto & Token • Webform • Rules • Email • Link • Smart Trim • Redirect • Entity Reference • Entity API • Entity Cache
  • 22. Nice to Have • Bean (better Blocks) • Administration Views • Display Suite • Backup & Migrate • Content Locking • Menu Block • Revisioning • Add Another
  • 23. Migration tools • Feeds • or Migrate • Pathologic • Views Data Export
  • 24. Views • GUI based Query Builder • Has its own terminology • Excels at building display output. • Not limited to HTML. https://commons.wikimedia.org/wiki/File:Tower_Optical_Binoculars.jpg
  • 25. Fields & Filters • Fields - the fields to return from the query • SELECT id, name, birthdate • Filters - conditions to select items • WHERE name=“smith”
  • 26. Contextual Filters • Apply filters based on external arguments. • Filter values usually come from the URL path. • Node ID • User ID • Term ID
  • 27. Relationships • Add a related table to the base query • JOIN groups ON (groups.id=users.group_id) • Can then pull in fields from other entites into Fields, Filters, and Contexts.
  • 28. Use an Existing View Programatically. • views_embed_view(): Useful for building custom blocks with logic while keeping them configurable in the Views UI. function mymodule_view() { $tid = (int) arg(2); $preferred = views_embed_view('dept_resources', 'block_1', $tid); // test if the view is empty by looking for view-empty class if (false !== strpos($preferred, 'class="view-empty"')) { $all = views_embed_view('dept_resources', 'block_2', $tid); $block['content'] = $all; } else { $block['content'] = $preferred; } return $block; }
  • 29. Views Hooks • Views API provides a number of hooks for changing a view. • hook_views_pre_view() • hook_views_pre_ender() • hook_views_query_alter() • and more! 
 https://api.drupal.org/api/views/views.api.php/group/views_hooks/7
  • 30. hook_views_pre_view() • Runs at start of processing. Useful for changing or cleaning up arguments. function foo_views_pre_view(&$view, &$display_id, &$args) { if ('map_legend' == $view->name) { // get location short name from aliased view pat // ex. "campus/fairfax-va" $shortname = parse_path_shortname(); // get the campus node with the matching shortname $node = foo_campus_lookup_shortname($shortname); $args[0] = $node->nid; } }
  • 31. hook_views_pre_render() • Runs at start of rendering. • Useful for changing titles, adding headers & footers, replacing placeholders. function foo_views_pre_render(&$view) { if ('campus_map' == $view->name) { if (isset($view->result[0]->nid)) { $node = $view->result[0]->_field_data['nid']['entity']; $view->set_title('Campuses for ' . $node->title); } return; }
  • 32. hook_views_query_alter() • Alter a query before it runs. • Helps deal with input edge cases. function foo_views_query_alter(&$view, &$query) { if ('campus_contacts' == $view->name) { if ('mid-state' == arg(2)) { $query->where[0]['conditions'][0]['value'] = 'Mid-State'; } } }
  • 33. …but Sometimes • You need to query for a collection of Entities • In that case, use EntityFieldQuery • Unless you're reading & writing your own custom tables, don't use db_query.
  • 34. function foo_lookup_shortname($short) { // now look up the node for this short to make sure it exists $query = new EntityFieldQuery(); $query->entityCondition('entity_type', 'node') ->entityCondition('bundle', 'campus') ->propertyCondition('status', 1) ->fieldCondition('field_short_name', 'value', $short, '=') ->range(0, 1); $result = $query->execute(); if (!$result || empty($result)) { return false; } $ids = array_keys($result['node']); $nodes = node_load_multiple($ids); $node = array_pop($nodes); // return first return $node; }
  • 36. Custom modules for: • Implementing hooks • Integration with 3rd party systems • Custom entities
  • 37. Use Permissions • hook_perm defines permissions • Check for custom permission in routes, views, etc. • Avoid checking for one or more roles. /** * Implements hook_permission(). */ function foo_email_digest_permission() { return array( 'administer foo digest' => array( 'title' => t('Administer FOO Digest'), 'description' => t('Manage Digest settings.'), ), ); }
  • 38. Use Node Grants • hook_node_grants control access to nodes. • Control user access for viewing, updating, deleting at the node-level. • Integrates with views and search results. • https:// www.phase2technolog y.com/drupal-7-node- access-grants-locks- and-keys/ function foo_node_grants($account, $op) { $grants = array(); // If a user is an admin then grant access to all if (user_has_role('Site Admin', $account)) { $admin_nids = foo_get_workspace_nids(); $grants['workspace_member'] = $admin_nids; } else { $ws_nids = foo_get_users_workspace_nids($account); // add the workspace nodes that the user // is an owner of too. $owner_nids = foo_get_owner_workspace_nids($account); $grants['workspace_member'] = array_merge($ws_nids, $owner_nids); } return $grants; }
  • 39. Use Node Grants • hook_node_grants control access to nodes. • Control "realms" that have access. • Integrates with views and search results. • https:// www.phase2technology. com/drupal-7-node- access-grants-locks- and-keys/ function foo_node_grants($account, $op) { $grants = array(); // If a user is an admin then grant access to all if (user_has_role('Site Admin', $account)) { $admin_nids = foo_get_workspace_nids(); $grants['workspace_member'] = $admin_nids; } else { $ws_nids = foo_get_users_workspace_nids($account); // add the workspace nodes that the user // is an owner of too. $owner_nids = foo_get_owner_workspace_nids($account); $grants['workspace_member'] = array_merge($ws_nids, $owner_nids); } return $grants; }
  • 40. Use Node Grants, pt 2 • hook_node_access _records control access to nodes. • Control user access for viewing, updating, deleting at the node-level. • Integrates with views and search results. • https:// www.phase2technolog y.com/drupal-7-node- access-grants-locks- and-keys/ function foo_node_access_records($node) { // don't clutter grants if ('resource' !== $node->type) { return; } $ws_nid = $node->field_workspace[LANGUAGE_NONE][0]['target_id']; if (empty($ws_nid)) { return; } $grants = array(); $grants[] = array ( 'realm' => 'workspace_member', 'gid' => $ws_nid, 'grant_view' => 1, 'grant_update' => 0, 'grant_delete' => 0, 'priority' => 0, ); return $grants; }
  • 41. Define custom pages for your module /** * Implements hook_menu(). */ function foo_email_digest_menu() { $items['admin/config/system/foo_digest'] = array( 'title' => 'FOO Daily Digest', 'description' => 'Administer FOO Digest settings.', 'page callback' => 'drupal_get_form', 'page arguments' => array('foo_digest_admin'), 'access arguments' => array('administer foo digest'), 'file' => 'foo_email_digest.admin.php', 'type' => MENU_NORMAL_ITEM, ); return $items; }
  • 42. Check Requirements Use hook_requirements to check installation requirements or report status. /** * Implements hook_requirements(). */ function foo_email_digest_requirements($phase) { if ('runtime' == $phase) { $toggle = variable_get('foo_digest_toggle', 'off'); if ('on' == $toggle) { $requirements['foo_digest_toggle'] = array( 'title' => 'FOO Digest Status', 'value' => check_plain($toggle), 'severity' => REQUIREMENT_OK, ); } else { $requirements['foo_digest_toggle'] = array( 'title' => 'FOO Digest Status', 'value' => check_plain($toggle), 'severity' => REQUIREMENT_WARNING, ); }
  • 43. Expose tasks via Drush • Make functionality available via drush • http://www.drush.org/en/ master/commands/ • Can then execute them in Terminal • easier to schedule via cron too /** * Implements hook_drush_command(). */ function foo_email_digest_drush_command() { $items['foo-digest-send'] = array( 'description' => 'Send email digest.', 'aliases' => array('foodig'), ); return $items; } function drush_foo_email_digest_foo_digest_send() { foo_digest_send(); }
  • 44. Best Practices • Create an admin settings form • Keep editable settings outside of code • Consider having switches to toggle functionality on/off • Provide theme functions • Themes and other modules can override rendered display
  • 45. Key Global Functions • t() • check_plain() • filter_xss • arg() • current_path() • menu_get_item() • drupal_goto() • drupal_deny_access() • get_current_user() • drupal_message()
  • 46. t() • Output a translatable string with replacements echo t( "Hello @fname", array('@fname' => $first_name) );
  • 47. check_plain() • Output sanitized text. Important if you’re taking user input and displaying it. echo check_plain( '<script type="text/javascript">alert("XSS")</script>' );
  • 48. filter_xss() • Output sanitized text, allow some HTML tags. Important if you’re taking user input and displaying it. • See also filter_admin_xss() echo filter_xss( '<strong>Danger ahead!</strong> <script type="text/javascript">alert("XSS")</script>' );
  • 49. arg() • Get an argument from the URL path. Remember to filter input! // path is "node/$nid" // first element is arg(0), second is arg(1), etc... $nid = (int) arg(1); if (empty($nid) { trigger_error('NID should be an integer', E_USER_ERROR); }
  • 50. current_path() • Returns the current unaliased path. Useful if a hook should only run on one or more specific pages. if ('node/15' == current_path()) { // customize this node }
  • 51. current_path() • Returns the current unaliased path or the aliased path for an internal one. • Useful if a hook should only run on one or more specific pages. if ('about' == drupal_get_path_alias()) { // customize the 'About Us' page } $alias = drupal_get_path_alias('node/15');
  • 52. menu_get_item() • Returns the currents menu item path. Similar to current_path, easier to test if something should only run on a set of pages. $menu = menu_get_item(); // make sure we're on a user profile page if ('user/%' !== $menu['path']) { return }
  • 53. drupal_goto() • Redirect client to another URL. Allows other modules to rewrite paths. if (0 == $user->uid) { drupal_goto('user/login'); }
  • 54. drupal_deny_access() • Show an access denied message.if (0 == $user->uid) { drupal_deny_access(); }
  • 55. get_current_user() • Retrieve the user object for the current user. function foo() { $user = get_current_user(); if (0 == $user->uid) { drupal_goto(‘user/login’); } }
  • 56. get_current_user() • Dont’s use global $user! function foo() { ger of overwriting or changing $user global $user; $user->uid = 0; // rest of function continues }
  • 57. drupal_messager() • Display success, warning, or error messages to client (web or Drush). function foo() { = node_load(‘node/‘ . $nid); … do some stuff to $node something went wrong drupal_set_message( ‘Could not use node’, ning’, // status|warning|error ); }
  • 58. Thank You. Questions? • Follow me @omerida • Will post slides on slideshare.net • Editor-in-chief of php[architect] • Like to write? I want to talk to you! • Check out http://world.phparch.com