SlideShare a Scribd company logo
Add-On Development:
 EE Expects that Every
Developer will do his Duty
          Paul Burdick, Lead Developer
                    solspace
   http://solspace.com/downloads/eeci2009/presentation.txt
Summary of Talk
•   What are Add-Ons?
    •   The Three Types of Add-Ons in EE
    •   Overview of Accessories in EE 2.x
•   Add-On Development Skills
•   Developing Add-Ons in ExpressionEngine
•   Writing Code
•   Debugging & Improving Performance
Summary of Talk
•   What are Add-Ons?
    •   The Three Types of Add-Ons in EE
    •   Overview of Accessories in EE 2.x
•   Add-On Development Skills
•   Developing Add-Ons in ExpressionEngine
•   Writing Code
•   Debugging & Improving Performance
I.
What are Add-Ons?
Three Types of Add-Ons in
      EE 1.x and 2.x

        • Extensions
        • Modules
        • Plugins
Extensions
• Extends the base functionality of
  ExpressionEngine

• Allows developers to interpose their own
  code into EE's codebase.

• Restrained by where hooks are placed in
  the code and what arguments are sent with
  the extension call
• More and more Third Party developers are
  adding hooks to their own code, allowing
  extensions for Third Party Add-Ons. Pretty
  darn cool.

• Typically no DB tables, but there are always
  exceptions

• Settings Form CP
function settings()
{
	   $settings = array();
	
	   $settings['butter']     = "Quite Tasty";
	   $settings['buttery']    = array('r', array('yes' => "yes", 'no' => "no"), 'no');
	
	   // Complex:
	   // [variable_name] => array(type, values, default value)
	   // variable_name => short name for setting and key for language file variable
	   // types:	   t - textarea
	   //	 	    	   r - radio buttons
	   //	 	    	   s - select
	   //	 	    	   ms - multiselect
	   //	 	    	   f - function calls
	   // values: can be array (r, s, ms), string (t), function name (f)
	   // default: name of array member, string, nothing
	   //
	   // Simple:
	   // [variable_name] => 'Butter'
	   // Text input, with 'Butter' as the default.
	
	   return $settings;
}
presentation
Modules
• The Mighty Workhorses of EE
• Complete and expansive Control Panels.
• Database Tables
• Template Tags
• Own extensions possible
Plugins
• No settings, no tables, no CP, no install
• Text manipulation either via Template Tags
  or Custom Fields

• Or, functionality "plugged" into your
  Templates.
Add-On Quantities @ devot-ee.com
            18 October 2009




                              Extensions:   170
                              Modules:      73
                              Plugins:      248
Examples of Extensions
•   Edit Tab AJAX - AJAX enabled search for
    Control Panel's Edit area

•   FieldFrame - Easily create new custom field
    types for ExpressionEngine.

•   LG Add Sitename - Site Label in upper left of
    your CP
Examples of Modules
•   Structure - Create Static and Listing pages,
    editable via a tree sitemap

•   Tag - Folksonomy functionality for Weblog and
    Gallery Entries

•   User - EE's Member Functionality in Templates
Examples of Plugins
•   EE Gravatar - Global Avatars for site members

•   Image Sizer - Resizes and caches images on the
    fly

•   Markdown - Markdown formatting in EE
    Custom Weblog Fields
Accessories
 in EE 2.0
•   Accessories provide tools, references, or
    abilities at the bottom of your EE Control
    Panel in ExpressionEngine 2.0

•   No CP page for each Accessory

•   Can have own DB tables

•   View files! Lovely lovely View files!
presentation
II.
    Add-On
Development Skills
PHP
• Duh...
• PHP: Hypertext Preprocessor. You really
  have to love recursive acronyms.

• Server side programming language.
  Processed at runtime.

• No Compiling! Viewable Source!
• PHP files contain code, but they can also
  have HTML, JS, XML, et cetera inside them.

• Extremely widespread on hosting
  environments.
PHP Learning References

PHP Docs: http://php.net/manual/

W3C Tutorial: http://www.w3schools.com/PHP/php_intro.asp

Zend Tutorial: http://devzone.zend.com/article/627
SQL
• Required for advanced Add-On development
• Active Record only *helps* build queries
MySQL
•   Popular, open-source, relational database.

•   Simple to setup and administrate.

•   Fast for reading, decent for writing

•   Dominant on hosted environments
MySQL Learning References
 •   MySQL Docs: http://dev.mysql.com/doc/

 •   Buy a book. ( O'Reilly Books are well done )

 •   Learn JOINs

     •   http://www.informit.com/articles/article.aspx?
         p=30875&seqNum=5

     •   http://en.wikipedia.org/wiki/Join_(SQL)
HTML/CSS
View Files
•   Essentially HTML files with PHP inside for
    outputting data

•   Part of ExpressionEngine 2.0 by default

•   Available in ExpressionEngine1.x using Hermes
    or custom include code
<?php echo $this->view('header.html');?>
	
<h4 class="alertHeadingCenter"><?php echo $LANG->line('error');?></h4>

<div class='defaultCenter' >
	   <div class="box">
	   	    <strong><?=$error_message?></strong>
	   	    	   <br /><br />
	   	    <strong>
	   	    	   <a href='javascript:history.go(-1)'>&#171; <?=$LANG->line('back')?></a>
	   	    </strong>
	   </div>
</div>
	
<?php echo $this->view('footer.html'); ?>
User Interfaces
•   Build in static HTML, CSS, JS files before converting
    to View files.

•   Easier development.

•   Easier bug testing.

•   No need to create data variables/objects first.

•   UI developer does not need to understand PHP.
jQuery/JavaScript
• jQuery available in EE 1.x via an extension
  (not enabled by default)

• jQuery available in EE 2.x with no additional
  work

• Relatively easy to add other libraries or
  custom JS if need be.
global $EXT;

if ( ! isset($EXT->version_numbers['Cp_jquery']))
{
	   return $OUT->show_user_error('general', $LANG->line('cp_jquery_requred')));
}
III.
Developing Add-Ons
in ExpressionEngine
Never, Ever Just
 Start Coding!
