Theme Documentation

This is the Phoogoo Wordpress theme development kit. This is not a framework, no child-themes, no bloatware. Developers can take this theme and modify it directly.

The goal of this kit is to provide common functionality required in most wordpress themes today in a lean and semantically clean format. Below is a quick outline of the functionality a developer can quickly tap into during theme construction.

This kit is also a constant work in progress and forking is encouraged.
( email michael.niles@phoogoo.com for GIT repo access. )


Setup

There are a few preliminary steps before a developer should start modifying this theme.

  1. Change theme directory name, update screenshot, favicons & iOS badges
  2. Move _htaccess.txt to root and rename to .htaccess
  3. Edit & move _humans.txt to root and rename to humans.txt
  4. Move _robots.txt to root and rename to robots.txt (unless using a plugin such as Yoast SEO)
  5. Edit lib/less/theme.less: change the variable @theme from demo to theme (or whatever dir that houses your theme specific LESS CSS)
  6. Review $phoo_config in functions.php
  7. Delete lib/less/theme.less.cache if it exists before developement

LESS CSS

This theme utilizes the CSS preprocessor LESS. To learn more about LESS, please review the documentation at lesscss.org.

No client-side preprocessors are nessecary, all work is done by the theme via lessphp and cached on the server. There are a few aspects to lessphp that are unique (such as setting variables with php), documentation can be found at leafo.net/lessphp.

Do NOT edit lib/css/theme.css instead edit lib/less/theme.less & lib/less/inc/{theme}/* where {theme} is your theme's less directory (it's "theme" by default).

Poke around lib/less/inc/demo/* to see how the demo theme is styled.


Mobile First

The stylesheets are organized in a mobile-first arrangement. Meaning that media queries are called from bottom-up and that styles are inherited from each set before it. This is so that mobile devices don't download assets they won't end up using, as they do with the traditional top-down approach.

For easy organization you'll find in lib/less/inc/{theme}/responsive/ 4 files; phone.less, tablet.less, desktop.less & print.less.


Conventions

File organization and naming conventions are a work in progress. As they stand now, you'll find every type of asset organized in it's respective directory in lib/.

There is an automated variable that you can use in your LESS that references the path to your theme's root. An example of use:


.class { 
background-image: url(@{url}/lib/img/picture.jpg) 
}

LESS

  • lib/less/ houses the core theme.less file.
    all .less includes should be called from the theme.less file.

    lib/less/inc/ houses various LESS includes.
    lib/less/inc/core/* should not be edited unless you plan on committing a change to the kit's GIT repository.
    lib/less/inc/vendor/* houses any vendor-specific css (such as styles that accompany 3rd-party scripts).
    lib/less/inc/demo/* houses the styles for the default demo theme.
    lib/less/inc/theme/* houses the barebone styles for your custom theme.
    lib/less/inc/theme/init.less should contain all your global LESS variables. Useful for making quick changes & adjustments.
    lib/less/inc/theme/layout.less should contain all your global structural styling.
    lib/less/inc/theme/type.less should contain all your typographic styling.
    lib/less/inc/theme/ui.less should contain all your user-interface styling including colors.

CSS

  • lib/css/ houses the core theme.css file that the lessphp preprocessor generates. This file should NOT be edited.

Fonts

  • lib/fonts/ should house your custom webfonts and icon fonts. These fonts should be requested via @font-face in lib/less/inc/{theme}/type.less

Images

  • lib/img/ contains the theme's favicon & iOS badges. This is were you'd place your theme's imagery.

Javascript

  • lib/js/ houses your main.js which is your primary custom javascript file, & plugins.js which should contain all the 3rd-party javascript your theme calls for. lib/js/vendor/* houses any vendor-specific css (primarily a local copy of jQuery, and modernizer).

PHP

  • lib/php/ contains a few PHP classes for additional functionality
    lib/php/core/* should not be edited unless you plan on committing a change to the kit's GIT repository.
    lib/php/admin/theme-settings.php is where you can add site-wide options for the client (found in appearance -> site options in WP's admin menu).
    lib/php/meta/* houses a simple PHP class for adding custom meta boxes. Do NOT edit. Use the commented structure under Metaboxes in functions.php

SVG

  • lib/svg/ houses any SVG objects or filters.

IE

  • lib/ie/ contains all IE only assets, including styles, scripts, images and polyfills.

Wrap up list

Aside from the usual items (making sure search engines aren't blocked, etc.) there are a few things specific to this theme that should be tended to before pushing live.

  1. Set inDevelopement in functions.php to false, and set the appropriate value for cacheBustVersion
  2. Remove /lib/less/inc/demo
  3. Remove any fonts & icon fonts not being used in /lib/fonts
  4. Trim lib/js/vendor/modernizr-.js so that we aren't checking the browser for every capability.
  5. Minify each 3rd-party javascript in lib/js/plugins.js. A helpful tool can be found at htmlcompressor.com
  6. Optimize images in lib/img/. A helpful tool can be found at smushit.com

Shrinkwrap

This is a simple organizational convention that can make your life easier. Infact your looking at it right now, this is the structure the whole theme is built upon.


<div id="full-container">
<div class="shrinkwrap">
...
</div>
</div>

Example

#header
.shrinkwrap
#content
.shrinkwrap
#footer
.shrinkwrap

Other Notes

The shrinkwrap class inherits it's width & left and right padding from the @site-width & @site-outer-margins variables set in lib/less/inc/{theme}/init.less, however it's built to be flexable and will shrink as the window requires it to.


Grids

Using the .grid() LESS mixin we can quickly and semantically construct unique flexable grid layouts


.grid( @total_columns: 1, @column_span: 1, @gutter_override: @gutter-width );

.replace-grid( @old_total_columns: 1, @new_total_columns: 1, @column_span: 1, @gutter_override: @gutter-width );

Examples

Continuous + Responsive grid

HTML


<ul class="gallery">
<li></li>
...
<li></li>
</ul>

LESS


/* mobile-first */.gallery li {
.grid(2);
}

