Upload
linnalexandra
View
794
Download
7
Tags:
Embed Size (px)
DESCRIPTION
Slides for my talk at WordCamp Toronto 2014. The full theme is available here: https://github.com/LinnAlexandra/wcto14
Citation preview
Don’t Fear the CustomDon’t Fear the CustomThemeThemeHow to build a custom WordPress theme withHow to build a custom WordPress theme withonly four filesonly four filesLinn Øyen Farley
/ @LinnOyenFarleydrollic.ca
Linn Øyen FarleyLinn Øyen FarleyWeb designer/developerBuilding things on the internet since 2005Usually working solo or with a designerMainly use WordPress for client sites
I ♥ WordPressI ♥ WordPressAmazing community and resourcesActive plugin community (don’t have to re-invent the wheel)Super easy to hand off to clients
But ...But ...“WordPress outputs bloated code”“All WordPress sites look the same”and/or“I don’t have time to learn PHP”“I tried customizing a [commercial theme provider] theme once and I couldn’t findanything”
This talkThis talkis a file-by-file guide to creating a fully-functional WordPress theme, based on anexisting HTML/CSS designgives an overview of the bare minimum of PHP functions needed to build a WordPresstheme (plus some extra stuff)suggests how you could use a custom WordPress theme as a tool for rapid prototypinguses WordPress.org’s Theme Guidelines (
) as a starting point for best practicesmake.wordpress.org/themes/handbook
/guidelines/
This talk won’tThis talk won’tcover HTML/CSS/design principles100% accurately represent how I build themes for clientsfocus on making a WordPress.org-repository-ready theme and/or incorporate every usecase into a single themebe a hands-on workshop — I have less than an hour, so I’ll be moving pretty quickly
Commercial themeCommercial theme
Full disclosure: I installed this exact theme on a client’s site earlier this year. There is definitely a place for commercial and child themes in theWordPress ecosystem, but creating a custom theme may be appropriate more often than you think.
Recent theme for a clientRecent theme for a client404.phpcomments.phpfooter.phpfunctions.phpheader.phpimages/
logo.pngnav-icon.pngsearch.png
index.phpjs/
html5shim.jsrespond.min.js
page.phpscreenshot.pngsearchform.phpstyle.css
Theme for WordPress.orgTheme for WordPress.orgindex.phpscreenshot.pngstyle.css
Note: The recommended theme guidelines ( ) include a few more files,but the three above are the only required files ( ).
make.wordpress.org/themes/handbook/guidelines/theme-check/#recommendedmake.wordpress.org/themes/handbook/guidelines/theme-check/#required
...plus we’ll talk about functions.php, because it’s my favourite
Wait a minute...Wait a minute...How can this →
be successfully reduced to this:
index.phpscreenshot.pngstyle.css
(you might be wondering)
The template hierarchyThe template hierarchyReference: codex.wordpress.org/Template_Hierarchy
The template hierarchyThe template hierarchyFor our purposes, the most important part of that giant diagram is on itsright-hand side: all arrows lead to index.php.
If your theme contains the other files on the diagram, they will trumpindex.php, but if you only have index.php, that’s fine too!
List of requested featuresList of requested featuresResponsive designHomepage with intro paragraph and latest postAbout page with image galleryBlog with widgets in the sidebar
WordPress dashboard tasksWordPress dashboard tasksPages → Add New:
Home (the intro paragraph), About (the image gallery), and Blog (with no content)Posts → Add New:
create a few blog postsSettings → Reading:
Choose “Front page displays: A static page”Make Home your “Front page” and Blog your “Posts page”
Appearance → Menus:Create a main navigation menu with the pages you’ve made
File #1:File #1:
screenshot.pngscreenshot.png
Start with a designStart with a designHere’s a design ready to go, built in HTML and CSS. The image below covers your firstrequired file, screenshot.png.
Recommended size: 880x660pxShould be a “reasonable facsimile” of the theme after it is initially activated with defaultoptions
Reference: make.wordpress.org/themes/handbook/guidelines/theme-check/#required
File #2:File #2:
style.cssstyle.css
Get your stylesheet readyGet your stylesheet readyMake sure your CSS file is called style.css, and that it starts with the following comment:
/*Theme Name: [Client's Name]Description: Custom theme for [Client's Name].Author: Linn Oyen FarleyAuthor URI: http://drollic.caVersion: 1.0*/
The absolute minimum you need to include here is your theme’s name, but why not giveyourself some credit?Reference: codex.wordpress.org/Theme_Development#Theme_Stylesheet
Include WordPress-specific classesInclude WordPress-specific classesWordPress auto-generates a few classes, which you can include if you want to style them:
/* Image alignment classes */.aligncenter {}.alignleft {}.alignright {}
/* Image caption-related classes */.wp-caption {}.wp-caption-text {}.gallery-caption {}
/* Post and comment classes */.sticky {}.bypostauthor {}
/* Menu classes */.current_page_item, .current_page_parent {}
File #3:File #3:
index.phpindex.php
Move from HTML to PHPMove from HTML to PHPTake your index.html file...
<!-- HTML goes here -->
...and save it as index.php.
<!-- HTML goes here -->
<?php // and also PHP ?>
That’s all you need to do to start writing PHP in the file. Most WordPress theme filesconsist of a lot of HTML and a bit of PHP.
Interlude:Interlude:
Intro to PHPIntro to PHP
Things to keep in mind:Things to keep in mind:PHP isn’t as forgiving as HTML or CSSMistakes in your code = white screen of death + (sometimes) error messagesYou only need to know a little PHP syntax to build WordPress themesUse a code editor with syntax checking, or run your code through a validator likePHPCodeChecker.com
Always:Always:enclose PHP with opening (<?php) and closing (?>) tagsdecide to use either single or double quotesmind your semicolons
<?php ?>
<?php echo "Hello world"; ?>
<?php echo 'Hello world'; ?>
<?php // this is a comment ?>
Reference: php.net/manual/en/index.php
ConditionalsConditionalsif ( condition1 ) {
if condition #1 is true, do thing #1} elseif ( condition2 ) {
otherwise, if condition #2 is true, do thing #2} else {
or, if none of those conditions are true, do thing #3}
don’t forget the closing curly brace!
Reference: Conditional statements: php.net/manual/en/language.control-structures.php
OperatorsOperators&& (and)|| (or)== (is equal to)!= (is not equal to)
References:Logical operators: Comparison operators:
php.net/manual/en/language.operators.logical.phpphp.net/manual/en/language.operators.comparison.php
LoopsLoopswhile ( condition1 ) { }
The while loop starts with a condition, and then specifies what to do as long as thatcondition is true.
For example, the main posts loop in WordPress states that as long as there are posts toshow (while you have posts), set up each post (so you can grab its title, content, etc).
Reference: php.net/manual/en/control-structures.while.php
VariablesVariables$ indicates a variable, either one that you want to store or one that is already stored
$myNewVariable = 'This variable should contain some text!';
$myNewVariable now contains that string of text, which you can use later.
Reference: php.net/manual/en/language.variables.basics.php
VariablesVariablesecho is used to display/output the contents of an existing variable
This:
<p><?php echo $myNewVariable; ?></p>
would output your text string on the page:
This variable should contain some text!
Reference: php.net/manual/en/function.echo.php
Conditional tagsConditional tagsWordPress has lots of its own functions that you can use in your theme’s conditionalstatements.
I’m going to cover these ones:
is_front_page()
true if you’re viewing the front pageis_page()
true if you’re viewing a single pageis_single()
true if you’re viewing a single post
Reference: codex.wordpress.org/Conditional_Tags
Back to file #3:Back to file #3:
index.phpindex.php
wp_title()wp_title()Replace the contents of <title></title> with wp_title().
This will output a separator and the title of the page or post being viewed.
If you’re viewing the front page, it won’t output anything.Reference: codex.wordpress.org/Function_Reference/wp_title
wp_title() in actionwp_title() in actionReplacing this:
<title>Feline Design Co.</title>
with this:
<title><?php wp_title(); ?></title>
outputs this (when viewing the blog post with this title):
» Blog post #1
wp_title() & bloginfo('name')wp_title() & bloginfo('name')The title function looks best if you also add the site’s name (the one you specify underSettings → General), and change the separator. This:
<title><?php wp_title('—', true, 'right'); bloginfo( 'name' ); ?></title>
changes the separator to a long dash, moves it to the right-hand side, and adds the sitename, outputting this (when viewing that same blog post):
Blog post #1 — Feline Design Co.
Reference: codex.wordpress.org/Function_Reference/bloginfo
wp_head() & wp_footer()wp_head() & wp_footer()These required tags always need to be included in your theme. They go immediatelybefore your closing head tag and your closing body tag, respectively:
<?php wp_head(); ?></head><body>
<?php wp_footer(); ?></body></html>
References:codex.wordpress.org/Function_Reference/wp_headcodex.wordpress.org/Function_Reference/wp_footer
language_attributes() & bloginfo('charset')language_attributes() & bloginfo('charset')You can dynamically specify the site’s language and character set using these functions.This:
<html <?php language_attributes(); ?>> <head> <meta charset="<?php bloginfo( 'charset' ); ?>" />
outputs something like this:
<html lang="en-US"> <head> <meta charset="UTF-8" />
Reference: codex.wordpress.org/Function_Reference/language_attributes
bloginfo('template_directory')bloginfo('template_directory')Replace all relative links to design elements (such as your logo in the header area) withlinks to those elements in your theme folder.
You can use the same bloginfo() function you used earlier to get your theme’s location.
Instead of asking for bloginfo('name') or bloginfo('charset'), ask forbloginfo('template_directory').
bloginfo('template_directory') in actionbloginfo('template_directory') in actionReplacing this:
<img src="images/logo.png" alt="Feline Design Co." />
with this:
<img src="<?php bloginfo('template_directory'); ?>/images/logo.png" alt="<?php bloginfo('name'); ?>" />
outputs this:
<img src="http://felinedesign.co/wp-content/themes/feline-design-co/images/logo.png" alt="Feline Design Co." />
wp_nav_menu()wp_nav_menu()Replace your static navigation menu with the WordPress native menu (the one you cancreate under Appearance → Menus).
Make a note of whatever you put as the theme location here, because you’ll need it later!Reference: codex.wordpress.org/Function_Reference/wp_nav_menu
wp_nav_menu() in actionwp_nav_menu() in actionReplacing this:
<ul> <li><a href="index.html">Home</a></li> <li><a href="about.html">About</a></li> <li><a href="blog.html">Blog</a></li></ul>
with this:
<?php wp_nav_menu('theme_location' => 'main-nav'); ?>
Make a note of “main-nav” for later!
wp_nav_menu() in actionwp_nav_menu() in action...outputs something like this:
<div class="menu"> <ul> <li class="page_item page-item-474"><a href="http://felinedesign.co/about/">About</a></li> <li class="page_item page-item-472"><a href="http://felinedesign.co/blog/">Blog</a></li> <li class="page_item page-item-470 current_page_item"><a href="http://felinedesign.co/">Home</a></li> </ul></div>
Until you assign a menu to the “main-nav” theme location, wp_nav_menu() will default toan alphabetical list of your pages.
The WordPress loopThe WordPress loopReplace your hard-coded content with dynamic content. Start by checking if any contentexists, and display an error message if it doesn’t:
<?php if ( ! have_posts() ) { ?> <h1>Not Found</h1> <p>Sorry, nothing found.</p><?php } ?>
Anatomy of an if statementAnatomy of an if statementA basic if statement is structured like this:
the word if1. opening parenthesis2. condition3. closing parenthesis4. opening curly brace5. things that should happen if the condition is true6. closing curly brace7.
have_posts()have_posts()<?php if ( ! have_posts() ) { ?> <h1>Not Found</h1> <p>Sorry, nothing found.</p><?php } ?>
have_posts() is a WordPress function that checks if there is any content to display(either posts or pages).
The ! means not, i.e. if there is not any content, do the following — in this case, display a“Not Found” heading and message.Reference: codex.wordpress.org/Function_Reference/have_posts
The WordPress loopThe WordPress loopIf there is stuff to show, however, it should display:
<?php if ( ! have_posts() ) { ?> <h1>Not Found</h1> <p>Sorry, nothing found.</p><?php } else { // Display the content!} // end if ?>
Anatomy of an if/else statementAnatomy of an if/else statementWhen you want different stuff to happen when your condition is true vs. when it is not true,the if statement needs a few extra parts after the closing curly brace:
the word else1. opening curly brace2. things that should happen if the condition is not true3. closing curly brace4.
The WordPress loopThe WordPress loopwhile ( have_posts() ) { the_post(); ?> <h1><?php the_title(); ?></h1> <?php the_content();} // end while
If you do have content, start a while loop to display it.
This states that as long as there is content to show, set up the_post(). the_post()function contains all of the info about a post or page in WordPress, so it’s ready for you tograb and use.Reference: codex.wordpress.org/Function_Reference/the_post
the_title() & the_content()the_title() & the_content()<h1><?php the_title(); ?></h1>
the_title() will pull whatever you’ve put in the post or page title field. WordPressdoesn’t automatically format your title, so you need to wrap the PHP tag in some HTML tostyle it.
<?php the_content(); ?>
the_content() pulls everything from the main content editing box in WordPress,formatting and all.References:codex.wordpress.org/Function_Reference/the_titlecodex.wordpress.org/Function_Reference/the_content
Recap: the full loopRecap: the full loopHere is the loop in its entirety, with comments throughout:
<?php// If we do not have content...if ( ! have_posts() ) { // ...then show an error message: ?> <h1>Not Found</h1> <p>Sorry, nothing found.</p><?php// Otherwise...} else { // ...as long as there is content to show... while ( have_posts() ) { // ...set up each piece of content so we can grab stuff from it: the_post(); ?> <h1><?php the_title(); ?></h1> <?php the_content(); } // end while} // end if ?>
Theme test driveTheme test driveAt this point, regular pages look almost perfect:
Theme test driveTheme test driveYou still need to set up a menu location to get thosemenu items in the right order, but I’ll cover thatwhen we get to functions.php.
Theme test driveTheme test driveOur error page is also functioning well:
Theme test driveTheme test driveThe blog page needs some additional info on each post, beyond just the title and content.It also needs a widgetized sidebar:
Theme test driveTheme test driveOur single blog posts need additional info and a sidebar too, plus a section for comments:
Theme test driveTheme test driveFinally, the homepage shouldn’t display the_title(), and it’s missing the latest post atthe bottom:
is_front_page()is_front_page()Once you’ve established that you do have content to show, start by checking whetheryou’re viewing the front page.
If you are, display the content without the title:
<?php if ( is_front_page() ) { the_content();} // end if ?>
Reference: codex.wordpress.org/Function_Reference/is_front_page
WP_Query()WP_Query()To grab the latest post and display it on the front page, you can use the functionWP_Query(). First, store the result (if there is one) in a variable:
<?php $latestPost = new WP_Query('posts_per_page=1'); ?>
Reference: codex.wordpress.org/Class_Reference/WP_Query
WP_Query()WP_Query()Then you can use the same have_posts() function you’ve already seen, but apply itspecifically to your $latestPost variable. This double-checks that there is a post toshow, before adding a “Latest from the blog” heading and setting up the_post():
<?php if ( $latestPost->have_posts() ) { // If there is a post to show, add a title before starting the loop: ?> <h2>Latest from the blog...</h2> <?php while ( $latestPost->have_posts() ) { $latestPost->the_post(); } // end while} // end if ?>
the_excerpt()the_excerpt()If there is a post to show, you can use the_title() again to display its title.
Instead of displaying the full content of the post, only display its excerpt by using thefunction the_excerpt():
<h3><?php the_title(); ?></h3><?php the_excerpt(); ?>
Reference: codex.wordpress.org/Function_Reference/the_excerpt
the_permalink()the_permalink()the_permalink() will get the post’s URL/permalink, so you can make the post title linkto the full post:
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
Reference: codex.wordpress.org/Function_Reference/the_permalink
the_time()the_time()Add the date and time the post was published, using the_time() and the Codex’s dateand time formatting cheatsheet ( ). This:codex.wordpress.org/Formatting_Date_and_Time
<p class="metadata">Posted on <?php the_time('F jS Y'); ?> at <?php the_time('g:i A'); ?></p>
outputs this:
<p class="metadata">Posted on November 15th 2014 at 8:00 AM</p>
Reference: codex.wordpress.org/Template_Tags/the_time
the_terms()the_terms()Add the post’s categories by using the_terms(). This:
in <?php the_terms( $post->ID, 'category' ); ?>
outputs this:
in <a href="http://felinedesign.co/category/cats/" rel="tag">Cats</a>, <a href="http://felinedesign.co/category/design/" rel="tag">Design</a>
Reference: codex.wordpress.org/Function_Reference/the_terms
Recap: latest postRecap: latest postHere’s the complete block of code to display the post’s permalink, title, metadata, andexcerpt:
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3><p class="metadata">Posted on <?php the_time('F jS Y'); ?> at <?php the_time('g:i A'); ?> in <?php the_terms( $post->ID, 'category' ); ?></p><?php the_excerpt(); ?>
And this is how it looks:
Homepage: complete!Homepage: complete!
is_page()is_page()You can use the same code to display each post’s metadata on the main blog page andon single posts.
But first, to avoid displaying it on pages, add another condition to the loop:
<?php } elseif ( is_page() ) { // If this is a regular page, just display the title and content: ?> <h1><?php the_title(); ?></h1> <?php the_content();} else { // Otherwise, display the title and content plus the metadata ?> <h1><?php the_title(); ?></h1> <p class="metadata">Posted on <?php the_time('F jS Y'); ?> at <?php the_time('g:i A'); ?> in <?php the_terms( $post->ID, 'category' ); ?></p> <?php the_content();} // end if ?>
Reference: codex.wordpress.org/Function_Reference/is_page
comments_template()comments_template()To avoid having comments display on pages, add the comments template at the end ofthe loop, after you’ve established that you’re not viewing a page:
<p class="metadata">Posted on <?php the_time('F jS Y'); ?> at <?php the_time('g:i A'); ?> in <?php the_terms( $post->ID, 'category' ); ?></p><?php the_content();comments_template(); ?>
Reference: codex.wordpress.org/Function_Reference/comments_template
comments_template() in actioncomments_template() in action
next_posts_link() & previous_posts_link()next_posts_link() & previous_posts_link()Once you have more posts than “Blog pages show at most” (under Settings → Reading),you’ll need pagination links to navigate the blog.
Add the following code between the_content() and comments_template():
<p class="aligncenter"> <?php next_posts_link( '← Older' ); ?> <?php previous_posts_link( 'Newer →' ); ?></p>
References:codex.wordpress.org/Function_Reference/next_posts_linkcodex.wordpress.org/Function_Reference/previous_posts_link
next_posts_link() & previous_posts_link() innext_posts_link() & previous_posts_link() inactionactionDepending on where you are in the blog, these links may look like any of the followingexamples:
Saving space for widgetsSaving space for widgetsYou’ll be creating a widgetized area in functions.php, so save some space for it now.
Before you start the loop, make sure you’re not on a page, and then start the primarysection:
<section class="main"> <?php if ( ! is_page() ) { ?> <section class="primary"> <?php } ?>
Saving space for widgetsSaving space for widgetsThen just before closing the main section, check to make sure you’re not on a pageagain, and add an aside:
<?php if ( ! is_page() ) { ?> </section><!-- .primary --> <aside class="secondary"> <?php dynamic_sidebar( 'blog-widget-area' ); ?> </aside><!-- .secondary --> <hr class="clear" /><?php } ?>
Make a note of “blog-widget-area” for later!
Reference: codex.wordpress.org/Function_Reference/dynamic_sidebar
Saving space for widgetsSaving space for widgetsFor now, this will give you an empty sidebar area on the blog and on single posts:
is_single()is_single()Post titles should appear slightly differently on single posts vs. on the main blog page.
Inside the final else statement, add one more conditional statement to take care of this:
if ( is_single() ) { // If you're viewing a single post, display the title as an h1: ?> <h1><?php the_title(); ?></h1><?php } else { // Otherwise, display the title as an h3 and link it to the full post: ?> <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2><?php } ?><p class="metadata">Posted on <?php the_time('F jS Y'); ?> at <?php the_time('g:i A'); ?> in <?php the_terms( $post->ID, 'category' ); ?></p><?php the_content(); ?>
Reference: codex.wordpress.org/Function_Reference/is_single
File #4:File #4:
functions.phpfunctions.php
Not required, but super usefulNot required, but super usefulThis file is a plugin bundled with your theme. It can add lots of functionality to your site,but keep in mind that it will all disappear if you switch your theme.
There are so many things you can do with a functions.php file, and I have very little time,so I’m just going to cover a few examples of what’s possible.
Create your functions fileCreate your functions fileMake a new file called functions.php, and add opening and closing PHP tags:
<?php?>
register_nav_menus()register_nav_menus()Remember making a note of “main-nav”, when you were replacing your hard-coded menuwith wp_nav_menu()?
It’s time to create that menu location, so you can assign your menu to it under Appearance→ Menus:
// Register menu(s)register_nav_menus( array( 'main-nav' => 'Main Navigation' ));
Reference: codex.wordpress.org/Function_Reference/register_nav_menus
register_nav_menus()register_nav_menus()If your theme is going to use more than one menu, you can register them all in one go:
// Register menu(s)register_nav_menus( array( 'main-nav' => 'Main Navigation', 'footer-nav' => 'Footer Navigation' ));
To display the menu assigned to Footer Navigation (under Appearance → Menus), add thecode below to index.php:
<?php wp_nav_menu('theme_location' => 'footer-nav'); ?>
register_nav_menus() in actionregister_nav_menus() in actionAhhhh. Much better.(Note: you need to go to Appearance → Menus in the WordPress dashboard, create a menu, andselect Main Navigation as its Theme location for this to work.)
register_sidebar()register_sidebar()Although the word “sidebar” is right there, this is how you create any widgetized area, i.e.areas that you can drag widgets into under Appearance → Widgets.References:
(writes the code for you)codex.wordpress.org/Function_Reference/register_sidebargeneratewp.com/sidebar/
// Register widgetized area(s)function my_widgets_init() { register_sidebar( array( 'id' => 'blog-widget-area', 'name' => 'Blog Widget Area', 'description' => 'Appears on the blog and single posts.', 'before_title' => '<h3 class="widget-title">', 'after_title' => '</h3>', 'before_widget' => '<section class="blog-widget">', 'after_widget' => '</section><!-- .blog-widget -->', ) );}add_action( 'widgets_init', 'my_widgets_init' );
register_sidebar()register_sidebar()Remember “blog-widget-area”? Whatever you put as the ID in functions.php:
'id' => 'blog-widget-area'
needs to match what you put in dynamic_sidebar() in index.php:
<?php dynamic_sidebar( 'blog-widget-area' ); ?>
register_sidebar()register_sidebar()You can register several widget areas in one go with this function, and then display eachone using dynamic_sidebar('the-id-you-chose'):
// Register widgetized area(s)function my_widgets_init() { register_sidebar( array( 'id' => 'blog-widget-area', 'name' => 'Blog Widget Area', 'description' => 'Appears on the blog and single posts.', 'before_title' => '<h3 class="widget-title">', 'after_title' => '</h3>', 'before_widget' => '<section class="blog-widget">', 'after_widget' => '</section><!-- .blog-widget -->', ) ); register_sidebar( array( 'id' => 'footer-widget-area', 'name' => 'Footer Widget Area', 'description' => 'Appears in the footer.', 'before_title' => '<h5 class="widget-title">', 'after_title' => '</h5>', 'before_widget' => '<section class="footer-widget">', 'after_widget' => '</section><!-- .footer-widget -->', ) );}add_action( 'widgets_init', 'my_widgets_init' );
register_sidebar() in actionregister_sidebar() in actionWe have a sidebar!(Note: you need to go to Appearance → Widgets in the WordPressdashboard, and drag widgets into the area called Blog Widget Areafor this to work.)
wp_enqueue_scriptswp_enqueue_scriptsInstead of including stylesheets in the <head> of your site:
<link rel="stylesheet" href="style.css" type="text/css"/><link href='http://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'>
register and then enqueue them in functions.php:
// Register and enqueue styles and scriptsfunction my_scripts_and_styles() { wp_register_style( 'core', get_stylesheet_uri(), false, '1.0', 'all' ); wp_register_style( 'fonts', 'http://fonts.googleapis.com/css?family=Montserrat', false, '1.0', 'all' ); wp_enqueue_style( 'core' ); wp_enqueue_style( 'fonts' );}add_action( 'wp_enqueue_scripts', 'my_scripts_and_styles' );
Reference: codex.wordpress.org/Plugin_API/Action_Reference/wp_enqueue_scripts
wp_register_style()wp_register_style()This registers the theme’s default stylesheet:
wp_register_style( 'core', get_stylesheet_uri(), false, '1.0', 'all' );
get_stylesheet_uri will grab the URL of style.css. This stylesheet has nodependencies on other CSS files to function, it’s at version 1.0, and it should be loaded onall media (as opposed to just “screen” or “print”).References:
(writes the code for you)codex.wordpress.org/Function_Reference/wp_register_stylegeneratewp.com/register_style/
wp_register_style()wp_register_style()This line registers a Google Fonts stylesheet:
wp_register_style( 'fonts', 'http://fonts.googleapis.com/css?family=Montserrat', false, '1.0', 'all' );
It’s located off-site, so you need to give the full URL. It also has no dependencies, is atversion 1.0, and should be loaded on all media.
wp_enqueue_scripts (for JS)wp_enqueue_scripts (for JS)The same function can be used to register and enqueue scripts, if your theme has any.
To register and then enqueue a file called global.js in your theme, for example, you wouldadd this below your wp_enqueue_style() lines:
wp_register_script( 'global', get_template_directory_uri() . '/js/global.js', array('jquery'), '1.0', true );wp_enqueue_script('global');
wp_register_script()wp_register_script()wp_register_script( 'global', get_template_directory_uri() . '/js/global.js', array('jquery'), '1.0', true );
The first line registers a file called global.js, which is in a folder called “js” in the themefolder. It depends on jQuery to function (so it should load after jQuery does), it’s at version1.0, and it should appear just before the closing </body> tag instead of in the <head>.
References:
(writes the code for you)codex.wordpress.org/Function_Reference/wp_register_scriptgeneratewp.com/register_script/
Conditionally enqueuingConditionally enqueuingWordPress comes with lots of .js files ready to go (they’ve already been registered), butuntil you enqueue them they won’t be loaded in your theme files.
comment-reply.js is one of these pre-registered scripts. It enhances threaded commentson single posts, but you only want it to load when it’s useful. To limit when this file isincluded, add this conditional statement to the end of your my_scripts_and_styles()function:
if ( is_singular() && get_option( 'thread_comments' ) && comments_open() ) { wp_enqueue_script( 'comment-reply' );}
Reference: http://codex.wordpress.org/Function_Reference/wp_enqueue_script#Default_Scripts_Included_and_Registered_by_WordPress
wp_enqueue_scripts in fullwp_enqueue_scripts in fullHere is the full block of code for your functions.php file:
// Register and enqueue styles and scriptsfunction my_scripts_and_styles() { wp_register_style( 'core', get_stylesheet_uri(), false, '1.0', 'all' ); wp_register_style( 'fonts', 'http://fonts.googleapis.com/css?family=Montserrat', false, '1.0', 'all' ); wp_enqueue_style( 'core' ); wp_enqueue_style( 'fonts' ); // Only include the two lines below if you actually have global.js: wp_register_script( 'global', get_template_directory_uri() . '/js/global.js', array('jquery'), '1.0', true ); wp_enqueue_script('global'); if ( is_singular() && get_option( 'thread_comments' ) && comments_open() ) { wp_enqueue_script( 'comment-reply' ); }}add_action( 'wp_enqueue_scripts', 'my_scripts_and_styles' );
excerpt_moreexcerpt_moreBy default, WordPress adds [...] to the end of the_excerpt(). To replace this with anellipsis character and a “Continue reading “[post title]” →” link to the full post, include thiscode in functions.php:
// Append ellipsis and continue reading link to automatic excerptsfunction my_excerpt_more( $more ) { return ' … <a href="'. get_permalink() .'">Continue reading “'. get_the_title() .'” →</a>';}add_filter('excerpt_more', 'my_excerpt_more');
excerpt_more() in actionexcerpt_more() in actionThis:
now looks like this:
add_image_size()add_image_size()If you want WordPress to automatically generate more image sizes than the ones availableunder Settings → Media, you can do so with this code:
// Register custom image sizesadd_image_size( 'slider', 750, 300, true ); // cropped to exactly 750 pixels wide by 300 pixels talladd_image_size( 'narrow', 150, 999, false ); // sized to 150 pixels wide and proportional height (max 999 pixels)
If you’ve uploaded images to your media library before adding this code, you need to run aplugin like Regenerate Thumbnails ( ). Allfuture uploads will create these custom image sizes automatically.
wordpress.org/plugins/regenerate-thumbnails/
Reference: codex.wordpress.org/Function_Reference/add_image_size
image_size_names_chooseimage_size_names_chooseThis code will make your new image sizes available when inserting a picture into a post ora page:
// Add custom sizes to the WordPress Media Libraryfunction my_custom_sizes( $sizes ) { return array_merge( $sizes, array( 'slider' => __( 'Image Slider' ), 'narrow' => __( 'Narrow' ) ) );}add_filter( 'image_size_names_choose', 'my_custom_sizes' );
Make sure the lowercase name above matches whatever you called your new image sizesin the previous step.Reference: codex.wordpress.org/Plugin_API/Filter_Reference/image_size_names_choose
Remove inline [gallery] stylesRemove inline [gallery] stylesThe default WordPress gallery inserts some inline CSS that you may want to override inyour theme. You could use lots of !importants in your stylesheet, but it’s super easy tojust stop them from loading entirely:
// Remove inline WordPress gallery stylesadd_filter( 'use_default_gallery_style', '__return_false' );
add_theme_support( 'post-thumbnails' )add_theme_support( 'post-thumbnails' )Enable featured images for posts and pages with this:
// Add support for featured imagesadd_theme_support( 'post-thumbnails' );
Then in index.php, check for and display the featured image. This code will get the“thumbnail” size, and add the class “alignright”:
if ( has_post_thumbnail() ) { the_post_thumbnail( 'thumbnail', array( 'class' => 'alignright' ) );}
References:codex.wordpress.org/Post_Thumbnailscodex.wordpress.org/Function_Reference/the_post_thumbnail
List of requested features, revisitedList of requested features, revisitedResponsive design ✓
List of requested features, revisitedList of requested features, revisitedResponsive design ✓Homepage with intro paragraph and latest post ✓
List of requested features, revisitedList of requested features, revisitedResponsive design ✓Homepage with intro paragraph and latest post ✓About page with image gallery ✓
List of requested features, revisitedList of requested features, revisitedResponsive design ✓Homepage with intro paragraph and latest post ✓About page with image gallery ✓Blog with widgets in the sidebar ✓
Questions?Questions?@LinnOyenFarley@[email protected]@drollic.ca
Slides, HTML & CSS template, and finished themedrollic.ca/wcto14