presentation
Research
• Previous Approaches
• Required Features
• Alternative Approach in ExpressionEngine?
 •   Can this be done in EE in any other way?

 •   Is a Module required? Could an Extension do it?

 •   Could a Plugin output weblog data in the way you
     need?
Tell a Story
•   How will Person A do Task 1?

•   Question Previous Approaches.

    •   Is X Really the BEST way to do it?

    •   What Would Apple Do?

•   Eliminate Steps, Make Process Intuitive.

•   Follow your instincts.
Map Out Features
• Major
 •   Functionality required for module to serve
     its market/purpose
• Minor
 •   Not Necessarily Required.
 •   Features are cuttable for a 1.0 release.
• Icing
 •   For specific clients or users
 •   Think and consider them
Database Structure
• Tables for your Major and Minor Features
• Normalization: Eliminate Data Duplication
  • http://en.wikipedia.org/wiki/Database_normalization
• Indexes!
• Specific, Sensical Field Names
  • 'event_title' vs 'event'
  • 'event_short_name' vs 'name'
Tags Structure
•   The Naming and Functionality of Template tags
•   For Each Tag
    •   Describe
    •   Name
    •   Parameters
    •   Variable Pairs and Single Variables
•   Consider this a precursor to your documentation
Tags Structure: Describe

•   Descriptions for each Tag, Parameter, and Variable.
•   Explain what each one does.
Tags Structure: Tag Name

•   Simple and Obvious
•   No Abbreviations, No Ambiguity
    •   {exp:module:g_entries} vs
        {exp:module:gallery_entries}
Tags Structure: Parameters

•   Prefix?
    •   form:id="" or form_id=""
•   Use prefixes to break up parameters into
    "groups" of functionality.
    •   notify:admin_email=""
    •   notify:user_email=""
Tags Structure: Variables
•   No Ambiguity, No Abbreviations
    •   {group}{/group} vs
        {category_group}{/category_group}
    •   {title} vs {event_title}
•   Prevent collisions in nested tags
•   Underscores recommended
Tags Structure:
    Show to Other People

•   Get Feedback
•   Revise until the Spec feels solid.
Building a
Control Panel
Workflow Module’s CP
Control Panel:
        Break Up into Sections
•   Data Adding, Deleting, and Manipulation
    •   Create/Modify/Delete Items
    •   Ex: Calendar, Wiki, Forum
    •   Build only one main interface
•   Preferences/Settings/Permissions
    •   Per Site, Per Weblog, Per Member Group, Per X
•   Actions
    •   Ex: Recount, Re-Cache, Clear Caches
•   Version Number and Documentation Link
KISS:
Keep It Simple, Stupid
Control Panel: Design
•   Build an HTML/CSS/JS mockup first
•   Put into a View file
•   PHP into HTML, Not HTML into PHP
    •   documentDOM in Hermes - Builds HTML in
        PHP, specifically form fields
•   Ignore IE6
    •   EE 2.x no longer supports it
    •   Solspace no longer supports it
    •   Neither should you.
Time Wasted on IE6
Making Software Support IE6   vs.   Upgrading Users
Time Wasted on IE6
Making Software Support IE6   vs.        Upgrading Users




            92%                     8%
Have Goals,
Even Milestones,
Never Deadlines
IV.
Writing Code
Follow the EllisLab
        Development Guidelines!

http://expressionengine.com/docs/development/guidelines/index.html
"Prolific and informative commenting
    using proper comment style"

 •   We want to know your thinking! Why this way?
 •   Expect people to learn from your code.
 •   Helps you understand your *own* logic
Sanitize and Escape Everything
•   Be Paranoid! Nothing is Immune! Constant
    Vigilance!

•   If you DID NOT set or get data yourself, assume
    it is tainted, even EE variables

•   If you DID set or get yourself, but not within ten
    lines of code, assume it is tainted.

•   Sanitize and Escape at the Query

•   No Security Exceptions for SuperAdmins
Abstraction

•   Use Twice, Write Once
•   Create Libraries!
•   Reduces Work and Mistakes
•   Purpose of Hermes
Simplify,
Simplify,
Simplify
Simplify: Reduce Code Work
 •   Do the Least Amount of Effort to produce results
 •   Bail Out First, Work Second
     •   Invalid variable type? Bail.
     •   No Permissions? Bail.
     •   Error? Bail.
 •   Don’t Do Serious Work Until You Know You Have
     Work To Do
Simplify: Reduce DB Work
•   Performing Multiple Queries are OK.
•   Validate, Check Pagination, Then Retrieve Data
Simplify: Models
•   Abstract common SELECTs into separate methods
•   INSERTs/UPDATEs for a DB Table in one method
•   Hermes has per Add-On model caching caching
    built into it.
•   Speaking of caching...
Per Page Load Caching
•   Use $SESS->cache
•       Suggested:
    •    $SESS->cache['modules']['module_name']['some_cache'] = array();

•   Alternative:
    •    $SESS->cache['Solspace']['module_name']['some_cache'] = array()

•   Try a Reference!
    •    $this->cache =& $SESS->cache['modules']['module_name'];
    •    $this->cache[‘some_cache’] = array();
Weblog Module Class
• Very powerful code, no need to write your own.
• Code was written so that it could be used elsewhere.
• Returns Results based on tag parameters
• You can modify $TMPL->tagparams!
require_once PATH_CORE.'core.typography'.EXT;
require_once PATH_MOD.'/weblog/mod.weblog'.EXT;

$TMPL->tagparams['entry_id']	   = '1|2|3|4';
$TMPL->tagparams['dynamic']	
                           	    = 'off';

$TMPL->tagdata	    = $TMPL->assign_relationship_data( $TMPL->tagdata );
$TMPL->var_single	 = array_merge( $TMPL->var_single, $TMPL->related_markers );

$weblog_object = new Weblog;

$weblog_object->fetch_custom_weblog_fields();
$weblog_object->fetch_custom_member_fields();
$weblog_object->fetch_pagination_data();
$weblog_object->create_pagination();
$weblog_object->build_sql_query();

if ($weblog_object->sql == '') return $this->return_data = $TMPL->no_results();

$weblog_object->query = $DB->query($weblog_object->sql);