/* everything else */@media only screen and (min-width: 480px) {
.gallery li {
.replace-grid(2, 4);
}
}

Colspan + nested + responsive grid

Main Content

  • 1
  • 2
  • 3

Aside Content

HTML


<div class="main">
<p>Main Content</p>
<ul class="nested-grid">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
<div class="aside">
<p>Aside Content</p>
</div>

LESS


/* mobile-first */.main,
.aside,
.nested-grid li {
.grid(1);
}

/* everything else */@media only screen and (min-width: 480px) {
.main {
.replace-grid(1, 3, 2);
}
.aside {
.replace-grid(1, 3);
}
.nested-grid li {
.replace-grid(1, 3);
}
}

Other Notes

The .grid() mixin uses ":last-of-type" css selectors, so make sure your grid is wrapped in a container.
Don't worry about IE, it's served a polyfill.


Icons

Using the .icon() mixin, we can easily add icons from iconfonts to our elements. Icon fonts are 100% customizable with CSS, and scale crystal clear to any pixel density.


.icon( @icon: attr('data-icon'), @icon-font: 'icons' );

Examples

Inline icon before element: Pure CSS

HTML


<span class="twitter">
Follow us on Twitter
</span>

LESS


.twitter {
&:before {
.icon('\F099', 'icons');
}
}

Inline icon after element: Data-attribute method

HTML


<span class="facebook" data-icon="&#xf082;">
Friend us on Facebook
</span>

LESS


.facebook {
&:after {
.icon();
}
}

Linked Icon with text hidden

Like Us!

HTML


<a class="like" href="#liked">
<span>Like Us!</span>
</a>

LESS


.like {
&:after {
.icon('\F164');
}
span {
.visuallyHidden();
}
}

Other Notes

It's best practice to round up all of your project's icons, export them individually as svg's, and create a custom icon-font over at http://icomoon.io/app/

Here's a set of icons included for testing: Fontawesome Index
*** Don't include icons your project won't be using as it will increase load-time.

If you find you need to convert unicode characters between formats (html entities, css escapes, etc.) this is a very helpful tool http://rishida.net/tools/conversion/


Modals

We can quickly bind a modal to any element by using the data-modal attribute.


<div data-modal="..."></div>

Examples

Image Modal

HTML


<img src="http://placekitten.com/200/200" data-modal="<img src='http://placekitten.com/400/400' />" />

Video Modal

HTML


<img src="http://placekitten.com/200/200" data-modal="<?php echo video(array('hash'=>'0Bmhjf0rKe8')); ?>" />

Gallery Modal

HTML


