WORDPRESS WORKFLOW
FOR AN AGENCY WORLD
INTRODUCTION
This course will be opinionated.
This course expects people to already have some familiarity with wordpress concepts and development
This approach tends toward the overly simplistic (from a structure point of view), so implement additional structural elements as you
feel suits your workflow.
There’s no one size fits all. The techniques I’m teaching here suit most projects in an agency small to mid website world, but you’ll need
to use your judgement and experience to know what to use and when.
This approach doesn’t suit building and selling wordpress themes (as we don’t try to make the themes generic). We’re building these
sites based around a pre-defined design and ux structure.
OVERVIEW OF TOPICS
Wordpress setup and common plugins
Theme structure
Git/versioning methodology
Naming conventions
Custom post type vs repeater in page template
Setting up the list page for a custom post type
Custom field groups
Menus
Options page
Separate theme front-end code from CMS logic
WORDPRESS SETUP AND COMMON PLUGINS
Download and install the latest version of wordpress from https://wordpress.org/
Make sure the table prefix isn’t wp_ (security reasons)
Make sure the administrator user isn’t admin (security reasons)
Install common plugins
iThemes Security (https://wordpress.org/plugins/better-wp-security/). Configure later.
ACF (https://wordpress.org/plugins/advanced-custom-fields/). We’ll be using the pro version.
Custom Post Type UI (https://wordpress.org/plugins/custom-post-type-ui/)
Yeost (https://wordpress.org/plugins/wordpress-seo/)
Adminize (https://wordpress.org/plugins/adminimize/)
Remove additional unnecessary themes
THEME STRUCTURE
This course assumes that you’ve already setup the frontend of the site.
Copy the frontend build of the site into a new theme folder in /wp-content/themes and make the following changes:
Add style.css with theme comment (see https://codex.wordpress.org/Theme_Development#Theme_Stylesheet). The details that
you enter should be the client’s details and not reference the agency
Add functions.php
Prefix all static resources with “<?php echo get_template_directory_uri(); ?>/”
Add wp_head() into the header.
Disable the emojicons (http://wordpress.stackexchange.com/questions/185577/disable-emojicons-introduced-with-wp-4-2)
Add a “classes” folder that will hold the php helper classes
Add the custom template header to all custom pages
GIT METHODOLOGY
We’ll work in a branch called “wordpress” rather than the “master” branch. We’ll only merge back to the master branch once we’re going
to deploy the build to to the live site. There should also be a branch called “frontend” which should hold the templates prior to CMS
integration.
Make an export of the database and include this into the git repo as well. Update this each time you make changes to custom fields or
db structure.
Make commits with each feature that’s submitted. The commit name should be a clear description of what’s been added.
The git repo naming convention is {end-client}-{site-domain-without-extension}
NAMING CONVENTIONS
File naming: All lowercase, hyphen to separate words, avoid acronyms or abbreviations. When naming a template, try to describe the
structure of the template, not the name of the page it’ll go with (ie generic-text.php rather than about.php). The exception to this is
the homepage.
Folder naming: All lowercase, hyphen to separate words, avoid acronyms or abbreviations.
CSS naming: This will be covered in a separate course, but we follow the BEM CSS naming convention (http://getbem.com/naming/)
For custom post types in the CMS, naming should be plural and sentence case and ids should be lowercase and _ to separate words (ie
label: “Products”, id: “products”)
For custom fields, labels should be descriptive and sentence case, field id should be lowercase and _ to separate words (ie label:
“Discount code”, id: “discount_code”). When nested (as in a repeater or flexible content block), don’t repeat the block name in the
name of the element (ie for a repeatable carousel “slider_image” - BAD “image” - GOOD)
CUSTOM POST TYPE VS REPEATER IN PAGE TEMPLATE
QUESTIONS TO ASK YOURSELF
Are the items going to be listed in more than one page on the site?
Are there any categories/taxonomies required for the items?
Is it something that clearly stands out as it’s own type of object rather than a part of a page (eg products, news items)?
Is it very important to the site overall (ie would the cms user be likely to be using it quite a bit and want to be able to get to it and edit it
quickly)?
Will there need to be a reference to the items (ACF relationship field) in other sections of the CMS?
If you answered yes to any of the above, then consider setting up a custom post type, otherwise, use a repeater in the page template.
SETTING UP THE LIST PAGE FOR A CUSTOM POST TYPE
The standard way for displaying the list of items from a custom post type is to use the {post-slug}-archive.php template. The downside of
using this technique is:
You can’t have any additional custom fields for the page, unless you create a new tab in the “Site settings” section, which isn’t a great
user experience for an administrator.
You can’t change the page url
The preferred method is to turn off the archive for the custom post type, and then create a custom page template that lists all the post type
items. This means that you can also create a custom field group that is associated with the page, which makes it more intuitive for the
admin as they just search for the page and edit the custom fields.
CUSTOM FIELDS GROUPS
Apply field groups to either a custom post type or a custom template, never directly to a page (there are exceptions to this)
At the bottom of the field group, ensure you hide any standard fields that aren’t necessary
Try to break down the field groups in such a way that you can reuse them in multiple places (eg Create separate carousel custom field
group if it will apply to several templates rather than recreating the carousel custom fields in multiple groups)
This is the place to be creative. Don’t be too literal, try to think a little more abstract. If elements are similar, likely they can use a single
custom field group with optional elements.
WYSIWYG fields should only ever be used for rich text (h1-h6, links, bold, underline etc). Turn off the media option for WYSIWYG’s.
Ensure the order of the fields is as logical as possible and replicates the order they will appear on the site
If you’ve got a custom field that will be a link to either an internal page or external site, please use a structure that has radio buttons for
internal or external link, and if internal, show relationship field to select page, if external, show url field and target dropdown
Get to understand some of the more advanced setup features, like conditional display and wrapper attributes
(http://support.advancedcustomfields.com/forums/topic/how-to-use-wrapper-attributes/). They’ll help you to make the CMS
MENUS
Use Appearance > Menus to create the menus required for the site.
Even if it’s not outlined in the design, if you can allow for multiple levels in the nav, please do as it’ll make the build more flexible
OPTIONS PAGE
There are going to be some global elements that need to be content managed, and some elements that just don’t fit anywhere else. This is
where the ACF options page comes in handy (see http://www.advancedcustomfields.com/add-ons/options-page/). A common name to call
this in the CMS is “Site settings”. Note that we’ll be hiding the wordpress settings from the end-user so this shouldn’t cause confusion (only
admin will be able to see settings).
A few notes on usage:
Ideally separate the options page into tabs. Each tab represents a different logical area of the site (eg header, footer, contact form)
Don’t go crazy with it. Only setup elements that you expect the admin to use.
SEPARATE THEME FRONT-END CODE FROM CMS LOGIC
Create php classes (in the “classes” folder) for each custom post type, each custom page template (which ideally inherits from a page
class)
All templates will then instantiate the correct class and use methods to get the data they need
The benefits of this are:
Cleaner, more easy to read front-end code
Separation of data/logic and display (not quite model/view/controller but closer ;)
Easier to setup an api from these classes if we decide to
FORMS. VALIDATION, SUBMISSION & STORAGE
Validation library of choice is http://www.formvalidator.net/
Unless there’s a specific reason, submit forms via ajax
As a safety net, unless it’s just a simple contact form, create a custom post type for it and store form submissions as well as emailing
the client
The details of any emails sent from the form should be able to be content managed in the “Site settings” section of the cms. Things like
the email address(s) to send to, email subject, copy etc.
To avoid spamming, make sure that we have either a honeypot or captcha
USER LOGIN AREAS
Wordpress users should be reserved for backend users. If the site has a user login, create a custom post type for the users rather than
using the default wordpress users. There are a few reasons for this:
If you use default wordpress users, you will need to implement hacks to make sure they don’t have access to the wordpress
admin
If you log in as the CMS admin user, it will show you logged onto the front-end (again, hacks required to get around this)
Conceptually, it’s cleaner to have this separation
If you’ve got a custom post type for users, there’s a few things to keep in mind
Hash the user password
KEEPING SECURITY AND SEO IN MIND
One of the major detractors for wordpress is it’s security. We’ve likely all had wordpress sites hacked in the past, but it’s not difficult to do
the basics of securing them.
Redirect all non-https traffic to https if you have ssl
Complete as many of the iThemes Security recommendations as possible
If it’s possible, lock the /wp-admin folder to only the ip addresses that are required (yours and the clients)
SEO will often be in the client’s hands. If you’ve installed Yeost, make sure to flag to the client that they’ll need to populate the fields.
WHEN TO SETUP CUSTOM DB TABLES
The default table structure of wordpress is very flexible, but not very well optimised for large data sets. All the custom fields are stored in
the wp_meta table as key value pairs. This means that it can be a hassle to manage content directly if needed and also slow for complex
queries.
If you have very large data sets or you need quick queries, consider creating a custom plugin that will create the db table(s) and setup the
admin interface (https://codex.wordpress.org/Creating_Tables_with_Plugins).
CLEANUP
Before sending the build to the client to review, make sure you:
Create a new wordpress user for the client
Use adminize to hide any menu items that the client doesn’t need to see
Remove all testing users and testing content
Hide any fields in custom post types or templates that aren’t needed
Hide Yeost SEO fields from anything that doesn’t display as a page on the site. You can do this from SEO > titles & meta
FINAL NOTES / CHECKLIST
Does your staging/development version of the site have search engine visibility discouraged, and the live version has this option turned
off?
Do you have a 404 page setup?
Has google analytics been implemented?
Do you have ssl? If so, are you redirecting all non-https traffic to https (including www)?
Have you got a favicon?
Always try to look at the CMS like you were the user. They should only see what they need to see.
Please don’t EVER expect the user to know html to be able to manage the content
No matter what the user does in the cms, they shouldn’t be able to make the site look broken
Make sure that all wordpress user passwords are unique and proper passwords (no admin / admin please)

Wordpress workflow for an agency world

  • 1.
  • 2.
    INTRODUCTION This course willbe opinionated. This course expects people to already have some familiarity with wordpress concepts and development This approach tends toward the overly simplistic (from a structure point of view), so implement additional structural elements as you feel suits your workflow. There’s no one size fits all. The techniques I’m teaching here suit most projects in an agency small to mid website world, but you’ll need to use your judgement and experience to know what to use and when. This approach doesn’t suit building and selling wordpress themes (as we don’t try to make the themes generic). We’re building these sites based around a pre-defined design and ux structure.
  • 3.
    OVERVIEW OF TOPICS Wordpresssetup and common plugins Theme structure Git/versioning methodology Naming conventions Custom post type vs repeater in page template Setting up the list page for a custom post type Custom field groups Menus Options page Separate theme front-end code from CMS logic
  • 4.
    WORDPRESS SETUP ANDCOMMON PLUGINS Download and install the latest version of wordpress from https://wordpress.org/ Make sure the table prefix isn’t wp_ (security reasons) Make sure the administrator user isn’t admin (security reasons) Install common plugins iThemes Security (https://wordpress.org/plugins/better-wp-security/). Configure later. ACF (https://wordpress.org/plugins/advanced-custom-fields/). We’ll be using the pro version. Custom Post Type UI (https://wordpress.org/plugins/custom-post-type-ui/) Yeost (https://wordpress.org/plugins/wordpress-seo/) Adminize (https://wordpress.org/plugins/adminimize/) Remove additional unnecessary themes
  • 5.
    THEME STRUCTURE This courseassumes that you’ve already setup the frontend of the site. Copy the frontend build of the site into a new theme folder in /wp-content/themes and make the following changes: Add style.css with theme comment (see https://codex.wordpress.org/Theme_Development#Theme_Stylesheet). The details that you enter should be the client’s details and not reference the agency Add functions.php Prefix all static resources with “<?php echo get_template_directory_uri(); ?>/” Add wp_head() into the header. Disable the emojicons (http://wordpress.stackexchange.com/questions/185577/disable-emojicons-introduced-with-wp-4-2) Add a “classes” folder that will hold the php helper classes Add the custom template header to all custom pages
  • 6.
    GIT METHODOLOGY We’ll workin a branch called “wordpress” rather than the “master” branch. We’ll only merge back to the master branch once we’re going to deploy the build to to the live site. There should also be a branch called “frontend” which should hold the templates prior to CMS integration. Make an export of the database and include this into the git repo as well. Update this each time you make changes to custom fields or db structure. Make commits with each feature that’s submitted. The commit name should be a clear description of what’s been added. The git repo naming convention is {end-client}-{site-domain-without-extension}
  • 7.
    NAMING CONVENTIONS File naming:All lowercase, hyphen to separate words, avoid acronyms or abbreviations. When naming a template, try to describe the structure of the template, not the name of the page it’ll go with (ie generic-text.php rather than about.php). The exception to this is the homepage. Folder naming: All lowercase, hyphen to separate words, avoid acronyms or abbreviations. CSS naming: This will be covered in a separate course, but we follow the BEM CSS naming convention (http://getbem.com/naming/) For custom post types in the CMS, naming should be plural and sentence case and ids should be lowercase and _ to separate words (ie label: “Products”, id: “products”) For custom fields, labels should be descriptive and sentence case, field id should be lowercase and _ to separate words (ie label: “Discount code”, id: “discount_code”). When nested (as in a repeater or flexible content block), don’t repeat the block name in the name of the element (ie for a repeatable carousel “slider_image” - BAD “image” - GOOD)
  • 8.
    CUSTOM POST TYPEVS REPEATER IN PAGE TEMPLATE QUESTIONS TO ASK YOURSELF Are the items going to be listed in more than one page on the site? Are there any categories/taxonomies required for the items? Is it something that clearly stands out as it’s own type of object rather than a part of a page (eg products, news items)? Is it very important to the site overall (ie would the cms user be likely to be using it quite a bit and want to be able to get to it and edit it quickly)? Will there need to be a reference to the items (ACF relationship field) in other sections of the CMS? If you answered yes to any of the above, then consider setting up a custom post type, otherwise, use a repeater in the page template.
  • 9.
    SETTING UP THELIST PAGE FOR A CUSTOM POST TYPE The standard way for displaying the list of items from a custom post type is to use the {post-slug}-archive.php template. The downside of using this technique is: You can’t have any additional custom fields for the page, unless you create a new tab in the “Site settings” section, which isn’t a great user experience for an administrator. You can’t change the page url The preferred method is to turn off the archive for the custom post type, and then create a custom page template that lists all the post type items. This means that you can also create a custom field group that is associated with the page, which makes it more intuitive for the admin as they just search for the page and edit the custom fields.
  • 10.
    CUSTOM FIELDS GROUPS Applyfield groups to either a custom post type or a custom template, never directly to a page (there are exceptions to this) At the bottom of the field group, ensure you hide any standard fields that aren’t necessary Try to break down the field groups in such a way that you can reuse them in multiple places (eg Create separate carousel custom field group if it will apply to several templates rather than recreating the carousel custom fields in multiple groups) This is the place to be creative. Don’t be too literal, try to think a little more abstract. If elements are similar, likely they can use a single custom field group with optional elements. WYSIWYG fields should only ever be used for rich text (h1-h6, links, bold, underline etc). Turn off the media option for WYSIWYG’s. Ensure the order of the fields is as logical as possible and replicates the order they will appear on the site If you’ve got a custom field that will be a link to either an internal page or external site, please use a structure that has radio buttons for internal or external link, and if internal, show relationship field to select page, if external, show url field and target dropdown Get to understand some of the more advanced setup features, like conditional display and wrapper attributes (http://support.advancedcustomfields.com/forums/topic/how-to-use-wrapper-attributes/). They’ll help you to make the CMS
  • 11.
    MENUS Use Appearance >Menus to create the menus required for the site. Even if it’s not outlined in the design, if you can allow for multiple levels in the nav, please do as it’ll make the build more flexible
  • 12.
    OPTIONS PAGE There aregoing to be some global elements that need to be content managed, and some elements that just don’t fit anywhere else. This is where the ACF options page comes in handy (see http://www.advancedcustomfields.com/add-ons/options-page/). A common name to call this in the CMS is “Site settings”. Note that we’ll be hiding the wordpress settings from the end-user so this shouldn’t cause confusion (only admin will be able to see settings). A few notes on usage: Ideally separate the options page into tabs. Each tab represents a different logical area of the site (eg header, footer, contact form) Don’t go crazy with it. Only setup elements that you expect the admin to use.
  • 13.
    SEPARATE THEME FRONT-ENDCODE FROM CMS LOGIC Create php classes (in the “classes” folder) for each custom post type, each custom page template (which ideally inherits from a page class) All templates will then instantiate the correct class and use methods to get the data they need The benefits of this are: Cleaner, more easy to read front-end code Separation of data/logic and display (not quite model/view/controller but closer ;) Easier to setup an api from these classes if we decide to
  • 14.
    FORMS. VALIDATION, SUBMISSION& STORAGE Validation library of choice is http://www.formvalidator.net/ Unless there’s a specific reason, submit forms via ajax As a safety net, unless it’s just a simple contact form, create a custom post type for it and store form submissions as well as emailing the client The details of any emails sent from the form should be able to be content managed in the “Site settings” section of the cms. Things like the email address(s) to send to, email subject, copy etc. To avoid spamming, make sure that we have either a honeypot or captcha
  • 15.
    USER LOGIN AREAS Wordpressusers should be reserved for backend users. If the site has a user login, create a custom post type for the users rather than using the default wordpress users. There are a few reasons for this: If you use default wordpress users, you will need to implement hacks to make sure they don’t have access to the wordpress admin If you log in as the CMS admin user, it will show you logged onto the front-end (again, hacks required to get around this) Conceptually, it’s cleaner to have this separation If you’ve got a custom post type for users, there’s a few things to keep in mind Hash the user password
  • 16.
    KEEPING SECURITY ANDSEO IN MIND One of the major detractors for wordpress is it’s security. We’ve likely all had wordpress sites hacked in the past, but it’s not difficult to do the basics of securing them. Redirect all non-https traffic to https if you have ssl Complete as many of the iThemes Security recommendations as possible If it’s possible, lock the /wp-admin folder to only the ip addresses that are required (yours and the clients) SEO will often be in the client’s hands. If you’ve installed Yeost, make sure to flag to the client that they’ll need to populate the fields.
  • 17.
    WHEN TO SETUPCUSTOM DB TABLES The default table structure of wordpress is very flexible, but not very well optimised for large data sets. All the custom fields are stored in the wp_meta table as key value pairs. This means that it can be a hassle to manage content directly if needed and also slow for complex queries. If you have very large data sets or you need quick queries, consider creating a custom plugin that will create the db table(s) and setup the admin interface (https://codex.wordpress.org/Creating_Tables_with_Plugins).
  • 18.
    CLEANUP Before sending thebuild to the client to review, make sure you: Create a new wordpress user for the client Use adminize to hide any menu items that the client doesn’t need to see Remove all testing users and testing content Hide any fields in custom post types or templates that aren’t needed Hide Yeost SEO fields from anything that doesn’t display as a page on the site. You can do this from SEO > titles & meta
  • 19.
    FINAL NOTES /CHECKLIST Does your staging/development version of the site have search engine visibility discouraged, and the live version has this option turned off? Do you have a 404 page setup? Has google analytics been implemented? Do you have ssl? If so, are you redirecting all non-https traffic to https (including www)? Have you got a favicon? Always try to look at the CMS like you were the user. They should only see what they need to see. Please don’t EVER expect the user to know html to be able to manage the content No matter what the user does in the cms, they shouldn’t be able to make the site look broken Make sure that all wordpress user passwords are unique and proper passwords (no admin / admin please)