if ($weblog_object->query->num_rows == 0) return $this->return_data = $TMPL->no_results();

$weblog_object->TYPE = new Typography;

$weblog_object->fetch_categories();
$weblog_object->parse_weblog_entries();
$weblog_object->add_pagination_data();

return $this->return_data = $weblog_object->return_data;
Provide Tools for Keeping
      Things Tidy
• Removal of Old Data.
• Removal of Old Caches
• Optimize Tables - Reduce DB Overhead
V.
   Debugging and
Improving Performance
Consider Performance
an Aspect of Add-On
     Debugging
Turn on PHP Debugging
• Insure Display Errors Setting is On in php.ini
• Error Reporting is E_ALL
• No PHP Errors! Ever!
• Remove All Deprecated PHP Functions.
Turn on SQL Queries
• Admin => System Preferences => Output and Debugging
• Queries appear on both CP and User side of EE
• Review Queries
  • Check the Add-On's CP
  • Extensions: Check areas of usage in CP
  • Check EVERY single tag in a Template.
• Eliminate Duplicates!
Turn on SQL Queries
• Are Certain Queries Necessary on EVERY load?
  • Settings/Preferences
  • Caching (Checks, Re-caching, Emptying)
  • Statistics
• Evaluate Queries for Performance
• Run in phpMyAdmin or similar
• Try Making the Query More Efficient
  • Add a WHERE clause on indexed field
  • Remove Extraneous JOINs when possible
Turn on SQL Queries
•   De-Normalization.
    •   Duplicating Data or Grouping It to Reduce Work
    •   http://en.wikipedia.org/wiki/Denormalization
    •   Best example? Statistics: Hit count.
    •   Abstract methods for data consistency (i.e. correct
        values)
• Learn About Optimizing MySQL
  • MySQL Performance Blog
  • http://mysqlperformanceblog.com
SuperSearch SQL Queries
Turn on Template Debugging
 • Admin => System Preferences => Output and Debugging
 • Outputs Elapsed Time during Add-On processing
 • What Code is Taking the Longest to Process?
 • $TMPL->log_item()
   • $TMPL->log_item('Freeform Module: Run Query');
 • Disable Processing
   • Disable Parameter ( disable="feng_shui" )
   • Auto-detect Variables and Remove Queries and
     Processing