<img src="http://placekitten.com/200/200" data-modal="<img src='http://placekitten.com/400/400' />" data-gallery="1" />
<img src="http://placekitten.com/200/200" data-modal="<img src='http://placekitten.com/400/400' />" data-gallery="1" />

Other Notes

When using the gallery modal, the index of the clicked gallery item must be relative to it's other gallery neighbors. if you wrap the item in a parent container, the index will always be returned as one.

To avoid this, make sure you place the actual data-modal and data-gallery attributes on the parent. See the example below.


<ul>
<li data-modal="<img src='http://placekitten.com/400/400' />" data-gallery="1">
<img src="http://placekitten.com/200/200" />
</li>
</ul>

Breadcrumbs

Built in, there's an extremely customizable breadcrumb generator. Just call the phoo_crumbs() PHP function.


<?php phoo_crumbs($title = '', $end = false, $separator = '»'); ?>

Examples

Custom seperator & prefix

Crumbs: Home / About Us / Our Mission

HTML


<div class="crumbs">
<?php phoo_crumbs('Crumbs:', true, '/'); ?>
</div>

LESS


.crumbs {
&, a, .seperator, .title {
color: blue;
}
}

No prefix & Omit current page title

Home » About Us

HTML


<div class="crumbs">
<?php phoo_crumbs(); ?>
</div>

LESS


.crumbs {
&, a {
color: blue;
}
}

Sharing

We've got simple, stylable sharing links built in for google+, facebook, & twitter. Use the phoo_share() PHP function.


<?php phoo_share(); ?>

Examples

Plain text links

HTML


<div class="share">
<?php phoo_share(); ?>
</div>

LESS


.share {
ul {
margin: 0;
padding: 0;
}
li {
display: inline;
margin: 0;
padding: 0 1em 0 0;
}
}

Icon links + hidden text

HTML


<div class="share">
<?php phoo_share(); ?>
</div>

LESS


.share {
/*duplicate css from above*/
.fb a:before {
.icon('\F082');
}
.ggl a:before {
.icon('\F0D4');
}
.twtr a:before {
.icon('\F081');
}
span {
.visuallyHidden();
}
}

Form Elements

Simple pre-styled form elements that can easily and quickly be skinned into any project.

Buttons

My Link

HTML


<a class="button" href="#button">My Link</a>
<button>My Button</button>
<input type="submit" value="My Submit" />

Other Notes

.button, button, & input['type=submit'] all have the .btn() mixin applied by default in /lib/less/inc/{theme}/ui.less.

 

Text Inputs with Placeholders + invalid entries

HTML


<label class="half">Text</label>
<label class="half">Email</label>
<input class="half" type="text" placeholder="placeholder text..." />
<input class="half" type="email" placeholder="address@domain.com" />
<label class="half">Tel</label>
<label class="half">Password</label>
<input class="half" type="tel" pattern="[0-9]{3} [0-9]{3} [0-9]{4}" placeholder="--- --- ----" />
<input class="half" type="password" placeholder="enter your password" />
<label>Date</label>
<input type="date" placeholder="mm/dd/yyyy" />
<label>Time</label>
<input type="time" placeholder="--:--:--" />
<label>Textarea</label>
<textarea placeholder="this is required..." required></textarea>

Other Notes

All input types & textarea (excluding submit, checkbox, & radio) have the .input() mixin applied by default in /lib/less/inc/{theme}/ui.less.

 

Checkboxes & Radios

HTML


<input type="checkbox" id="demo_checkbox" />
<label for="demo_checkbox">Custom Checkbox</label>

<input type="radio" name="demo_radio" id="demo_radio_01" />
<label for="demo_radio_01">Custom Radio 01</label>

<input type="radio" name="demo_radio" id="demo_radio_02" />
<label for="demo_radio_02">Custom Radio 02</label>

Other Notes

Checkboxes & Radios both have the .toggle-input() mixin applied by default in /lib/less/inc/{theme}/ui.less.

 

Custom Checkboxes & Radios

LESS


input[type=checkbox] + label,
input[type=radio] + label {
display: block;
&:before {
border: none;
background-color: transparent;
font-family: icons;
}
}
input[type=checkbox] {
+ label:before {
content: '\F09C';
}
&:checked + label:before {
content: '\F023';
}
}
input[type=radio] {
+ label:before {
content: '\F026';
}
&:checked + label:before {
content: '\F028';
}
}