Vanilla Template Log
SuperSearch Processing
Knowing is Half the Battle!
Automated Actions
• Example: Caching or Retrieving Remote Data
• Can Seriously Slow Down an Add-On
• Try AJAX
Deprecated Code
• Consider using trigger_error()
• trigger_error('Favorites Module: The Favorites Count
  tag has been deprecated. Use the Entry Count tag
  instead');
• Don't Leave It Around Forever, Discontinue Support,
  Then Remove It
Ask for Help
• Plenty of EE, PHP, SQL Knowledge out there. Use it.
• Often just discussing a problem will lead to a solution.
V.
Presentation Over, So
      Let's Talk
Ad

More Related Content

What's hot (19)

JMP402 Master Class: Managed beans and XPages: Your Time Is Now
JMP402 Master Class: Managed beans and XPages: Your Time Is NowJMP402 Master Class: Managed beans and XPages: Your Time Is Now
JMP402 Master Class: Managed beans and XPages: Your Time Is Now
Russell Maher
 
Custom Development with Novell Teaming
Custom Development with Novell TeamingCustom Development with Novell Teaming
Custom Development with Novell Teaming
Novell
 
How to Prepare a WordPress Theme for Public Release
How to Prepare a WordPress Theme for Public ReleaseHow to Prepare a WordPress Theme for Public Release
How to Prepare a WordPress Theme for Public Release
David Yeiser
 
Vibe Custom Development
Vibe Custom DevelopmentVibe Custom Development
Vibe Custom Development
GWAVA
 
Extension developer secrets - How to make money with Joomla
Extension developer secrets - How to make money with JoomlaExtension developer secrets - How to make money with Joomla
Extension developer secrets - How to make money with Joomla
Tim Plummer
 
Drupal 8 theming deep dive
Drupal 8 theming deep diveDrupal 8 theming deep dive
Drupal 8 theming deep dive
Romain Jarraud
 
State of play for Joomla - Nov 2014
State of play for Joomla - Nov 2014State of play for Joomla - Nov 2014
State of play for Joomla - Nov 2014
Tim Plummer
 
Introduction to building joomla! components using FOF
Introduction to building joomla! components using FOFIntroduction to building joomla! components using FOF
Introduction to building joomla! components using FOF
Tim Plummer
 
Wordpress theme submission requirement for Themeforest
Wordpress theme submission requirement for ThemeforestWordpress theme submission requirement for Themeforest
Wordpress theme submission requirement for Themeforest
Enayet Rajib
 
The things we found in your website
The things we found in your websiteThe things we found in your website
The things we found in your website
hernanibf
 
BP-9 Share Customization Best Practices
BP-9 Share Customization Best PracticesBP-9 Share Customization Best Practices
BP-9 Share Customization Best Practices
Alfresco Software
 
Starting WordPress Theme Review
Starting WordPress Theme ReviewStarting WordPress Theme Review
Starting WordPress Theme Review
Catch Themes
 
Browser Developer Tools for APEX Developers
Browser Developer Tools for APEX DevelopersBrowser Developer Tools for APEX Developers
Browser Developer Tools for APEX Developers
Christian Rokitta
 
Creating a Great XPages User Interface, TLCC Teamstudio Webinar - Feb, 2014
Creating a Great XPages User Interface, TLCC Teamstudio Webinar - Feb, 2014Creating a Great XPages User Interface, TLCC Teamstudio Webinar - Feb, 2014
Creating a Great XPages User Interface, TLCC Teamstudio Webinar - Feb, 2014
Howard Greenberg
 
44 Slides About 22 Modules
44 Slides About 22 Modules44 Slides About 22 Modules
44 Slides About 22 Modules
heyrocker
 
Oxford DrupalCamp 2012 - The things we found in your website
Oxford DrupalCamp 2012 - The things we found in your websiteOxford DrupalCamp 2012 - The things we found in your website
Oxford DrupalCamp 2012 - The things we found in your website
hernanibf
 
WordPress Theme Development Basics
WordPress Theme Development BasicsWordPress Theme Development Basics
WordPress Theme Development Basics
Tech Liminal
 
WordPress Themes 101 - dotEduGuru Summit 2013
WordPress Themes 101 - dotEduGuru Summit 2013WordPress Themes 101 - dotEduGuru Summit 2013
WordPress Themes 101 - dotEduGuru Summit 2013
Curtiss Grymala
 
Ant User Guide
Ant User GuideAnt User Guide
Ant User Guide
Muthuselvam RS
 
JMP402 Master Class: Managed beans and XPages: Your Time Is Now
JMP402 Master Class: Managed beans and XPages: Your Time Is NowJMP402 Master Class: Managed beans and XPages: Your Time Is Now
JMP402 Master Class: Managed beans and XPages: Your Time Is Now
Russell Maher
 
Custom Development with Novell Teaming
Custom Development with Novell TeamingCustom Development with Novell Teaming
Custom Development with Novell Teaming
Novell
 
How to Prepare a WordPress Theme for Public Release
How to Prepare a WordPress Theme for Public ReleaseHow to Prepare a WordPress Theme for Public Release
How to Prepare a WordPress Theme for Public Release
David Yeiser
 
Vibe Custom Development
Vibe Custom DevelopmentVibe Custom Development
Vibe Custom Development
GWAVA
 
Extension developer secrets - How to make money with Joomla
Extension developer secrets - How to make money with JoomlaExtension developer secrets - How to make money with Joomla
Extension developer secrets - How to make money with Joomla
Tim Plummer
 
Drupal 8 theming deep dive
Drupal 8 theming deep diveDrupal 8 theming deep dive
Drupal 8 theming deep dive
Romain Jarraud
 
State of play for Joomla - Nov 2014
State of play for Joomla - Nov 2014State of play for Joomla - Nov 2014
State of play for Joomla - Nov 2014
Tim Plummer
 
Introduction to building joomla! components using FOF
Introduction to building joomla! components using FOFIntroduction to building joomla! components using FOF
Introduction to building joomla! components using FOF
Tim Plummer
 
Wordpress theme submission requirement for Themeforest
Wordpress theme submission requirement for ThemeforestWordpress theme submission requirement for Themeforest
Wordpress theme submission requirement for Themeforest
Enayet Rajib
 
The things we found in your website
The things we found in your websiteThe things we found in your website
The things we found in your website
hernanibf
 
BP-9 Share Customization Best Practices
BP-9 Share Customization Best PracticesBP-9 Share Customization Best Practices
BP-9 Share Customization Best Practices
Alfresco Software
 
Starting WordPress Theme Review
Starting WordPress Theme ReviewStarting WordPress Theme Review
Starting WordPress Theme Review
Catch Themes
 
Browser Developer Tools for APEX Developers
Browser Developer Tools for APEX DevelopersBrowser Developer Tools for APEX Developers
Browser Developer Tools for APEX Developers
Christian Rokitta
 
Creating a Great XPages User Interface, TLCC Teamstudio Webinar - Feb, 2014
Creating a Great XPages User Interface, TLCC Teamstudio Webinar - Feb, 2014Creating a Great XPages User Interface, TLCC Teamstudio Webinar - Feb, 2014
Creating a Great XPages User Interface, TLCC Teamstudio Webinar - Feb, 2014
Howard Greenberg
 
44 Slides About 22 Modules
44 Slides About 22 Modules44 Slides About 22 Modules
44 Slides About 22 Modules
heyrocker
 
Oxford DrupalCamp 2012 - The things we found in your website
Oxford DrupalCamp 2012 - The things we found in your websiteOxford DrupalCamp 2012 - The things we found in your website
Oxford DrupalCamp 2012 - The things we found in your website
hernanibf
 
WordPress Theme Development Basics
WordPress Theme Development BasicsWordPress Theme Development Basics
WordPress Theme Development Basics
Tech Liminal
 
WordPress Themes 101 - dotEduGuru Summit 2013
WordPress Themes 101 - dotEduGuru Summit 2013WordPress Themes 101 - dotEduGuru Summit 2013
WordPress Themes 101 - dotEduGuru Summit 2013
Curtiss Grymala
 

Viewers also liked (7)

bcgr3-jquery
bcgr3-jquerybcgr3-jquery
bcgr3-jquery
tutorialsruby
 
phpTutorial1
phpTutorial1phpTutorial1
phpTutorial1
tutorialsruby
 
flash-flv
flash-flvflash-flv
flash-flv
tutorialsruby
 
annotation_tutorial_2008
annotation_tutorial_2008annotation_tutorial_2008
annotation_tutorial_2008
tutorialsruby
 
collapsible-panels-tutorial
collapsible-panels-tutorialcollapsible-panels-tutorial
collapsible-panels-tutorial
tutorialsruby
 
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting &lt;b>...&lt;/b>
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting &lt;b>...&lt;/b>The Art Institute of Atlanta IMD 210 Fundamentals of Scripting &lt;b>...&lt;/b>
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting &lt;b>...&lt;/b>
tutorialsruby
 
TopStyle Help &amp; &lt;b>Tutorial&lt;/b>
TopStyle Help &amp; &lt;b>Tutorial&lt;/b>TopStyle Help &amp; &lt;b>Tutorial&lt;/b>
TopStyle Help &amp; &lt;b>Tutorial&lt;/b>
tutorialsruby
 
annotation_tutorial_2008
annotation_tutorial_2008annotation_tutorial_2008
annotation_tutorial_2008
tutorialsruby
 
collapsible-panels-tutorial
collapsible-panels-tutorialcollapsible-panels-tutorial
collapsible-panels-tutorial
tutorialsruby
 
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting &lt;b>...&lt;/b>
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting &lt;b>...&lt;/b>The Art Institute of Atlanta IMD 210 Fundamentals of Scripting &lt;b>...&lt;/b>
The Art Institute of Atlanta IMD 210 Fundamentals of Scripting &lt;b>...&lt;/b>
tutorialsruby
 
TopStyle Help &amp; &lt;b>Tutorial&lt;/b>
TopStyle Help &amp; &lt;b>Tutorial&lt;/b>TopStyle Help &amp; &lt;b>Tutorial&lt;/b>
TopStyle Help &amp; &lt;b>Tutorial&lt;/b>
tutorialsruby
 
Ad

Similar to presentation (20)

Best Practices for Building WordPress Applications
Best Practices for Building WordPress ApplicationsBest Practices for Building WordPress Applications
Best Practices for Building WordPress Applications
Taylor Lovett
 
Yapc10 Cdt World Domination
Yapc10   Cdt World DominationYapc10   Cdt World Domination
Yapc10 Cdt World Domination
cPanel
 
Best Practices for WordPress
Best Practices for WordPressBest Practices for WordPress
Best Practices for WordPress
Taylor Lovett
 
Professional Help for PowerShell Modules
Professional Help for PowerShell ModulesProfessional Help for PowerShell Modules
Professional Help for PowerShell Modules
June Blender
 
Beyond Domino Designer
Beyond Domino DesignerBeyond Domino Designer
Beyond Domino Designer
Paul Withers
 
5 Common Mistakes You are Making on your Website
 5 Common Mistakes You are Making on your Website 5 Common Mistakes You are Making on your Website
5 Common Mistakes You are Making on your Website
Acquia
 
Building Rich Internet Applications with Ext JS
Building Rich Internet Applications  with Ext JSBuilding Rich Internet Applications  with Ext JS
Building Rich Internet Applications with Ext JS
Mats Bryntse
 
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
Anupam Ranku
 
50 Shades of Fail KScope16
50 Shades of Fail KScope1650 Shades of Fail KScope16
50 Shades of Fail KScope16
Christian Berg
 
How To Use Selenium Successfully
How To Use Selenium SuccessfullyHow To Use Selenium Successfully
How To Use Selenium Successfully
Dave Haeffner
 
How to Use Selenium, Successfully
How to Use Selenium, SuccessfullyHow to Use Selenium, Successfully
How to Use Selenium, Successfully
Sauce Labs
 
Codeigniter
CodeigniterCodeigniter
Codeigniter
Joram Salinas
 
JSLink for ITPros - SharePoint Saturday Jersey
JSLink for ITPros - SharePoint Saturday JerseyJSLink for ITPros - SharePoint Saturday Jersey
JSLink for ITPros - SharePoint Saturday Jersey
Paul Hunt
 
Extjs3.4 Migration Notes
Extjs3.4 Migration NotesExtjs3.4 Migration Notes
Extjs3.4 Migration Notes
SimoAmi
 
Miami2015
Miami2015Miami2015
Miami2015
DevinVinson
 
Writing Your First Plugin
Writing Your First PluginWriting Your First Plugin
Writing Your First Plugin
George Ornbo
 
Intro to ExpressionEngine and CodeIgniter
Intro to ExpressionEngine and CodeIgniterIntro to ExpressionEngine and CodeIgniter
Intro to ExpressionEngine and CodeIgniter
brightrocket
 
DMann-SQLDeveloper4Reporting
DMann-SQLDeveloper4ReportingDMann-SQLDeveloper4Reporting
DMann-SQLDeveloper4Reporting
David Mann
 
Sterling for Windows Phone 7
Sterling for Windows Phone 7Sterling for Windows Phone 7
Sterling for Windows Phone 7
Jeremy Likness
 
Best practices-wordpress-enterprise
Best practices-wordpress-enterpriseBest practices-wordpress-enterprise
Best practices-wordpress-enterprise
Taylor Lovett
 
Best Practices for Building WordPress Applications
Best Practices for Building WordPress ApplicationsBest Practices for Building WordPress Applications
Best Practices for Building WordPress Applications
Taylor Lovett
 
Yapc10 Cdt World Domination
Yapc10   Cdt World DominationYapc10   Cdt World Domination
Yapc10 Cdt World Domination
cPanel
 
Best Practices for WordPress
Best Practices for WordPressBest Practices for WordPress
Best Practices for WordPress
Taylor Lovett
 
Professional Help for PowerShell Modules
Professional Help for PowerShell ModulesProfessional Help for PowerShell Modules
Professional Help for PowerShell Modules
June Blender
 
Beyond Domino Designer
Beyond Domino DesignerBeyond Domino Designer
Beyond Domino Designer
Paul Withers
 
5 Common Mistakes You are Making on your Website
 5 Common Mistakes You are Making on your Website 5 Common Mistakes You are Making on your Website
5 Common Mistakes You are Making on your Website
Acquia
 
Building Rich Internet Applications with Ext JS
Building Rich Internet Applications  with Ext JSBuilding Rich Internet Applications  with Ext JS
Building Rich Internet Applications with Ext JS
Mats Bryntse
 
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
Office 365 Saturday (Sydney) - SharePoint framework – build integrated user e...
Anupam Ranku
 
50 Shades of Fail KScope16
50 Shades of Fail KScope1650 Shades of Fail KScope16
50 Shades of Fail KScope16
Christian Berg
 
How To Use Selenium Successfully
How To Use Selenium SuccessfullyHow To Use Selenium Successfully
How To Use Selenium Successfully
Dave Haeffner
 
How to Use Selenium, Successfully
How to Use Selenium, SuccessfullyHow to Use Selenium, Successfully
How to Use Selenium, Successfully
Sauce Labs
 
JSLink for ITPros - SharePoint Saturday Jersey
JSLink for ITPros - SharePoint Saturday JerseyJSLink for ITPros - SharePoint Saturday Jersey
JSLink for ITPros - SharePoint Saturday Jersey
Paul Hunt
 
Extjs3.4 Migration Notes
Extjs3.4 Migration NotesExtjs3.4 Migration Notes
Extjs3.4 Migration Notes
SimoAmi
 
Writing Your First Plugin
Writing Your First PluginWriting Your First Plugin
Writing Your First Plugin
George Ornbo
 
Intro to ExpressionEngine and CodeIgniter
Intro to ExpressionEngine and CodeIgniterIntro to ExpressionEngine and CodeIgniter
Intro to ExpressionEngine and CodeIgniter
brightrocket
 
DMann-SQLDeveloper4Reporting
DMann-SQLDeveloper4ReportingDMann-SQLDeveloper4Reporting
DMann-SQLDeveloper4Reporting
David Mann
 
Sterling for Windows Phone 7
Sterling for Windows Phone 7Sterling for Windows Phone 7
Sterling for Windows Phone 7
Jeremy Likness
 
Best practices-wordpress-enterprise
Best practices-wordpress-enterpriseBest practices-wordpress-enterprise
Best practices-wordpress-enterprise
Taylor Lovett
 
Ad

More from tutorialsruby (20)

&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />
tutorialsruby
 
&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />
tutorialsruby
 
&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />
tutorialsruby
 
Standardization and Knowledge Transfer – INS0
Standardization and Knowledge Transfer – INS0Standardization and Knowledge Transfer – INS0
Standardization and Knowledge Transfer – INS0
tutorialsruby
 
xhtml_basics
xhtml_basicsxhtml_basics
xhtml_basics
tutorialsruby
 
xhtml_basics
xhtml_basicsxhtml_basics
xhtml_basics
tutorialsruby
 
xhtml-documentation
xhtml-documentationxhtml-documentation
xhtml-documentation
tutorialsruby
 
xhtml-documentation
xhtml-documentationxhtml-documentation
xhtml-documentation
tutorialsruby
 
CSS
CSSCSS
CSS
tutorialsruby
 
CSS
CSSCSS
CSS
tutorialsruby
 
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa0602690047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
tutorialsruby
 
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa0602690047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
tutorialsruby
 
HowTo_CSS
HowTo_CSSHowTo_CSS
HowTo_CSS
tutorialsruby
 
HowTo_CSS
HowTo_CSSHowTo_CSS
HowTo_CSS
tutorialsruby
 
BloggingWithStyle_2008
BloggingWithStyle_2008BloggingWithStyle_2008
BloggingWithStyle_2008
tutorialsruby
 
BloggingWithStyle_2008
BloggingWithStyle_2008BloggingWithStyle_2008
BloggingWithStyle_2008
tutorialsruby
 
cascadingstylesheets
cascadingstylesheetscascadingstylesheets
cascadingstylesheets
tutorialsruby
 
cascadingstylesheets
cascadingstylesheetscascadingstylesheets
cascadingstylesheets
tutorialsruby
 
Winter%200405%20-%20Advanced%20Javascript
Winter%200405%20-%20Advanced%20JavascriptWinter%200405%20-%20Advanced%20Javascript
Winter%200405%20-%20Advanced%20Javascript
tutorialsruby
 
Winter%200405%20-%20Advanced%20Javascript
Winter%200405%20-%20Advanced%20JavascriptWinter%200405%20-%20Advanced%20Javascript
Winter%200405%20-%20Advanced%20Javascript
tutorialsruby
 
&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />
tutorialsruby
 
&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />
tutorialsruby
 
&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />
tutorialsruby
 
Standardization and Knowledge Transfer – INS0
Standardization and Knowledge Transfer – INS0Standardization and Knowledge Transfer – INS0
Standardization and Knowledge Transfer – INS0
tutorialsruby
 
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa0602690047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
tutorialsruby
 
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa0602690047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
0047ecaa6ea3e9ac0a13a2fe96f4de3bfd515c88f5d90c1fae79b956363d7f02c7fa060269
tutorialsruby
 
BloggingWithStyle_2008
BloggingWithStyle_2008BloggingWithStyle_2008
BloggingWithStyle_2008
tutorialsruby
 
BloggingWithStyle_2008
BloggingWithStyle_2008BloggingWithStyle_2008
BloggingWithStyle_2008
tutorialsruby
 
cascadingstylesheets
cascadingstylesheetscascadingstylesheets
cascadingstylesheets
tutorialsruby
 
cascadingstylesheets
cascadingstylesheetscascadingstylesheets
cascadingstylesheets
tutorialsruby
 
Winter%200405%20-%20Advanced%20Javascript
Winter%200405%20-%20Advanced%20JavascriptWinter%200405%20-%20Advanced%20Javascript
Winter%200405%20-%20Advanced%20Javascript
tutorialsruby
 
Winter%200405%20-%20Advanced%20Javascript
Winter%200405%20-%20Advanced%20JavascriptWinter%200405%20-%20Advanced%20Javascript
Winter%200405%20-%20Advanced%20Javascript
tutorialsruby
 

Recently uploaded (20)

Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven InsightsAndrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven InsightsAndrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell: Transforming Business Strategy Through Data-Driven Insights
Andrew Marnell
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
Semantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AISemantic Cultivators : The Critical Future Role to Enable AI
Semantic Cultivators : The Critical Future Role to Enable AI
artmondano
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...What is Model Context Protocol(MCP) - The new technology for communication bw...
What is Model Context Protocol(MCP) - The new technology for communication bw...
Vishnu Singh Chundawat
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 

presentation

  • 1. Add-On Development: EE Expects that Every Developer will do his Duty Paul Burdick, Lead Developer solspace http://solspace.com/downloads/eeci2009/presentation.txt
  • 2. Summary of Talk • What are Add-Ons? • The Three Types of Add-Ons in EE • Overview of Accessories in EE 2.x • Add-On Development Skills • Developing Add-Ons in ExpressionEngine • Writing Code • Debugging & Improving Performance
  • 3. Summary of Talk • What are Add-Ons? • The Three Types of Add-Ons in EE • Overview of Accessories in EE 2.x • Add-On Development Skills • Developing Add-Ons in ExpressionEngine • Writing Code • Debugging & Improving Performance
  • 5. Three Types of Add-Ons in EE 1.x and 2.x • Extensions • Modules • Plugins
  • 7. • Extends the base functionality of ExpressionEngine • Allows developers to interpose their own code into EE's codebase. • Restrained by where hooks are placed in the code and what arguments are sent with the extension call
  • 8. • More and more Third Party developers are adding hooks to their own code, allowing extensions for Third Party Add-Ons. Pretty darn cool. • Typically no DB tables, but there are always exceptions • Settings Form CP
  • 9. function settings() { $settings = array(); $settings['butter'] = "Quite Tasty"; $settings['buttery'] = array('r', array('yes' => "yes", 'no' => "no"), 'no'); // Complex: // [variable_name] => array(type, values, default value) // variable_name => short name for setting and key for language file variable // types: t - textarea // r - radio buttons // s - select // ms - multiselect // f - function calls // values: can be array (r, s, ms), string (t), function name (f) // default: name of array member, string, nothing // // Simple: // [variable_name] => 'Butter' // Text input, with 'Butter' as the default. return $settings; }
  • 12. • The Mighty Workhorses of EE • Complete and expansive Control Panels. • Database Tables • Template Tags • Own extensions possible
  • 14. • No settings, no tables, no CP, no install • Text manipulation either via Template Tags or Custom Fields • Or, functionality "plugged" into your Templates.
  • 15. Add-On Quantities @ devot-ee.com 18 October 2009 Extensions: 170 Modules: 73 Plugins: 248
  • 16. Examples of Extensions • Edit Tab AJAX - AJAX enabled search for Control Panel's Edit area • FieldFrame - Easily create new custom field types for ExpressionEngine. • LG Add Sitename - Site Label in upper left of your CP
  • 17. Examples of Modules • Structure - Create Static and Listing pages, editable via a tree sitemap • Tag - Folksonomy functionality for Weblog and Gallery Entries • User - EE's Member Functionality in Templates
  • 18. Examples of Plugins • EE Gravatar - Global Avatars for site members • Image Sizer - Resizes and caches images on the fly • Markdown - Markdown formatting in EE Custom Weblog Fields
  • 20. Accessories provide tools, references, or abilities at the bottom of your EE Control Panel in ExpressionEngine 2.0 • No CP page for each Accessory • Can have own DB tables • View files! Lovely lovely View files!
  • 22. II. Add-On Development Skills
  • 23. PHP
  • 24. • Duh... • PHP: Hypertext Preprocessor. You really have to love recursive acronyms. • Server side programming language. Processed at runtime. • No Compiling! Viewable Source!
  • 25. • PHP files contain code, but they can also have HTML, JS, XML, et cetera inside them. • Extremely widespread on hosting environments.
  • 26. PHP Learning References PHP Docs: http://php.net/manual/ W3C Tutorial: http://www.w3schools.com/PHP/php_intro.asp Zend Tutorial: http://devzone.zend.com/article/627
  • 27. SQL
  • 28. • Required for advanced Add-On development • Active Record only *helps* build queries
  • 29. MySQL • Popular, open-source, relational database. • Simple to setup and administrate. • Fast for reading, decent for writing • Dominant on hosted environments
  • 30. MySQL Learning References • MySQL Docs: http://dev.mysql.com/doc/ • Buy a book. ( O'Reilly Books are well done ) • Learn JOINs • http://www.informit.com/articles/article.aspx? p=30875&seqNum=5 • http://en.wikipedia.org/wiki/Join_(SQL)
  • 32. View Files • Essentially HTML files with PHP inside for outputting data • Part of ExpressionEngine 2.0 by default • Available in ExpressionEngine1.x using Hermes or custom include code
  • 33. <?php echo $this->view('header.html');?> <h4 class="alertHeadingCenter"><?php echo $LANG->line('error');?></h4> <div class='defaultCenter' > <div class="box"> <strong><?=$error_message?></strong> <br /><br /> <strong> <a href='javascript:history.go(-1)'>&#171; <?=$LANG->line('back')?></a> </strong> </div> </div> <?php echo $this->view('footer.html'); ?>
  • 34. User Interfaces • Build in static HTML, CSS, JS files before converting to View files. • Easier development. • Easier bug testing. • No need to create data variables/objects first. • UI developer does not need to understand PHP.
  • 36. • jQuery available in EE 1.x via an extension (not enabled by default) • jQuery available in EE 2.x with no additional work • Relatively easy to add other libraries or custom JS if need be.
  • 37. global $EXT; if ( ! isset($EXT->version_numbers['Cp_jquery'])) { return $OUT->show_user_error('general', $LANG->line('cp_jquery_requred'))); }
  • 39. Never, Ever Just Start Coding!
  • 41. Research • Previous Approaches • Required Features • Alternative Approach in ExpressionEngine? • Can this be done in EE in any other way? • Is a Module required? Could an Extension do it? • Could a Plugin output weblog data in the way you need?
  • 42. Tell a Story • How will Person A do Task 1? • Question Previous Approaches. • Is X Really the BEST way to do it? • What Would Apple Do? • Eliminate Steps, Make Process Intuitive. • Follow your instincts.
  • 43. Map Out Features • Major • Functionality required for module to serve its market/purpose • Minor • Not Necessarily Required. • Features are cuttable for a 1.0 release. • Icing • For specific clients or users • Think and consider them
  • 44. Database Structure • Tables for your Major and Minor Features • Normalization: Eliminate Data Duplication • http://en.wikipedia.org/wiki/Database_normalization • Indexes! • Specific, Sensical Field Names • 'event_title' vs 'event' • 'event_short_name' vs 'name'
  • 45. Tags Structure • The Naming and Functionality of Template tags • For Each Tag • Describe • Name • Parameters • Variable Pairs and Single Variables • Consider this a precursor to your documentation
  • 46. Tags Structure: Describe • Descriptions for each Tag, Parameter, and Variable. • Explain what each one does.
  • 47. Tags Structure: Tag Name • Simple and Obvious • No Abbreviations, No Ambiguity • {exp:module:g_entries} vs {exp:module:gallery_entries}
  • 48. Tags Structure: Parameters • Prefix? • form:id="" or form_id="" • Use prefixes to break up parameters into "groups" of functionality. • notify:admin_email="" • notify:user_email=""
  • 49. Tags Structure: Variables • No Ambiguity, No Abbreviations • {group}{/group} vs {category_group}{/category_group} • {title} vs {event_title} • Prevent collisions in nested tags • Underscores recommended
  • 50. Tags Structure: Show to Other People • Get Feedback • Revise until the Spec feels solid.
  • 53. Control Panel: Break Up into Sections • Data Adding, Deleting, and Manipulation • Create/Modify/Delete Items • Ex: Calendar, Wiki, Forum • Build only one main interface • Preferences/Settings/Permissions • Per Site, Per Weblog, Per Member Group, Per X • Actions • Ex: Recount, Re-Cache, Clear Caches • Version Number and Documentation Link
  • 55. Control Panel: Design • Build an HTML/CSS/JS mockup first • Put into a View file • PHP into HTML, Not HTML into PHP • documentDOM in Hermes - Builds HTML in PHP, specifically form fields • Ignore IE6 • EE 2.x no longer supports it • Solspace no longer supports it • Neither should you.
  • 56. Time Wasted on IE6 Making Software Support IE6 vs. Upgrading Users
  • 57. Time Wasted on IE6 Making Software Support IE6 vs. Upgrading Users 92% 8%
  • 60. Follow the EllisLab Development Guidelines! http://expressionengine.com/docs/development/guidelines/index.html
  • 61. "Prolific and informative commenting using proper comment style" • We want to know your thinking! Why this way? • Expect people to learn from your code. • Helps you understand your *own* logic
  • 62. Sanitize and Escape Everything • Be Paranoid! Nothing is Immune! Constant Vigilance! • If you DID NOT set or get data yourself, assume it is tainted, even EE variables • If you DID set or get yourself, but not within ten lines of code, assume it is tainted. • Sanitize and Escape at the Query • No Security Exceptions for SuperAdmins
  • 63. Abstraction • Use Twice, Write Once • Create Libraries! • Reduces Work and Mistakes • Purpose of Hermes
  • 65. Simplify: Reduce Code Work • Do the Least Amount of Effort to produce results • Bail Out First, Work Second • Invalid variable type? Bail. • No Permissions? Bail. • Error? Bail. • Don’t Do Serious Work Until You Know You Have Work To Do
  • 66. Simplify: Reduce DB Work • Performing Multiple Queries are OK. • Validate, Check Pagination, Then Retrieve Data
  • 67. Simplify: Models • Abstract common SELECTs into separate methods • INSERTs/UPDATEs for a DB Table in one method • Hermes has per Add-On model caching caching built into it. • Speaking of caching...
  • 68. Per Page Load Caching • Use $SESS->cache • Suggested: • $SESS->cache['modules']['module_name']['some_cache'] = array(); • Alternative: • $SESS->cache['Solspace']['module_name']['some_cache'] = array() • Try a Reference! • $this->cache =& $SESS->cache['modules']['module_name']; • $this->cache[‘some_cache’] = array();
  • 69. Weblog Module Class • Very powerful code, no need to write your own. • Code was written so that it could be used elsewhere. • Returns Results based on tag parameters • You can modify $TMPL->tagparams!
  • 70. require_once PATH_CORE.'core.typography'.EXT; require_once PATH_MOD.'/weblog/mod.weblog'.EXT; $TMPL->tagparams['entry_id'] = '1|2|3|4'; $TMPL->tagparams['dynamic'] = 'off'; $TMPL->tagdata = $TMPL->assign_relationship_data( $TMPL->tagdata ); $TMPL->var_single = array_merge( $TMPL->var_single, $TMPL->related_markers ); $weblog_object = new Weblog; $weblog_object->fetch_custom_weblog_fields(); $weblog_object->fetch_custom_member_fields(); $weblog_object->fetch_pagination_data(); $weblog_object->create_pagination(); $weblog_object->build_sql_query(); if ($weblog_object->sql == '') return $this->return_data = $TMPL->no_results(); $weblog_object->query = $DB->query($weblog_object->sql); if ($weblog_object->query->num_rows == 0) return $this->return_data = $TMPL->no_results(); $weblog_object->TYPE = new Typography; $weblog_object->fetch_categories(); $weblog_object->parse_weblog_entries(); $weblog_object->add_pagination_data(); return $this->return_data = $weblog_object->return_data;
  • 71. Provide Tools for Keeping Things Tidy • Removal of Old Data. • Removal of Old Caches • Optimize Tables - Reduce DB Overhead
  • 72. V. Debugging and Improving Performance
  • 73. Consider Performance an Aspect of Add-On Debugging
  • 74. Turn on PHP Debugging • Insure Display Errors Setting is On in php.ini • Error Reporting is E_ALL • No PHP Errors! Ever! • Remove All Deprecated PHP Functions.
  • 75. Turn on SQL Queries • Admin => System Preferences => Output and Debugging • Queries appear on both CP and User side of EE • Review Queries • Check the Add-On's CP • Extensions: Check areas of usage in CP • Check EVERY single tag in a Template. • Eliminate Duplicates!
  • 76. Turn on SQL Queries • Are Certain Queries Necessary on EVERY load? • Settings/Preferences • Caching (Checks, Re-caching, Emptying) • Statistics • Evaluate Queries for Performance • Run in phpMyAdmin or similar • Try Making the Query More Efficient • Add a WHERE clause on indexed field • Remove Extraneous JOINs when possible
  • 77. Turn on SQL Queries • De-Normalization. • Duplicating Data or Grouping It to Reduce Work • http://en.wikipedia.org/wiki/Denormalization • Best example? Statistics: Hit count. • Abstract methods for data consistency (i.e. correct values) • Learn About Optimizing MySQL • MySQL Performance Blog • http://mysqlperformanceblog.com
  • 79. Turn on Template Debugging • Admin => System Preferences => Output and Debugging • Outputs Elapsed Time during Add-On processing • What Code is Taking the Longest to Process? • $TMPL->log_item() • $TMPL->log_item('Freeform Module: Run Query'); • Disable Processing • Disable Parameter ( disable="feng_shui" ) • Auto-detect Variables and Remove Queries and Processing
  • 82. Knowing is Half the Battle!
  • 83. Automated Actions • Example: Caching or Retrieving Remote Data • Can Seriously Slow Down an Add-On • Try AJAX
  • 84. Deprecated Code • Consider using trigger_error() • trigger_error('Favorites Module: The Favorites Count tag has been deprecated. Use the Entry Count tag instead'); • Don't Leave It Around Forever, Discontinue Support, Then Remove It
  • 85. Ask for Help • Plenty of EE, PHP, SQL Knowledge out there. Use it. • Often just discussing a problem will lead to a solution.