Other Notes

Checkboxes & Radios both have the .toggle-input() mixin applied by default in /lib/less/inc/{theme}/ui.less.


Thumbnails

Quick and easy thumbnail fetch with PHP using the get_thumb() function.


<?php get_thumb($size = 'thumbnail', $fallback_image_ID = null, $echo = true); ?>

Examples

Grabbing an existing 150x150 thumbnail from featured image

pretty kitty

HTML


<div class="thumb">
<?php get_thumb(); ?>
</div>

No Feature Image exists, fall back to default + Medium size

pretty kitty

HTML


<div class="thumb">
<?php get_thumb('medium', 12); ?>
</div>

No Feature Image exists, no fallback specified.

HTML


<div class="thumb">
<?php get_thumb(); ?>
</div>

Other Notes

When no feature image exists & no fallback is specified, the image from /lib/img/default.jpg is fetched.
Change it if you feel let down.


Galleries

Fetching a gallery from a post's media using phoo_gallery() function.


<?php phoo_gallery($postID = $post->ID, $size = 'thumbnail'); ?>

Example

Display gallery if post has media.

HTML


<?php phoo_gallery(); ?>

LESS


.gallery-grid {
li {
...
}
a {
...
&:after {
...
}
}
img  {
...
}
}

Other Notes

Responsive out of the box. No styling required. phoo_gallery() will not render anything if the post has no media attached; it will also ignore the featured image.


Excerpts

Quickly fetch and customize a post's excerpt with the phoo_excerpt() PHP function.


<?php phoo_excerpt($length = 20, $text = null, $letters = false, $echo = true); ?>

Examples

Default usage. Cuts length at 20 words.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut...

HTML


<?php phoo_excerpt(); ?>...

Cut length at 20 characters.

Lorem ipsum dolor si...

HTML


<?php phoo_excerpt(20, null, true); ?>...

Excerpt'ify from another source + cut length at 10 characters.

A Really L...

HTML


<?php phoo_excerpt(10, get_the_title(), true); ?>...

Mixins

A Quick reference of the other available mixins.

Placeholder

Defines placeholder color for inputs.


.placeholder(@color);

Greyscale

Forces an image to greyscale. Cross-browser support with IE filters, SVG filters, & CSS3.


.greyscale();

Remove Greyscale

Resets all filters to remove greyscale from image.


.remove-greyscale();

Prevent Highlight

Prevents element from being highlighted. Good for UI elements.


.prevent-highlight();

Image Replacement

Wipes element of text to be replaced by an image in a SEO friendly way. Inspired by zeldman: http://goo.gl/gdVJI


.ir();

Completely Hidden

Hide from both screenreaders and browsers: h5bp.com/u


.hidden();

Visually Hidden

Hide only visually, but have it available for screenreaders: h5bp.com/v


.visually-hidden();

Clearfix

Contain floats: h5bp.com/q


.clearfix();

Other Mixins

This theme also includes all mixins from elements.less


WP Helpers

A Quick reference of the custom wordpress helpers.

Is Post Type

Matches current post against postType. Better to use is_singular( $post-type ) if you're able.


<?php is_post_type($type, $postID = $post->ID); ?>

Is Blog

Returns true if current post is blog-related. Use is_home() to check if it's the blogroll page.


<?php is_blog(); ?>

Is Descendant

Returns true if current page is descendant of specified page. $parent parameter can be slug or ID.


<?php is_descendant($parent); ?>

Quick Meta

Echo meta, get meta, & check if meta exists.


<?php 
meta($meta);
get_meta($meta);
meta_exists($meta);
?>

Get Posts Page URL/Title

Gets page URL or Title that's responsible for housing posts when manually set. $data parameter can be 'url' or 'title'.


<?php echo get_posts_page($data); ?>

Youtube/Vimeo fetch

Can get video or image assets from youtube or vimeo from url or video hash. $array parameter has the following options:

'hash' => video url or hash
'type' => only required if hash was given instead of url. options: 'youtube', 'vimeo'. Defaults to 'youtube'
'action' => options 'get_thumb', 'get_image', 'get_hash', 'get_type', 'get_video'. Defaults to 'get_video'
'width' => integer: video width in px
'height' => integer: video height in px


<?php echo video($array); ?>