IntroductionWelcome| 00:04 | Hi! I am Drew Falkman, and I am going to
show you how to develop custom plugins and
| | 00:08 | widgets for WordPress.
| | 00:10 | In the last few years, the powerful
open-source WordPress software has become
| | 00:13 | popular, not just for basic blogs,
but for full-blown interactive web
| | 00:17 | environments, all made possible by
WordPress's Plugin and Widget interfaces.
| | 00:21 | In this course, we are going to look at
exactly what it takes to build plugin
| | 00:25 | and widgets for WordPress.
| | 00:26 | Using the WordPress Widget application
programming interface, we can build our
| | 00:30 | own widgets, little windows of
functionality, both for use on the front-end of
| | 00:34 | WordPress sites and in
the administrative console.
| | 00:37 | We'll also look at hooks in the form of
actions and filters that we can use to
| | 00:42 | plug our own bits of code into WordPress.
| | 00:44 | This code can interact with post data,
talk to the WordPress database, add new
| | 00:50 | pages into the WordPress admin, and
can extend functionality in many other
| | 00:54 | parts of WordPress.
| | 00:56 | As we go through the process of
building our own custom plugins and widgets,
| | 01:00 | we'll explore just how to access the
inner workings of WordPress, to learn how
| | 01:03 | it can work for you.
| | 01:05 | As a long-time web developer and
blogger, I will share with you what I've
| | 01:08 | learned about customizing my own
sites and the sites of my clients.
| | 01:12 | So let's dive into WordPress and
get started building our own plugins
| | 01:14 | and widgets.
| | Collapse this transcript |
| Using the exercise files| 00:01 | If you are a premium member of the
lynda.com Online Training Library, you have
| | 00:04 | access to the exercise files
used throughout this title.
| | 00:07 | I've placed my exercise files on the Desktop.
| | 00:10 | You can put them wherever you like.
| | 00:12 | There are files for all the
movies that pertain to writing code.
| | 00:15 | They reside in subfolders
according to the chapters.
| | 00:18 | It's not necessary for you to use these files;
| | 00:20 | you can use files of your own in place of them.
| | 00:23 | If you're a monthly or annual
subscriber to lynda.com, you don't have access to
| | 00:27 | the exercise files, but you can
follow along with your own work.
| | 00:30 | So let's get started
writing plugins for WordPress.
| | Collapse this transcript |
|
|
1. Getting StartedWordPress overview| 00:00 | WordPress is more than just blog software;
| | 00:03 | it's become the standard publishing
platform for millions of sites around the world,
| | 00:07 | from celebrity sites like Kim
Kardashian and Margaret Cho, to online publishing
| | 00:11 | powerhouses like the Wall
Street Journal magazine and CNN.
| | 00:14 | WordPress is also a powerful
publishing toolkit. It's robust.
| | 00:18 | It's easy to use, and it's extremely extensible.
| | 00:21 | In this movie, we were going to
take a look at the basics of WordPress.
| | 00:25 | WordPress allows admins and
authors to create posts and pages.
| | 00:29 | These are essentially the
building blocks of blogs.
| | 00:33 | WordPress allows for the integration
of all kinds of different media, for
| | 00:37 | video, for plugging into sites like
Facebook and Twitter, and for performing
| | 00:41 | all kinds of different tasks.
| | 00:44 | It can be installed locally,
| | 00:46 | it can be hosted at WordPress.com, or
it can be run in a hosting environment;
| | 00:52 | it's all up to you.
| | 00:54 | You can view sites through an RSS feed
or through a traditional web site, via a
| | 01:00 | browser or using a mobile device.
| | 01:04 | WordPress.org is the
center for all things WordPress.
| | 01:08 | Here you can find information
about different versions of WordPress.
| | 01:11 | You can find information about development.
| | 01:14 | You can find information about
how to use and extend WordPress.
| | 01:20 | WordPress has an administrator where
site administrators can add new plugins.
| | 01:25 | They can create posts.
| | 01:27 | They can edit the appearance and edit
all the content inside of WordPress.
| | 01:32 | In addition, the look and feel of
WordPress can be changed by using themes.
| | 01:36 | There are over a thousand themes at
the WordPress.org web site that can be
| | 01:40 | downloaded for free.
| | 01:42 | You can create your own custom themes,
or you can start with these themes and
| | 01:46 | add on and make them your own.
| | 01:48 | In addition, the plugin API
allows for the addition of tons of
| | 01:52 | different functionality,
| | 01:53 | for integrating with Facebook, for
outputting an iPhone web site, for generating
| | 01:59 | XML, for social networking, and
literally thousands of other tasks.
| | 02:04 | WordPress has become a powerful content
management system for building more than just blogs.
| | 02:09 | Using the built-in features and
extending WordPress with themes, widgets, and
| | 02:13 | plugins, site admins can have full
control over their web site, with little or
| | 02:17 | no programming experience.
| | 02:19 | In the rest of this course, we are
going to show you how to use PHP,
| | 02:22 | the open-source application
development environment that WordPress uses to
| | 02:27 | further customize WordPress to do
exactly as you, your company, or your
| | 02:30 | clients need.
| | Collapse this transcript |
| Installing WPI for Windows| 00:00 | When you are working with WordPress,
it's a good idea to create a local
| | 00:03 | development environment, so you can
code, test, and even break things without
| | 00:07 | bringing down your web site.
| | 00:09 | The main requisites you need to do
this are a web server, a MySQL database server,
| | 00:14 | and the PHP application server.
| | 00:17 | The easiest way to do
this is to do it all at once.
| | 00:20 | Microsoft now has this all available
through the WPI installation package.
| | 00:25 | You can find the WordPress
specific one, if you go to
| | 00:27 | microsoft.com/web/gallery/WordPress.aspx.
When you get there, go ahead and click
| | 00:35 | Install. This will bring
into the installation screen.
| | 00:38 | You can click Install Now, which
will start the installation process.
| | 00:42 | Go ahead and accept Run for all those,
because we are just going to run the
| | 00:46 | installation right away.
| | 00:48 | When you get this prompt, your browser
is going to say, "Would you like to run
| | 00:51 | the web platform installer?"
| | 00:53 | Go ahead and click that yes, you want to run it.
| | 00:56 | It's an ActiveX control, so you have to
approve it to run inside of your browser.
| | 01:00 | And yes, you can allow this web site
to open a program on your computer.
| | 01:08 | When you download it, you can look and
see what options you want to install in
| | 01:12 | addition to WordPress.
| | 01:13 | It will default to WordPress, and any of
the other things that are required, but
| | 01:17 | there is also some other
software that you may want to include.
| | 01:20 | When you're ready, you can
go ahead and click Install.
| | 01:23 | Notice it will tell you that it's going
to install WordPress, but then it also
| | 01:27 | is required to install some other tools,
including PHP, a web server, and MySQL.
| | 01:35 | Once you've reviewed this, go ahead
and accept the License Terms, assuming of
| | 01:39 | course, you agree with them.
| | 01:41 | Whatever your password that you would like
to have for MySQL, go ahead and enter it here.
| | 01:45 | You're now going to wait for it to
download and install each of the
| | 01:53 | different components.
| | 01:55 | Once you've completed the
installation, the web platform installation is
| | 01:59 | actually going to prompt you for some
configuration for your WordPress site,
| | 02:03 | so you can determine how you want to
set it up. New Web Site is just going to
| | 02:07 | be the default web site, et cetera.
| | 02:09 | In this case, I am going to keep the
WordPress installation and everything
| | 02:13 | else to be the default.
| | 02:16 | You are going to choose your database, which
is going to default to MySQL, which is correct.
| | 02:21 | Then you can decide whether you want
to create a new database or whether you
| | 02:24 | want to use an existing database.
| | 02:26 | Since we just downloaded and installed it,
they are no existing databases, so you
| | 02:29 | can leave it to create a new database.
| | 02:32 | You are going to need to define which
username you're going to use to access the database.
| | 02:37 | If you don't have administrator access,
just use your database username, but
| | 02:40 | since we've just installed it, you are
going to have set up the root password.
| | 02:44 | So make sure to enter what
you put for the root password.
| | 02:47 | The database server is going
to be located in localhost;
| | 02:50 | you can keep this the same.
| | 02:51 | If you want to change the name of
your database, you can do this here.
| | 02:55 | You can enter a unique key for passwords and
secure passwords, authentication if you like.
| | 03:04 | Even if you are using root, you are
going to have to create a new username,
| | 03:08 | so go ahead and put a password in, and
if you want to change the user, you can
| | 03:11 | do that as well, and then
continue when you are ready to go.
| | 03:21 | Once you're done, it will give you this 'success,'
| | 03:23 | and you can go ahead and launch WordPress.
| | 03:26 | So now you can see it's loaded up
WordPress at your localhost, in the WordPress
| | 03:34 | directory or whatever directory you decided.
| | 03:36 | You can now set it up just as we
do any other WordPress web site.
| | Collapse this transcript |
| Installing MAMP for the Mac| 00:00 | When working with WordPress, it's a
good idea to create a local development
| | 00:05 | environment so you can code, test,
and even break things without bringing
| | 00:07 | down your real web site.
| | 00:09 | The main requirements to do so are a web
server, a MySQL database server, and the
| | 00:15 | PHP application server.
| | 00:18 | The easiest way to do this is to
install the whole package at once.
| | 00:22 | This is where we can use
MAMP, if you are on Macintosh.
| | 00:25 | MAMP stands for Macintosh,
Apache, MySQL, and PHP.
| | 00:32 | The first thing you'll need to do is go
to the MAMP web site at www.mamp.info.
| | 00:37 | Here you'll have the
opportunity to download MAMP.
| | 00:41 | It'll tell you information, what the
requirements are in terms of your version of
| | 00:46 | your operating system, and it will also
give you information about MAMP Pro and
| | 00:50 | why you may or may not want to use that.
| | 00:53 | Once you've downloaded it, you'll
have a ZIP file in your hard drive.
| | 00:58 | Double-clicking will create a DMG file.
| | 01:02 | You can then launch this DMG file, which
will launch an installer and essentially
| | 01:07 | set a disk image in your directory.
| | 01:10 | You'll now have the MAMP information, and
all you really need to do to install it
| | 01:15 | is to grab either MAMP or MAMP Pro
into the Application's directory.
| | 01:20 | It will then copy everything over.
| | 01:23 | Now MAMP is installed, so you can go
ahead and close it out, and you can
| | 01:27 | eject the disk image.
| | 01:29 | If you go into the Application folder,
you'll see you now have a folder called MAMP.
| | 01:35 | If you open this up, inside you'll see
there is a file labeled MAMP with some
| | 01:40 | kind of little coin icon.
| | 01:42 | Double-clicking on this will launch MAMP.
| | 01:45 | The first time you load it, you'll get a
warning saying, "This is downloaded from the Internet.
| | 01:49 | Are you sure you want to open it?"
| | 01:50 | And I assure you, it is okay.
| | 01:52 | This will launch the Control Panel,
which tells you whether or not the
| | 01:56 | servers are running.
| | 01:57 | It's from here that you'll be able to start
and stop server, as well as set preferences.
| | 02:02 | It will also open the Start page by default.
| | 02:05 | If you want to open it later,
because you are going to keep this Control
| | 02:08 | Panel open while you are working with your web
sites, you can always click to Open Start page.
| | 02:14 | This is the Start page, and it gives
you information about your server, what
| | 02:18 | port it's running in, what
the password for MySQL is,
| | 02:23 | you can find information about PHP, and there
is some other documentation that you can see.
| | 02:28 | In addition, I can view PHP--
| | 02:30 | it tells me all the information
about the server that I might need--
| | 02:34 | XCache, phpMyAdmin will give me
access to the MySQL database and allow you
| | 02:42 | to edit that from PHP,
| | 02:45 | SQLiteManager gives you access to the
SQLite database that's installed, and then
| | 02:50 | an FAQ to answer some questions of what
else is included. And you can see there
| | 02:54 | is quite a few things in addition to
just the main stack that are installed.
| | 02:58 | So WordPress runs on top of PHP.
| | 03:02 | You are also going to access PHP
through a web server, and the backend of
| | 03:06 | WordPress is controlled by the MySQL database,
| | 03:08 | so you need to have all three
of these things on your computer.
| | 03:12 | The easiest and most flexible way
to get this set up in a development
| | 03:15 | environment on your Mac
is by using MAMP software.
| | 03:19 | Now that you have your environment set
up, let's get started and take a look
| | 03:23 | at WordPress.
| | Collapse this transcript |
| Installing and configuring WordPress| 00:00 | If you've never done so,
installing WordPress is a pretty
| | 00:03 | straightforward process,
| | 00:05 | although having said that, I have had
some times in the past that have been
| | 00:08 | difficult, but things have gotten easier
on the way and hopefully, walking through
| | 00:11 | this with you, I can help you to avoid
any potential 'gotchas' that might come up.
| | 00:15 | I am assuming that you have already
installed MAMP or WAMP, which have the
| | 00:19 | underlying PHP and MySQL Server.
| | 00:22 | If you have not, there are videos
in how to do that you can go through.
| | 00:27 | A good place to start, in terms of
reference, is in the Codex of WordPress,
| | 00:32 | which is their documents.
| | 00:33 | There is a page at codex.wordpress.org/
installing_WordPress that can help you
| | 00:40 | with any 'gotchas' that might come up
or if you have an environment that's
| | 00:43 | different than the one we're using.
| | 00:46 | On Mac, the first thing you are going
to need to do is install the database.
| | 00:51 | In MAMP, the main MAMP screen has a
link to the phpMyAdmin, which allows you to
| | 00:57 | access your database.
| | 00:58 | We are going to need to create a new
database where all of our WordPress data
| | 01:01 | is going to be stored.
| | 01:03 | So on the main screen, there
is a Create new database dialog.
| | 01:06 | So you can type in 'wp_test,'
and you can keep these defaults.
| | 01:12 | Go ahead and click Create.
| | 01:14 | So now our database has been created.
| | 01:16 | So, we're ready to install WordPress.
| | 01:18 | So we have downloaded the ZIP file,
which contains all of the WordPress files,
| | 01:25 | so you can go ahead and
double-click and extract those.
| | 01:28 | We are going to move these into
the root of our web directory.
| | 01:32 | So in Mac, it's in the Applications
directory, in the MAMP directory, and there
| | 01:38 | is a folder in there called htdocs,
where all the HTTP files are stored,
| | 01:42 | and you can drop it in.
| | 01:44 | If you want to name it something
different, you are more than welcome to.
| | 01:47 | The default name is WordPress;
| | 01:49 | you may want to call it
whatever the name of your blog is.
| | 01:52 | Just keep note that this will be part of
the URL, when you go to access your web site.
| | 01:57 | The next step will be to
go to that installation.
| | 02:02 | An easy way to do this is actually to
have this create a configuration file for you;
| | 02:06 | however, it's probably in your best
interest to learn how to create it on your own.
| | 02:12 | So if you look in your installation,
you can see there is wp-config-sample.php,
| | 02:22 | and we are going to want to edit this file.
| | 02:24 | Let's go ahead for now and just open
it in TextEdit and yes, you can open it.
| | 02:28 | There is just a few
configurations that you need to set here.
| | 02:33 | The first one is the name of your database.
| | 02:36 | So, I called mine wp_test;
| | 02:39 | whatever you called yours, you'll enter
there, and then access to the database.
| | 02:44 | By default, if you have the default
installation of MAMP, you are going to have
| | 02:48 | root for the username and root for the
password, and that will be just fine.
| | 02:52 | Everything else you can leave for
the default, and then you're going to
| | 02:56 | need these secret keys.
| | 02:57 | These are used for the cookies to
essentially validate to your domain.
| | 03:01 | There is an easy way to get these.
| | 03:03 | You can go to this web site that's
listed in the document, go ahead, and copy it,
| | 03:11 | and then go back to your web
browser, open a new tab, and paste it in.
| | 03:19 | When you load this, you will then get
all of your keys, which you can then
| | 03:23 | highlight, copy, and go back to TextEdit
and just paste it over these samples here.
| | 03:31 | So now you are all set.
| | 03:34 | You want to save this as
wp-config and you save it as .php.
| | 03:43 | When you're finished, go ahead and save
the file as and remove the sample, and
| | 03:48 | save it as wp-config.php.
| | 03:54 | Now, we can go back to our browser and
our install page, which is whatever your
| | 04:01 | install directory is /wp-admin/install.php.
| | 04:06 | If you reload it, you will see that it
detected your config file, so now it's
| | 04:11 | ready to set you up.
| | 04:13 | So you're going to give a name for
your site, which you can call 'WordPress
| | 04:18 | plugins,' or whatever you like,
| | 04:21 | a username and a password--make sure to
pick something that you can remember and
| | 04:26 | that also, especially if you're up live, is secure--
| | 04:31 | and then in e-mail, this is going to be
the default administrator e-mail that's
| | 04:36 | going to be used by your web site. Don't worry;
| | 04:38 | you can change all of these things
later in the admin. And then we are going to
| | 04:42 | uncheck this which determines whether or not
search engines are going to look at your web site.
| | 04:47 | When you are done, click Install WordPress.
| | 04:50 | WordPress has now been installed,
| | 04:53 | so you can go ahead and log in with
your username and password, and here we are
| | 05:01 | in the WordPress 3.0 dashboard.
| | 05:03 | One other note that I wanted to go over:
| | 05:05 | if you're not installing something on
your local development server, that's okay;
| | 05:09 | you can do this all via FTP.
| | 05:11 | The directories will basically be the
same with wp-admin and all that, and the
| | 05:16 | installation process will,
for the most part, be the same.
| | 05:19 | But most likely, the database is going
to be configured by your hosting provider.
| | 05:23 | Other than that, everything is
going to work pretty much the same,
| | 05:26 | only you are going to be uploading it,
instead of just saving it to the local file.
| | 05:30 | So that's the basic
process of installing WordPress.
| | 05:34 | It's definitely to your advantage to
have a local version of WordPress, so that
| | 05:37 | you can back things up and break
things and undo things and not have to worry
| | 05:42 | about being in the live
environment and that kind of thing.
| | 05:44 | So I highly recommend this part of
the process, and let's go on to develop
| | 05:49 | some plugins.
| | Collapse this transcript |
| Comparing WordPress 3.0 with previous versions| 00:00 | WordPress 3.0, also known as Thelonious--
named after Thelonious Monk--is the
| | 00:05 | first full-numbered WordPress
release since 2.0 came out back in 2005.
| | 00:11 | And there is a good reason for that.
| | 00:12 | WordPress 3 has a ton of
new fixes and enhancements.
| | 00:15 | There's over 1,200 total.
| | 00:17 | One of the main things they did was
they added a new redesign of the interface.
| | 00:21 | They also added a new default theme,
and they added a merge with WordPress MU,
| | 00:28 | which essentially allows you to have
not just one blog for your site, but you
| | 00:32 | can actually manage 10 million
blogs from the same installation.
| | 00:36 | So let's take a look at some
of these new installations.
| | 00:39 | First of all, just a note:
| | 00:41 | keeping up with new versions of
WordPress--when you become a plugin developer--
| | 00:45 | it becomes more and more important,
because every time a new update comes out,
| | 00:49 | some things that used to work may be
disabled, and there will also be new ways
| | 00:53 | that you can do things.
| | 00:54 | So it's very important to keep up with
the new functions and the new hooks and
| | 00:58 | all that kind of stuff.
| | 00:59 | And we'll get into those--what's new
in 3.0--as we go throughout this course.
| | 01:04 | From a high level, some of the new things
they added, the new Admin is a big piece of it.
| | 01:10 | As you can see, it's a little bit
lighter weight, if you're familiar
| | 01:12 | with previous versions.
| | 01:13 | There is actually a super admin
that can be available if you flag the
| | 01:18 | wp_allow_multisite in your
config file, in the wpconfig.
| | 01:23 | That will essentially allow you to
have a super admin, from which you can go
| | 01:28 | into different admins from different blogs;
| | 01:31 | it's a very neat feature.
| | 01:33 | The install process is a little different.
| | 01:36 | You can actually walk through a wizard
to set up your config file and get all
| | 01:40 | your secret keys from the wizard.
| | 01:42 | The Twenty Ten Theme is a new addition.
| | 01:45 | As you can see, it looks a little
different from what was called Kubrick, which
| | 01:49 | was the previous theme that they had,
and it integrates some of the new features
| | 01:53 | that come with WordPress 3,
including the ability to have custom menus.
| | 01:59 | You can add your own menus and customize them.
| | 02:02 | You can also use customized post types.
| | 02:07 | Before, pages and posts were used;
| | 02:10 | now, you can use the same database that
stores posts to have whatever you want.
| | 02:14 | You can add contacts, you can add a
product database, all that kind of stuff.
| | 02:19 | In addition, there's some short link
support, there's a new update process
| | 02:23 | for WordPress, as well as for plugins, and
overall things seem to work more smoothly.
| | 02:30 | So we're going to look throughout
this course on how we can use these new
| | 02:33 | features, as well as the features
that already existed, to make WordPress a
| | 02:37 | great tool for you to use.
| | 02:40 | So overall, WordPress 3 has
brought a number of new features.
| | 02:43 | It brought multi-site functionality, it
has a new lighter weight Admin, it has
| | 02:48 | custom post taxonomies, it has the
ability for customized menus, and a number of
| | 02:52 | other fixes that overall should make
our lives easier as WordPress users.
| | Collapse this transcript |
| Setting up a PHP/WordPress development environment| 00:00 | So in order to develop for WordPress,
it's key to have a programming environment
| | 00:04 | that can help us with our PHP coding.
| | 00:07 | There are a bunch of different tools
out there, and every one ultimately has
| | 00:10 | their own preference:
| | 00:11 | Adobe Dreamweaver, PHP designer, Zend
studio, Aptana PHP, NetBeans and text
| | 00:17 | editors like TextMate. There are tons of
them, really, and if you already have a
| | 00:21 | preference, by all means, go ahead and use that.
| | 00:23 | I like PDT, because it's open source.
| | 00:26 | It's based on Eclipse, which has a
plugin environment so that it can have all
| | 00:30 | kinds of other things that I can jump
around in, if I want to edit JavaScript or
| | 00:34 | XML or something like that, but it
also has all the basic things I need in a
| | 00:38 | development environment:
| | 00:39 | code-hinting, code-completion, error
highlighting, and it's just real simple and lightweight.
| | 00:44 | So let's go ahead and get set out for PDT.
| | 00:47 | So PDT stands for PHP Development Tools.
| | 00:50 | It's part of this Eclipse
project. It's a plugin.
| | 00:54 | It's very well used. The whole project
is led by Zend, who made Zend Studio.
| | 00:59 | The up side is, because it is managed by Zend,
they tend to keep it fairly well up to date.
| | 01:05 | The downside, of course, is there's
not really any incentive for them to add
| | 01:09 | the kind of things that they have in their
studio, but it's a great lightweight tool.
| | 01:13 | So we're going to download it from
eclipse.org/pdt/downloads/ and when we're
| | 01:18 | done downloading, we have this tarball,
and in order to install this tarball,
| | 01:24 | double-clicking will extract it to our Desktop.
In this case, I downloaded it to my Desktop;
| | 01:31 | you might have downloaded it somewhere else.
| | 01:34 | So now we have this folder Eclipse.
| | 01:36 | The installation process, in this case,
is really just a matter of going to your
| | 01:44 | Applications directory and dragging
Eclipse into your Applications directory.
| | 01:50 | You can see, once it's placed in here,
there's a file inside called eclipse with
| | 01:54 | the little sphere icon.
| | 01:56 | That's our application.
| | 01:58 | To make it easy, I am going to grab
this application, and I am going to put it
| | 02:02 | onto my Dock down here, so that I
can launch it whenever I want to.
| | 02:06 | So when you're ready to launch PDT,
simply click the Eclipse icon and go
| | 02:13 | ahead and open it up.
| | 02:15 | It's going to give us an
option first to choose a workspace.
| | 02:18 | All a workspace really is is a
grouping of projects, so we can go ahead and put
| | 02:22 | it in this particular directory.
| | 02:24 | If you want to change directories, that's fine;
| | 02:25 | just point to an empty directory somewhere.
| | 02:29 | When it's done setting up, we'll
get our welcome screen: Welcome to PDT
| | 02:33 | Eclipse for PHP developers.
| | 02:35 | There are some tutorials, samples, and
some other helpful things for you that you
| | 02:40 | may want to check out on your own.
| | 02:42 | For now, I'm just going to ahead and
continue straight to the workbench, which is
| | 02:45 | the actual development part of the IDE.
| | 02:49 | So this is our workspace. Over here is where
all our files and projects are going to be.
| | 02:54 | This is called the Editor.
| | 02:55 | This is where our actual file will be edited.
| | 02:57 | I've got some other helpful what they
call views down here, which can give me
| | 03:01 | information while I am coding,
like problems in my code.
| | 03:04 | And then I have an outline view that
will essentially give me a hierarchical
| | 03:08 | view of my coding files.
| | 03:10 | Anytime you're working in anything in
Eclipse--and PDT is no different--you need
| | 03:14 | to have a project which is
going to organize your files.
| | 03:17 | So to create up new project you can
either go to File > New > PHP Project, or
| | 03:21 | you can right-click in the Explore
here and go to New > PHP Project.
| | 03:26 | This will open the New PHP Project Wizard.
| | 03:29 | You're going to enter a name. I am just
going to call it WordPress, and I like
| | 03:34 | to just point it to the WordPress
installation itself. That way I have access to
| | 03:38 | all the different PHP files inside of it.
| | 03:41 | So create a project in an existing
location and go ahead and point to where all
| | 03:46 | of your WordPress files are.
| | 03:48 | In my cases it's going to be
in MAMP > htdocs > wordpress.
| | 03:55 | You can also set it if you want to use
different versions of PHP depending on
| | 03:59 | if you're trying to sync with a
different environment or something or if that's
| | 04:02 | what you have installed on your
computer, you can select that.
| | 04:04 | By default, it will use whatever PHP it
detects. And we're going to go ahead and
| | 04:08 | Enable JavaScript support.
| | 04:10 | Really all that means is if I open a
JavaScript file, it's going to open in
| | 04:13 | editor, and this is going to have code-
hinting for that as well, which is nice.
| | 04:18 | The next item is the Include Path, which
essentially allows me to choose different
| | 04:23 | places where I might have PHP
files that I am going to use.
| | 04:27 | In this case, I don't have any, so
I am not going to do anything here.
| | 04:30 | So you can see I've got it installed
now, and I have access to all my files.
| | 04:36 | It has detected some issues--
nothing to worry about.
| | 04:39 | I can open any of these files, and
you can see I have all my code-hinting,
| | 04:45 | comments are a different color,
| | 04:46 | HTML is a different color, so it makes it
real easy to see what's going on in my code.
| | 04:51 | And again, I have this
hierarchical view I can go through.
| | 04:55 | Now we've got PDT all set up and
configured, and we're ready to start
| | 04:59 | writing WordPress plugins.
| | Collapse this transcript |
|
|
2. Understanding WordPress Plugin BasicsExploring WordPress plugins| 00:01 | One of the main reasons why WordPress is
so powerful and so well used is because
| | 00:06 | of its extensibility.
| | 00:08 | One of the key elements of its
extensibility is its Plugin API.
| | 00:13 | So let's take a look at what plugins are,
what they can do for you, and why they
| | 00:18 | are great for WordPress administrators,
for developers, and ultimately for the
| | 00:23 | end users of these web sites.
| | 00:25 | The WordPress Plugin Directory is
located at WordPress.org/extend/plugins.
| | 00:31 | All of the plugins here are
distributed through WordPress themselves, though
| | 00:35 | they are made by independent developers
like yourselves, and they are downloaded
| | 00:40 | through the GNU public license,
which means they're all open source.
| | 00:45 | So you can download these. You can use them.
| | 00:47 | You can even edit them if you want to.
And as you can see here, there are 11,000
| | 00:52 | plugins available on this web site that
have been downloaded quite a few times.
| | 00:57 | Some of the featured plugins you can see:
| | 00:59 | WordPress.com Stats, which gives you
statistics on who is viewing what posts,
| | 01:04 | and pages, and things like
that in a very intuitive way;
| | 01:08 | BuddyPress is a great tool; Super Cache
for caching your web site, helping for
| | 01:13 | performance; and this Twitter Widget.
| | 01:16 | Let's go into one of these, like BuddyPress.
| | 01:18 | So you can see for the plugin,
we can look at the Description.
| | 01:23 | It tells you what it is.
| | 01:25 | Basically, what BuddyPress is is it's
the ability to add some social networking
| | 01:29 | into your blog or into your
web site quickly and easily.
| | 01:32 | Again, you do this at one click of a
button, create some settings, and you
| | 01:35 | are off in running.
| | 01:37 | If there is any installation, it will
tell you a little bit about how to do
| | 01:40 | that, beyond the normal. There is
an FAQ, Frequently Asked Questions,
| | 01:46 | Screenshots, so if you want
to see what it looks like.
| | 01:49 | You can see it's very much like Facebook-esque
thing, integrated right within your web site.
| | 01:54 | Then there is Other Notes,
history of changes, and then maybe some
| | 01:59 | statistics about it,
| | 02:01 | how often it's downloaded.
| | 02:02 | Here you can see we have a version number.
| | 02:04 | It will tell you compatibilities of
which version of WordPress it works well
| | 02:09 | with, and sometimes you will even
find the ability to make donations.
| | 02:13 | Another one that I like is Recent Tweets,
and there is quite a few out there like this.
| | 02:18 | Recent Tweets is actually a widget plugin.
| | 02:20 | So you can see this is what it
looks like on a user's web site.
| | 02:23 | It just shows the most recent
tweets that the owner of this blog made.
| | 02:27 | Here is the configuration aspect
of it that a site owner can use.
| | 02:31 | So they can give it a Title, Recent Tweets.
| | 02:33 | They put their Twitter username, so that
it can go out and grab that information,
| | 02:37 | how many tweets you want to show,
| | 02:38 | if you want the Follow Me link and
if you want to have a link for the
| | 02:43 | Recent Tweets plugin.
| | 02:44 | In addition to all of these plugins
available at the WordPress Plugin Directory,
| | 02:49 | there are also companies out
there that are selling these plugins.
| | 02:53 | You can see Broken Link Checker, Events Manager;
| | 02:56 | these are all located at wpplugins.com.
| | 02:59 | So it's a little application store that
you can download these and install them
| | 03:02 | right into your WordPress.
| | 03:04 | There are some larger ones that are
independently distributed, like shop,
| | 03:07 | located at shopplugin.net.
| | 03:10 | This is a full ecommerce system
that you can plug right into your
| | 03:13 | WordPress installation.
| | 03:15 | So all in all, there are a lot of
plugins available to plug into WordPress.
| | 03:20 | The WordPress.org Plugin Directory
provides you access to a lot of different
| | 03:25 | tools, and like I said earlier, all
of these plugins are open source.
| | 03:29 | So you can plug these directly into your
web site, and you can also access them,
| | 03:33 | and modify them if you want to.
| | 03:35 | So it's always a good start, whenever
you develop plugins, to take a look here
| | 03:39 | first and see what's available.
| | Collapse this transcript |
| Administering plugins from the WordPress admin| 00:01 | Let's go ahead and log in to the
WordPress admin console and have a look at how
| | 00:04 | site administrators work with plugins.
| | 00:07 | We'll look at how you can install
and remove plugins, we'll look at the
| | 00:10 | upgrading process, what it means to
activate and deactivate a plugin, and finally
| | 00:15 | how to delete a plugin
that's already been installed.
| | 00:17 | So to log in to the admin console,
| | 00:19 | you go into whatever the URL of
your WordPress installation is--
| | 00:23 | In our case with map, it's localhost:8888
/WordPress/wp-admin will always be your
| | 00:31 | administrative console--and log in
with the username and password that you chose
| | 00:36 | during the installation process.
| | 00:37 | So over here on our left, you can
see I have this Plugins section.
| | 00:43 | This is where administrators go to
administer all the existing plugins, and you
| | 00:47 | can see it's a list of all the plugins
that are currently installed in their
| | 00:51 | WordPress environment.
| | 00:53 | In this case, we have three:
| | 00:54 | the two defaults--one is called
Akismet which is a web service that checks
| | 00:59 | comments to determine if they are spam
or not, we have Hello Dolly, which is just
| | 01:03 | a simple basic plugin that you can take
a look at to see how plugins work--and
| | 01:07 | then I have this Tweet This, which I had
added later so that I can use Twitter to
| | 01:12 | tweet certain posts.
| | 01:14 | Notice for each one, you have a plugin name,
you have a description of what the plugin does,
| | 01:19 | you a version number, you have whoever
the author was of the plugin and very
| | 01:24 | often a link to their site, and finally
a link to the plugin site which would go
| | 01:28 | directly to the site that host the plugin.
| | 01:31 | If I want to add new plugins, I can do
those directly from the administrator.
| | 01:35 | I simply click the Add New Link.
| | 01:37 | I can filter by Featured,
Popular, Newest, Recently Updated.
| | 01:43 | I can do different tags that they have--
| | 01:45 | these are the popular tags that have
been searched at the WordPress directory--
| | 01:49 | or I can search directly from here.
| | 01:51 | So if I were to search for something
like 'social networking,' you can see I get
| | 02:00 | a number of widgets.
| | 02:01 | They all have a rating and an
explanation of what they all are.
| | 02:05 | This is coming directly from the web
site, the WordPress.com Plugin Directory.
| | 02:10 | If I want to install any of these--
say this one, it looks pretty good--
| | 02:14 | I can click the Install Now button.
| | 02:17 | When I acknowledge it, it will actually
download a ZIP file into our WordPress
| | 02:23 | installation and extract
it into the Plugin Directory.
| | 02:26 | So now that it's all been installed, I
can go back to my Plugins page, and I can
| | 02:30 | see the Social Links plugin has been
added to my WordPress installation.
| | 02:36 | If I ever want any of these plugins to be
used, I need to click the Activate button.
| | 02:42 | By default when they're installed,
they're not actually going to run.
| | 02:46 | They're just going to put the
files onto your WordPress installation.
| | 02:49 | So to make them actually run,
you need to activate them.
| | 02:53 | Once they're activated, then they'll work.
| | 02:55 | If you ever want to turn them off,
you can go ahead and deactivate them.
| | 02:59 | Deactivating won't uninstall them.
| | 03:02 | In fact, it'll save any settings or
database information, typically, but it
| | 03:08 | essentially turns it off.
| | 03:10 | So if you ever have an issue come up,
a conflict with different plugins or
| | 03:13 | something, you can just try to deactivate.
| | 03:16 | In fact, usually if there's an error in
your WordPress installation, one of the
| | 03:19 | first things you can do is
deactivate your plugins and see where you go.
| | 03:24 | The Bulk Actions menu allows you to
do a lot of these functions to multiple
| | 03:29 | plugins at the same time.
| | 03:32 | So by selecting this top
check box will check all of them.
| | 03:36 | You can then activate all,
deactivate all, upgrade all, or delete all.
| | 03:40 | If you were to look at a live web site,
this is my mmmstuff.com blog where I
| | 03:45 | post some nifty little things
that I find on the Internet.
| | 03:48 | As you can see, I haven't
updated to WordPress 3.0 yet--
| | 03:50 | in fact, it's prompting me up here that I
should, and I will, but I haven't done it yet.
| | 03:56 | This is WordPress 2.92.
| | 03:58 | You can see here in my Plugins page
that I have a number of messages here that
| | 04:04 | tell me there is a new version available.
| | 04:06 | So anything that's hosted at the
WordPress.com Plugin Directory will tell me
| | 04:11 | when there's a new version available
inside my administrator, so that I can
| | 04:15 | download directly from there.
| | 04:17 | So, for example, this list category post,
| | 04:20 | if I do want to upgrade it, I
click Upgrade Automatically.
| | 04:23 | It will then download all the files,
just like it did when I installed the
| | 04:27 | plugin, but it will also
reactivate the plugin for me.
| | 04:32 | You can see it reactivated successfully.
| | 04:35 | Now when I go back, I now
only have seven upgrades to go.
| | 04:38 | One of the things that you can see in
the differences here is that in the Bulk
| | 04:42 | Actions menu I don't have upgrade available.
| | 04:45 | That was something that was added new to
Bulk Update at the same time in WordPress 3.0.
| | 04:51 | So that's the basics of interacting with
plugins from the WordPress admin console.
| | 04:56 | From there, WordPress
administrators can add new plugins,
| | 05:00 | they can update their existing plugins,
they can turn them on and off, and when
| | 05:04 | they're done finally, they can delete them.
| | 05:07 | One more thing I want to show you that
will be relevant to plugin development as
| | 05:11 | we go along is this Edit button.
| | 05:13 | If you click on the Edit button, you can
actually see the source file of your plugins.
| | 05:18 | We are not going to get into this
yet, but this is what we're going to
| | 05:21 | be writing.
| | Collapse this transcript |
| Exploring where plugins reside| 00:00 | The process of installing
WordPress plugins is really a pretty
| | 00:04 | straightforward one.
| | 00:05 | Anytime you install a plugin, really
all you're doing is copying a folder into
| | 00:10 | a specific directory in
the WordPress environment.
| | 00:14 | Sometimes we can download plugins
from third-party sites that aren't through
| | 00:18 | the WordPress directory.
| | 00:19 | In the case of CLICKY--although you can
get to get through the WordPress site--
| | 00:22 | they do allow you to download
it directly from their web site.
| | 00:25 | So you can see I can click Download
the Clicky WordPress Plugin now, which
| | 00:32 | downloaded the plugin.
| | 00:33 | I can than manually install this from
this Plugin screen in the Add New and
| | 00:40 | then clicking on Upload.
| | 00:42 | What this will do is I can upload a ZIP file.
| | 00:45 | It will extract the ZIP file
and put it into that directory.
| | 00:49 | So you can see I've got clicky
here in my downloads directory.
| | 00:54 | Install Now, and it's installed.
And really, basically this is all that's
| | 00:59 | happening with the widgets and the
plugins that we are getting from the
| | 01:02 | WordPress directory.
| | 01:03 | It's just downloading a ZIP file
from that web site, extracting it, and
| | 01:07 | uploading it to a specific folder.
| | 01:09 | If we were to take a look inside the
development environment--I'm in PDT now--
| | 01:15 | this is my WordPress installation.
| | 01:18 | There's a number of directories in here.
| | 01:20 | One of them is content and
under content, I have plugins.
| | 01:26 | So I had to refresh them there by right-
clicking on the Refresh option to see any
| | 01:31 | new ones that existed since the
last time I was in this environment.
| | 01:34 | You can see here is clicky.
| | 01:36 | If I were to open it up, you can see
there's a number of different images.
| | 01:40 | There is some language information, so
they can work in different environments.
| | 01:46 | There's a readme.txt file, which tells some
information about it, and there is a PHP file.
| | 01:54 | This is the actual plugin itself, and
we'll get more into how to develop these later.
| | 02:00 | You can also see the other plugins I have.
| | 02:02 | Hello php is the Hello, Dolly.
| | 02:04 | akismet, we talked about earlier.
| | 02:08 | social-links and tweet-this are also
third-party ones that I've downloaded.
| | 02:13 | You can see in some instances they install
as directories, or they can install as files.
| | 02:19 | In any case, all plugins in the
WordPress environment are simply a php file
| | 02:26 | either on its own or in a
directory that's uploaded to the WordPress
| | 02:31 | installation/wp-content/plugins directory.
| | 02:36 | Whether you download them from the
WordPress Plugin Directory, or you upload
| | 02:41 | your own ZIP, or you actually manually
copy a folder into here, any of those
| | 02:45 | methodologies will work.
| | 02:47 | Once they're in here, they will
become available as a WordPress plugin.
| | Collapse this transcript |
| Introduction to hooks| 00:01 | When you get down to it, there's one
key element that allows for WordPress
| | 00:04 | plugins, and that's the hook.
| | 00:06 | Hooks are also known as actions and filters.
| | 00:09 | They're basically points in the
WordPress life cycle that go out and look for
| | 00:12 | registered programming pieces to execute.
| | 00:15 | This can occur when a user requests a
page, when an admin page is created, when
| | 00:21 | an admin menu is created, when the
author submits a post, or at myriad of other
| | 00:25 | places throughout WordPress.
| | 00:27 | All of these pieces have hooks related to them.
| | 00:31 | All we need to do to make a plugin
work then is register a function to a
| | 00:36 | specific hook, and bam:
| | 00:38 | that's really all there is to it.
| | 00:40 | That piece of code will
execute when that hook occurs.
| | 00:43 | WordPress hook started back in version 1.2.
| | 00:47 | Before that, WordPress
hacking was literally that.
| | 00:50 | It was taking the original
code and hacking away at it.
| | 00:53 | When they added hooks, essentially
what they did is they added points in the
| | 00:58 | code that would look to see if anything was
registered to execute at that particular point.
| | 01:05 | So, for example, when the user
submits a comment, there is a hook there.
| | 01:09 | If you want something to happen, then you
can write a function that will send out
| | 01:13 | an e-mail, and then you add it into that hook.
| | 01:17 | Or let's say you want to add
something to a menu in admin.
| | 01:20 | You can write a function that generates
some user interface, some display, and
| | 01:24 | then simply add a hook.
| | 01:26 | That hook will then add your piece of user
interface into the display of the Admin menu.
| | 01:32 | So the process of plugin development
is really writing a function that does
| | 01:37 | something, then finding the correct
hook when you want that thing to occur, and
| | 01:43 | simply registering your function with that hook.
| | 01:45 | As a WordPress developer, a key part of
getting started is using the WordPress Codex.
| | 01:51 | The Codex is really the user manual for
WordPress, for everyone, whether they're
| | 01:56 | an administrator or developer.
| | 01:58 | But from a developer standpoint,
we have a list of all kinds of stuff:
| | 02:02 | specifically here at
codex.WordPress.org/plugin_API.
| | 02:08 | It's a great jumping point to get started.
| | 02:11 | It will explain hooks, actions and
filters, what they are, and it will also tell
| | 02:15 | you some examples of actions and also
of filters, and we'll talk about the
| | 02:21 | distinctions in these later
when we get into development.
| | 02:23 | In addition, Adam Brown at Brigham Young
also has a database of all the WordPress
| | 02:30 | hooks, called the WordPress
Hooks Database at adambrown.info.
| | 02:34 | So the key to plugins is the hook.
| | 02:37 | The process of developing a plugin is
really the process of writing a function,
| | 02:41 | registering it with a hook, and then
whenever that occurs in that process when
| | 02:46 | the user uses your plugin,
your functionality will occur.
| | Collapse this transcript |
|
|
3. Building a WordPress PluginCreating the plugin PHP file(s)| 00:00 | Just as every journey starts with the
first step, every application starts with
| | 00:04 | a single piece of code.
| | 00:05 | In the case of WordPress plugins, we
start by creating the main PHP plugin file.
| | 00:10 | This file has a predefined comment
section, called the headers, that is used by
| | 00:15 | WordPress to essentially register
and make your plugin available to a
| | 00:18 | WordPress installation.
| | 00:20 | In order to create this, we are going to
go in to PDT, and we are going to go in
| | 00:24 | to our plugins directory,
which is in wp-content/plugins.
| | 00:26 | We are going to right-click,
and go to New > PHP File.
| | 00:33 | You can name it whatever you want.
| | 00:36 | In this case, we are just going to call it
first_plugin and hit enter, and here we have it.
| | 00:41 | So I am going to start with a comment
block, and inside this comment block, I
| | 00:45 | need to put some standard information.
| | 00:47 | I am going to put Plugin, and it's important
you spell it the same way as I'm doing here.
| | 00:55 | This is part of the WordPress standard plugin.
| | 00:57 | "Drew's Awesome Widget." The Plugin URI,
| | 01:07 | it's going to be a web site that will
have information about this plugin.
| | 01:11 | So it would probably be a web
site somewhere in your domain.
| | 01:15 | So "falkonproductions.com/first_plugin."
| | 01:22 | Then you put a description of your plugin.
| | 01:24 | "This plugin does awesome things."
| | 01:29 | The Author, that's you;
| | 01:33 | the version, 1.0, and lastly the
Author URI, which is your web site.
| | 01:44 | When you are done, you can go ahead and save it.
| | 01:48 | If you log into your WordPress
administrator wp-admin and go to the Plugins
| | 01:55 | page, you will now see your
plugin has been registered.
| | 01:59 | All this information was obtained by
going through and looking in the Plugins
| | 02:04 | Directory and finding any PHP
file that had those comment headers.
| | 02:08 | It then outputs everything here.
| | 02:10 | Notice it is not activated, so
it's not actually plugged in.
| | 02:13 | Even if it were, there is nothing there;
| | 02:15 | I haven't written any functions
or created any hooks or anything.
| | 02:18 | But it does have the name, my plugin,
the description, the version, the author
| | 02:23 | name, and the links to my web site
and a link to the plugin web site.
| | 02:27 | One last thing I wanted to go over is licensing.
| | 02:30 | The standard license is the GNU, General
Public License's version 2, and you can
| | 02:36 | find it at codex.WordPress.org/Writing
_a_Plugin, and you can see it has the
| | 02:44 | standard license built-in.
| | 02:46 | It's not necessary that you include this,
but it is fairly customary, especially
| | 02:50 | if you are going to post it
on the WordPress.com site.
| | 02:54 | So that's the beginning part of
creating a PHP plugin: creating the comment
| | 02:59 | header, describing your name, the
URI of the plugin, the description, the
| | 03:04 | author, the version, and then your URI as well.
| | 03:07 | This will register it in a WordPress
installation, and then anyone can start
| | 03:10 | to use your plugin.
| | Collapse this transcript |
| More on hooks: Actions and filters| 00:00 | As you know, hooks are what make plugins work.
| | 00:02 | There are two basic kinds of hooks:
| | 00:04 | actions and filters.
| | 00:06 | Each of them serve a different purpose.
| | 00:07 | Actions are performing all kinds
of tasks in WordPress processing.
| | 00:12 | Filters are specifically for filtering
text, either before it could send to a web
| | 00:16 | page or before it can save to the database.
| | 00:18 | We are going to talk about these hooks
and how you can register and use them in
| | 00:22 | your custom plugins.
| | 00:23 | So first of all, filters are how we parse text.
| | 00:27 | So you can see here in the plugin API
at the codex.wordpress.org, there are
| | 00:32 | some functions that
relate specifically to filters.
| | 00:35 | The key ones are going to be has_filter,
which can determine if a filter exists,
| | 00:39 | add_filter which we'll used to add a
new filter, and remove_filter if you ever
| | 00:44 | want remove one of your existing filters.
| | 00:46 | There is different categories on filters,
and you can find them in the filter reference.
| | 00:51 | It's in the plugin API, in a folder
called Filter_Reference, and this has a list
| | 00:57 | of all kinds of filters.
| | 00:59 | You can see Database Reads and Writes
for the Post and Page attachment, Comment
| | 01:05 | and Trackbacks, Categories, Links,
Date and Time, Author and User,
| | 01:10 | basically all of the different places in
WordPress where they are accessing some
| | 01:14 | kind of textual data.
| | 01:16 | So anytime you want to make changes to
a text, either before you save or before
| | 01:19 | you send it to a web page,
this is where you can do it.
| | 01:23 | Actions on the other hand, are
where we perform some specific task.
| | 01:28 | When something is happening, when a comment is
being submitted, or when a menu is being created,
| | 01:33 | all of these things are actions.
| | 01:35 | So actions function a little
differently because they don't necessarily have
| | 01:39 | to do with text specifically.
| | 01:41 | They usually have to do with some
sort of function that's going on.
| | 01:44 | But the way they behave is
very much the same as filters.
| | 01:47 | So the functions are quite similar;
| | 01:49 | has_action will allow to determine if
one exists, add_ action will allow you
| | 01:53 | to essentially hook into that action, and
remove_action will also allow you to remove it.
| | 02:00 | Just like with filters, there
is a reference at the codex under
| | 02:04 | Action_Reference, in the plugin API.
| | 02:06 | Again, you can see this has broken down
by the different types of places where
| | 02:12 | these actions occur.
| | 02:13 | A typical request, you can see, there is
a number of different action hooks that
| | 02:18 | takes place in the request.
| | 02:20 | Wp_footer, for example, runs when
the user's footer is loaded, both in the
| | 02:25 | backend and in the front-end.
| | 02:26 | wp_enqueue_script is what's used to
generate all of your JavaScript calls, and so forth.
| | 02:32 | So you'll get very familiar with
these throughout the course and definitely
| | 02:35 | throughout the process of filming plugins.
| | 02:38 | So filters and actions are the
different types of hooks that can be used in the
| | 02:42 | WordPress plugin environment to perform tasks.
| | 02:45 | The key thing to remember is that
filters are used when you want to do something
| | 02:49 | to the text, either before the text is
sent to the database or the browser or
| | 02:53 | wherever else, if it's going out to
an iPhone or something like that.
| | 02:57 | Actions, on the other hand, are hooks that
are called when something happens in WordPress:
| | 03:01 | a post is saved, an admin menu has
generated, the footers is being created, and
| | 03:06 | all that kind of stuff.
| | 03:07 | We can then create our own functions,
set them to these filters and actions, and bam:
| | 03:13 | we've got our plugins.
| | Collapse this transcript |
| Installation and activation| 00:00 | The first step for an administrator to use a
custom plugin in WordPress is to install it;
| | 00:04 | however, in order for the plugin to
actually work, it needs to be activated.
| | 00:09 | The activation process allows for a
plugin to perform some tasks that enable
| | 00:14 | the plugin to work.
| | 00:15 | Maybe some things will be done on
activation, like creating a database table, but
| | 00:19 | for the most part, it's going to allow
code to execute, which is going to add
| | 00:22 | hooks in and maybe do some other things as well.
| | 00:25 | In addition, it allows for plugin
administrators to turn on and off plugins,
| | 00:30 | without having to worry about actually
getting rid of all the files and whatnot.
| | 00:34 | As we've discussed earlier, the process
of installing a plugin in WordPress is
| | 00:38 | really just a matter of putting a PHP
file or folder with a PHP file in it
| | 00:44 | into the plugins directory of WordPress.
| | 00:47 | However, until you actually activate
it, that code will never be looked at.
| | 00:52 | When you activate it--for example,
Hello Dolly, I'll activate--that will then
| | 00:57 | tell WordPress that on every subsequent request
it needs to include that file in its execution.
| | 01:04 | So, this is the key point:
| | 01:06 | anything that's not in a function in
that file will be executed on every request.
| | 01:11 | So you can see now, up here I've got the
display of what the Hello Dolly plugin is doing.
| | 01:17 | When you go from page to page, it
simply puts out some other line from Louis
| | 01:23 | Armstrong's Hello Dolly song.
| | 01:25 | So let's go back into our plugin.
| | 01:28 | This is a little plugin that
eventually is going to output some copyright
| | 01:31 | information, just a little stamp
copyright, whatever year, whatever company, et cetera.
| | 01:37 | Before I do all that, I do want to
have a check to make sure that I'm using
| | 01:41 | WordPress version 3.0 or higher.
| | 01:43 | So, one way to do that
is to put an if statement.
| | 01:47 | Now, in order to test the version, I
need to get a variable called wp_version.
| | 01:53 | So, I'm going to actually declare it
up here, by saying global $wp_version;
| | 01:59 | that will then make that
variable available to me.
| | 02:02 | Then I can use the version_compare
function from PHP to test the WordPress
| | 02:08 | version with some version that I say--
so 3.0 for example--and then I can
| | 02:16 | determine how I want to test it; > or >=.
| | 02:20 | So, in this case what I want to do is if
the version is greater than or equal to,
| | 02:26 | then I will execute some
statement inside my if statement.
| | 02:30 | Now, what I actually want to do is I
want to say, if it's not greater than or
| | 02:35 | equal to--so I am going to use this
little 'not' modifier and in here I am going
| | 02:39 | to say 'die,' and I'll put a message, 'You
need at least version 3.0 of WordPress to
| | 02:48 | use a copyright plugin.'
| | 02:50 | There is also an exit statement
which works basically in the same way.
| | 02:54 | Now, I can save it.
| | 02:56 | Now upon activation, every subsequent
request now is actually parsing that file.
| | 03:06 | Since I have WordPress version
3.0 or higher, it's not a problem;
| | 03:10 | however, if I were to change this and
say I require version 3.2 or higher,
| | 03:16 | and then refresh it,
| | 03:18 | you will see it actually executes this code,
and it aborts the processing of the code.
| | 03:25 | So, in order for a plugin to work, it
needs to be not only installed, but it
| | 03:30 | actually needs to be activated as well.
| | 03:32 | Once it's activated, however,
everything that is not located inside of the
| | 03:37 | function will be executed.
| | 03:38 | So it's something you want to be careful of but
also something that you can take advantage of.
| | 03:42 | All plugins have to be
installed and activated in order to work.
| | 03:45 | Installation, as we saw, is just a
matter of placing a file in the right
| | 03:48 | directory, but the plugin won't
do anything until it's activated.
| | 03:52 | Once it's activated, however, it's
going to be included in all requests inside
| | 03:56 | of the WordPress environment.
| | 03:58 | This can be a very dangerous thing, but
this is also a very powerful thing, and at
| | 04:02 | the end, this is what makes our plugins work.
| | Collapse this transcript |
| Writing activation code| 00:00 | Activating a plugin is required for
that plugin's code to be included in
| | 00:04 | WordPress's execution.
| | 00:05 | WordPress developers have the option, if
they want to, to execute some additional
| | 00:09 | code when the plugin is activated.
| | 00:10 | For example, your plugin might need
some additional database tables or maybe
| | 00:15 | you want to set some options up, or
maybe you want to check for software
| | 00:18 | requirements, like PHP5 or a
certain version of WordPress.
| | 00:21 | Whatever you want to do, activation
is the time to do that kind of thing.
| | 00:25 | In order to utilize these features, we
are going into our activate_plugin.php.
| | 00:31 | It's just a simple PHP
file I created with comments.
| | 00:34 | I haven't done anything in here yet.
| | 00:35 | I am going to create a function, and
this function is going to do something when
| | 00:42 | the plugin is activated.
| | 00:43 | So, we'll just call my_plugin_activate,
and in here you could do whatever you want:
| | 00:49 | you could create your database, you could
create your options--whatever you want to do.
| | 00:54 | For now, we are just going to write
something into the error_log, my plugin activated.
| | 01:02 | So that's all it's going to do.
| | 01:04 | Now, if I were to save this and run
this in the WordPress environment, even if
| | 01:08 | this plugin were activated, nothing
would happen, because if you look, there's
| | 01:11 | nothing that occurs outside of this function.
| | 01:14 | There is no code that will execute, and
functions will only execute if you've
| | 01:18 | associated them with something
where they're going to execute in.
| | 01:22 | So to make it execute on activation,
there's a special function called
| | 01:25 | register_activation_hook.
| | 01:29 | You specify the file that contains a
function that you want to execute and the
| | 01:33 | name of the function you want to run
when the user activates the plugin.
| | 01:37 | So we are going to use the special
variable __FILE--and you can see it comes
| | 01:42 | up in the code-hinting--which represents the
current file that you're writing the code in.
| | 01:47 | Then we are going to specify the
name of our function: my_plugin_activate.
| | 01:51 | So, now when I activate this,
this function will execute.
| | 01:56 | The reason why is because once I
activate this plugin, any code that's not in the
| | 02:01 | function--which specifically will be
this line of code--will be executed, which
| | 02:05 | will set up that function so that it
will run when the user activates it.
| | 02:10 | So, here you can see in my Plugin
page, I have my activated plugin.
| | 02:15 | So I am going to refresh it, just
to make sure that that code executes
| | 02:19 | to register that hook.
| | 02:21 | Then I call activate.
| | 02:24 | Now, I can look in my php_error.log,
and you can see it said, at this day and
| | 02:32 | time, my plugin was activated.
| | 02:35 | If I want to do something on
deactivation, the process is nearly identical.
| | 02:41 | You write a code--a function rather--
my function, deactivate, you do whatever
| | 02:47 | it is you want to do inside of
there, and then instead of calling
| | 02:52 | register_activation_hook, we call register_
deactivation_hook, my deactivate, and save it.
| | 03:03 | Now refresh to make sure that it gets
executed, deactivate, I can go back to my
| | 03:10 | log, open it again, and we'll
see that it's been deactivated.
| | 03:18 | So in order for a plugin to work in
a WordPress installation, it has to
| | 03:22 | first be activated.
| | 03:24 | This activation process can be a
great time to set up anything you need for
| | 03:27 | the plugin to work:
| | 03:28 | creating database tables, setting option fields.
| | 03:31 | We'll learn about these things in later units.
| | 03:33 | Whatever it is you want to do, you can
use the register_activation_hook function
| | 03:37 | to take care of this.
| | 03:39 | In addition, if you want to do
anything else on deactivation, you can use the
| | 03:43 | register_deactivation_hook.
| | Collapse this transcript |
| Writing an action| 00:00 | Actions are the events of WordPress.
| | 00:02 | That is to say when you want something
of your own making to happen inside of
| | 00:06 | WordPress, you are going to use an action.
| | 00:08 | If you want something to happen when a
menu is generated, you'll use an action.
| | 00:11 | If you want something to happen when the
users saves a comment, you use an action.
| | 00:15 | So the process of writing plugins that
do things is really a process of writing
| | 00:19 | what you want done, then associating
that with one of WordPress's many actions.
| | 00:23 | To do that, we are going to use the add
action method, which we will talk about
| | 00:26 | in a second. But the first
thing we need is a plugin.
| | 00:29 | So I have created this file here, cc_
comment.php in my plugins directory.
| | 00:34 | You can see I have set up all the
comment information so that WordPress
| | 00:37 | administrator can read it and see it.
| | 00:39 | Now I need to essentially write the function
that's going to do what it is I want to be done.
| | 00:44 | In this case, I am going to set it so
that whenever someone submits a comment
| | 00:48 | on the front-end of the web site,
it's going to send a CC e-mail to some
| | 00:52 | particular e-mail address.
| | 00:54 | So we will create a new
function. We'll call it cc_comment.
| | 00:58 | And it's a good idea to create
your functions with some special name.
| | 01:02 | You may want to get more specific
than this, so that it doesn't collide with
| | 01:06 | other functions in the WordPress environment.
| | 01:08 | In the function itself, I want to
have access to the _request scope.
| | 01:13 | That way I can get the information
that has been submitted from the form.
| | 01:18 | In order to do that in my functions, I
am going to declare it using the global
| | 01:22 | keyword and then typing $_REQUEST. I now
have access to the request scope, and I
| | 01:28 | can use whatever
variables I want to inside of it.
| | 01:31 | The next that is to set up some
variables that are going to store
| | 01:34 | information that's going to be used
by the e-mail. to, we can send this to
| | 01:40 | drew@somewhere.com.
| | 01:43 | We will set a subject, and in the subject,
we are going to say, "New comment posted
| | 01:51 | @ yourblog," and of course we could use
some other ways to access what their blog
| | 01:56 | name is from the information, but for
now we are just going to keep it simple.
| | 02:00 | Then _REQUEST, and the request scope is
all stored in associative array, and the
| | 02:06 | name of this subject field is subject.
| | 02:09 | Then I am going to set the actual message.
| | 02:12 | I'm going to say, "Message from:"
| | 02:15 | and note that I'm using the dot,
which is just the concatenator in PHP.
| | 02:19 | So in a sense, you just append this on to
my string, REQUEST, and then there's a
| | 02:24 | name field which has the name of the
user that they submitted. And we will say,
| | 02:30 | 'at e-mail,' and then we can use a
concatenator add REQUEST, e-mail.
| | 02:41 | Then we can use a concatenator
and add on the actual message.
| | 02:46 | And I am going to add a new line,
and that field is called comments.
| | 02:52 | So now I have got all my variables set up.
| | 02:55 | I am going to actually do the mailing.
| | 02:56 | I am going to keep it simple and use
the built-in PHP mail function, and you
| | 03:01 | can see the arguments it takes. The first three are
the to address, the subject, and the message, and I
| | 03:07 | don't need to send any
additional headers or parameters.
| | 03:09 | So I go ahead and just pass the fields
that I have just created, to,$subject.
| | 03:15 | So there we have it.
| | 03:16 | That's my function.
| | 03:17 | This however is never going to execute.
| | 03:19 | If you remember, when I activate a plug-
in, it will run any code that's not in
| | 03:23 | this function, and currently, I don't
have any code that's not in this function.
| | 03:27 | So what I want to do is outside of this
function, I want to add this is an action.
| | 03:31 | So I use the add_action method, I pass
the name of the action--in this case it's
| | 03:37 | called comment_post, and I know this
from the WordPress Codex--and then the name
| | 03:43 | of the function that I want to
execute for that action: cc_comment.
| | 03:47 | So that's all it takes.
| | 03:49 | If I now go to my WordPress Plugins
page, you can see my plugin right here.
| | 03:54 | When I activate it, it will now set it
up so that any future comments that are
| | 03:59 | submitted will send an e-mail along with it.
| | 04:11 | If you should ever want to remove an
action, you can use the remove_action, and
| | 04:16 | it takes the same arguments.
| | 04:18 | You specify the name of the action
and then the name of the function that
| | 04:21 | you want to remove.
| | 04:22 | Of course, we don't want to do this
because we've only just added it, but it
| | 04:26 | gives you the flexibility to do that.
| | 04:28 | So WordPress actions really allow us to
get into WordPress and do all kinds of
| | 04:33 | stuff in all kinds of places.
| | 04:35 | We looked at one particular
action, but there are tons of these.
| | 04:37 | There are hundreds of them.
| | 04:39 | The way I like to think of them is
they're like power outlets around an empty
| | 04:42 | house: all you need do is plug your
appliances in wherever you want to, and then
| | 04:46 | you can have that in that room.
| | 04:48 | There's one less thing to mention is
there's a third argument here, which is priority.
| | 04:53 | Priority allows you to determine
what order you want these to execute in.
| | 04:57 | In this case, it doesn't really
matter, but in other cases it might.
| | 05:01 | I recommend, to become familiar with this,
is going through the Codex and looking
| | 05:05 | at the plugins API, and in addition, you
can check out Adam Brown's web site at
| | 05:10 | adambrown.info.
| | Collapse this transcript |
| Writing a filter| 00:00 | Filters are hooks that we can
use to edit content in WordPress.
| | 00:03 | This can be done either as content
is output to the browser--or some other
| | 00:07 | content reader--or is saved to the database.
| | 00:10 | You can use filters to add to, remove
from, or otherwise modify textual data.
| | 00:15 | Your task as a WordPress plugin
developer is to find the right filter and then
| | 00:19 | make the right change to the text.
| | 00:20 | We are going to use the add filter
method to add this, but the first thing we
| | 00:25 | need to do is create a function.
| | 00:27 | You can see I have created
another plugin here in the plugins
| | 00:30 | directory: feed_copyrighter.
| | 00:32 | I have set all the information in
the comments, so I am ready to go.
| | 00:35 | I am now going to write a filter function.
| | 00:38 | Now with filters, the function itself
is a little different than with actions.
| | 00:43 | The function itself is going to take
an argument, which will be the content.
| | 00:47 | So again, I am going to use this prefix cwmp.
| | 00:51 | This just keeps a unique name on my
functions, so that there's no collision with
| | 00:55 | other functions in WordPress, and we
will call this add_content_watermark.
| | 01:01 | Now here is the difference: content.
| | 01:04 | So notice I am taking in data.
| | 01:06 | So this is going to be the raw content,
| | 01:08 | whatever is I am filtering on.
It's going to depend on the filter.
| | 01:11 | I might be filtering a comment.
| | 01:13 | I might be filtering a post or a page or
something like that. That's going to be the content.
| | 01:18 | So in here what I am going to do is I
am first going to test to see if the
| | 01:22 | content is a feed, so that's
a built-in WordPress function.
| | 01:26 | So if it is a feed then I am going
to return the content just as it is.
| | 01:31 | I am not actually going to change it,
except for I am going to append to it,
| | 01:35 | "Created by Falkon Productions," and
let's put a little space in here first, and
| | 01:41 | then we'll say, copyright.
| | 01:44 | Now we can use the date function to
output the year, and then we will add on,
| | 01:50 | "all rights reserved."
| | 01:52 | So what that will do then,
| | 01:55 | if this is a feed, it will append it on.
| | 01:58 | So think about your web site.
| | 01:59 | Your web site probably has a footer
with copyright information, but if someone
| | 02:03 | accesses your RSS feed, it may not have that.
| | 02:06 | So this will add it to
everything in the RSS feed.
| | 02:09 | And then lastly, I am going to
have sort of a default return, in case
| | 02:12 | it's not a feed, essentially, that
will just return the raw content.
| | 02:17 | Now to add this as a filter,
I use the add_filter method.
| | 02:21 | It's going to take the name of the filter--
| | 02:24 | in this case, the_content--
| | 02:26 | this filter loops through each of the posts
that gets output, so it'll get output in each post.
| | 02:31 | And then I put my function name.
| | 02:33 | It's not a bad idea to
just copy it and paste it in.
| | 02:37 | That way I can make sure I at least avoid
making a typo, especially when you have
| | 02:42 | this prefix that's a rather long function name.
| | 02:44 | So now I can go into my WordPress admin console.
| | 02:48 | Here's my Content Watermark
Plugin. I'll activate it.
| | 02:52 | The RSS feed can be found at any site by
typing in the URL of the site and then
| | 02:58 | afterwards appending this variable
feed equals, and in this case, rss2.
| | 03:01 | There are actually some other
formats you can use, but rss2 will be fine.
| | 03:05 | So you can see here is our plugin
feed before we added that plugin.
| | 03:11 | If I refresh it, you can
see it adds in my copyright.
| | 03:15 | So that's the watermark.
| | 03:18 | If I want to remove a filter, I follow
basically the same format--only I use
| | 03:23 | remove_filter and I apply that to
the filter and pass whatever function.
| | 03:29 | Of course, I don't want to do
that, so I am not going to do that.
| | 03:32 | There are lists of all
these different functions.
| | 03:35 | The Plugin API that we looked at
earlier has a filter reference.
| | 03:39 | This can be really helpful
when you're first getting started.
| | 03:42 | So WordPress filters, as their name
implies, allow developers to filter, to edit
| | 03:48 | the actual content of WordPress.
| | 03:50 | This can be done either before the
information is saved to the database or
| | 03:54 | before it's sent out to the client.
| | 03:55 | To write filters, write a function that
does the filtering. It's going to take
| | 04:00 | the argument, which is going to be the
content, and it's going to return the
| | 04:03 | filtered content after having done
whatever you want it to do in the function.
| | 04:07 | Then you add the hook by using the add
_filter function, and finally if you
| | 04:11 | should want to remove a filter,
call the remove_filter function.
| | Collapse this transcript |
| About pluggable functions| 00:00 | Pluggable functions are set of
functions built into WordPress.
| | 00:03 | These functions can do anything from
getting the current user's information to
| | 00:06 | generating hashes from
strings to setting cookies.
| | 00:09 | As a WordPress developer, you
can use these in your plugins.
| | 00:12 | All of the pluggable functions are
included in wp-includes/pluggable.php.
| | 00:17 | You can also find a list
of them online at the Codex.
| | 00:22 | If you look in the code--this is that
WordPress track that's available online
| | 00:26 | directly from the Codex site--
| | 00:28 | you can see before every function
declaration there is a special if statement
| | 00:33 | that looks to see if that
function already exists or not.
| | 00:37 | If the function doesn't
exist, it then declares it.
| | 00:40 | If it does exist, it then
ignores the declaration.
| | 00:43 | This is precisely what makes these pluggable.
| | 00:46 | What that means is these are
functions that are used throughout the
| | 00:49 | environment of WordPress that you have the
ability to override and create your own versions of.
| | 00:55 | If you create your own version, these
will then exist, and it will not then
| | 00:59 | declare its internal version--thus pluggable.
| | 01:03 | Take, for example, the plugin that we worked on.
| | 01:06 | We had a function called Cc Mail.
| | 01:08 | Cc Mail uses the PHP mail
function to send out the mail.
| | 01:13 | Well, let's say we want to send it
through a universal mail application that was
| | 01:17 | used within WordPress.
| | 01:20 | There is one called wp mail, and if you
click on it in the Codex, you'll see the
| | 01:25 | format is very similar to PHP mail--
| | 01:27 | only we have the ability to override this.
| | 01:29 | So maybe it's something we want to utilize.
| | 01:32 | To change it, you simply use the
function, because it's already included in the
| | 01:36 | WordPress environment.
| | 01:38 | WordPress has a set of built-in
functions called pluggable functions.
| | 01:42 | These can be helpful when we need to use them.
| | 01:44 | Simply find them in the pluggable
PHP file, or here in WordPress Codex.
| | 01:48 | They provide us with some special
functionality that is not available
| | 01:51 | everywhere within WordPress.
| | 01:53 | What makes them pluggable is the
ability to override them if we want to, and
| | 01:56 | that new functionality will be used
all throughout the WordPress environment.
| | Collapse this transcript |
| Writing a pluggable function| 00:00 | Pluggable functions are a set of
functions built into WordPress.
| | 00:03 | While there are many functions in
WordPress, pluggable functions are special
| | 00:06 | because they allow you to override them,
essentially adding new functionality
| | 00:10 | into the built-in workings of WordPress.
| | 00:12 | All that's necessary to override
pluggable functions is to create a new
| | 00:15 | function with the same name.
| | 00:17 | All the pluggable functions are
located in wp-includes, pluggable.php file.
| | 00:24 | It's a good practice often, when you are
going to override a pluggable function,
| | 00:27 | to start with the original pluggable
function from the pluggable.php file.
| | 00:31 | What I am going to do is I am
going to create a new plugin here
| | 00:34 | called welcome.php.
| | 00:36 | This is going to override the wp_new_user
_notification pluggable function, which
| | 00:40 | sends a message whenever a
new user registers at the site.
| | 00:43 | This way I can customize the message that
gets send to the user, so they get the
| | 00:46 | message that I want them to see.
| | 00:48 | So, in the plugins directory, I've
created a new file called the welcome.php.
| | 00:52 | I've put in all my plugin
comments, and I am ready to go.
| | 00:55 | So, now I am going to go
into the pluggable.php file.
| | 00:58 | I am going to find that
function, wp_new_user_notification.
| | 01:04 | I am going to copy this as it stands
directly from the pluggable.php file, and I
| | 01:12 | am going to paste it
directly into my plugin file.
| | 01:18 | Now that I've pasted this function
into my plugin file, I simply need to
| | 01:22 | override the function and
change it how I want to.
| | 01:24 | Most of the functionality
I want to remain the same.
| | 01:27 | Notice I am sending a mail
to the administrator here.
| | 01:30 | I don't need to change that, but I do
want to change the message that's going
| | 01:34 | out to the new user, which is located here.
| | 01:36 | A couple things so you don't get scared:
| | 01:38 | They're using an sprintf function, which
essentially allows you to replace parts
| | 01:43 | of your string with the
variables that you pass in--
| | 01:46 | it's simply a secure way of
doing dynamic variables replacement.
| | 01:49 | In addition, they have this underscore,
underscore function, which we'll talk
| | 01:52 | about later when we get
into the internationalization.
| | 01:55 | So for now, let's go ahead and create
our message variable, and we are going to
| | 02:00 | write some new information in here.
| | 02:02 | So, I am going to use the same
function that they use, in case we want to
| | 02:04 | internationalize this down the road.
And I am going to change this to say,
| | 02:08 | 'Welcome to mmmStuff.com,'
which is my blog name.
| | 02:16 | And then I am going to add some new lines,
returns, and I am going to add another line.
| | 02:23 | I am going to use the same
methodology that they are using, which is the dot
| | 02:27 | equals, and I am going to do
that for the original one as well.
| | 02:30 | What that does is that says, "Set this
message equal to whatever is already in
| | 02:34 | this variable plus whatever comes
after the Equal sign," which is going to be
| | 02:38 | a new part of the message, which will say,
'Here is your information for future reference.'
| | 02:48 | And again, a couple of new lines, and
one final line signing out, and this one
| | 02:58 | will simply say, 'Feel free to
come back and check on stuff often'.
| | 03:08 | So there is my new message.
| | 03:10 | In order to make this function work,
I simply need to activate the plugin;
| | 03:15 | however, I need to be careful because
in some instances, the original plugin
| | 03:20 | may have already been activated
because of the order of inclusion.
| | 03:23 | So I need to put a special if
statement that will wrap around it, and this is
| | 03:27 | exactly what you'll see in the plugin.php file.
| | 03:30 | I'll say not function_exists, which
determines whether or not the function exists.
| | 03:37 | So, if it doesn't exist, then
it will go ahead and create it;
| | 03:40 | otherwise it will simply ignore this piece.
| | 03:43 | So, we're going to copy our function
name, paste it into here, and then make
| | 03:54 | sure we close both of them.
| | 03:55 | Eclipse has a special feature:
| | 03:56 | if you highlight everything and hit Command+I,
it'll automatically clean up your indentation.
| | 04:02 | So that's an easy way to do that.
| | 04:03 | So now we can save it, and we can go
into our admin, and you'll see on your
| | 04:08 | Plugins page your
Welcome Plugin has been parsed.
| | 04:11 | If we activate it, it should go
through and set up that function so that
| | 04:15 | the next user who registers at the web site
will then be able to get your new message.
| | 04:20 | In order to enable registration at the
web site, by default, WordPress has it
| | 04:24 | turned off so that not everyone can register.
| | 04:27 | So, we are going to go ahead and select
this so that anyone can register, save
| | 04:30 | the changes, and then we are going to go
ahead and log out, and sign in as a new user.
| | 04:35 | So, if you go to the beginning of
your web site, the front page, you'll see
| | 04:39 | there is a link here to register.
| | 04:41 | If we click this, we'll have the option,
and you can choose whatever username
| | 04:44 | you want, and then enter
your e-mail, and click Register.
| | 04:51 | That will then call our function,
that wp_new_user_notification.
| | 04:58 | Checking your e-mail. So you can see I got
a welcome e-mail, Welcome to mmmStuff.com.
| | 05:06 | Here is your information for future reference.
| | 05:07 | It has my username and password, the URL
to the web site, and then "Feel free to
| | 05:12 | come back and check on stuff often."
| | 05:14 | WordPress has a set of built-in
functions called pluggable functions that can be
| | 05:18 | overridden by plugin developers.
| | 05:19 | Because these functions are called on
from within WordPress and other plugins,
| | 05:23 | it allows us to be able to override
the default functionality, and have things
| | 05:26 | work a little differently,
however we may choose.
| | Collapse this transcript |
| Using template tags| 00:00 | WordPress template tags are little
custom functions that can be used by
| | 00:04 | WordPress administrators in their themes
and throughout their WordPress site to
| | 00:07 | perform a bunch of tasks.
| | 00:09 | Usually that's going to be
getting and outputting something.
| | 00:11 | More simply put: they're functions
that can be used in WordPress templates.
| | 00:15 | Sometimes they output authors or
posts or categories or short links or
| | 00:19 | something like that.
| | 00:20 | For plugin developers, this is
another way we can add functionality to
| | 00:23 | WordPress, creating our own template tags.
| | 00:26 | The Codex has some information about
template tags, and it actually lists the
| | 00:30 | template tags that are
currently available inside of WordPress.
| | 00:34 | For example, here is one: bloginfo.
| | 00:36 | You can use bloginfo to get different
types of data inside of your WordPress blog.
| | 00:40 | To use it, let's go ahead and log into
our WordPress admin, and under Appearance,
| | 00:47 | there is an option for Editor.
| | 00:49 | This allows administrators to edit
their themes directly, and you can see they
| | 00:53 | can select which theme they want to edit--
| | 00:54 | In this case, Twenty Ten, which is the
default theme that comes with WordPress
| | 00:57 | 3.0--and we're going to
choose Main Index Template.
| | 01:01 | We'll scroll down to the bottom, and you
can see they have some template tags in
| | 01:04 | here that get the sidebar and get the
footer, and we are going to add another
| | 01:07 | one, bloginfo, and we are
going to get description.
| | 01:13 | So, it's as simple as that.
| | 01:15 | I update the file, which will save it,
and I can go ahead and launch my blog site,
| | 01:20 | and if I scroll down, you'll see at the
bottom of the site, after the footer, I
| | 01:24 | have my description.
| | 01:26 | To create your own template tag, if you
remember, every WordPress plugin file
| | 01:30 | is included automatically in the request,
| | 01:32 | which means not only is the code
that isn't in function is included,
| | 01:36 | the functions themselves are included.
| | 01:38 | So, in this example, I have
an add_copyright function.
| | 01:42 | This will essentially become a template tag.
| | 01:45 | You can see it just outputs a little
copyright message directly to the screen.
| | 01:49 | So, if I want to use this, I can go
back into my administrator, in the Edit
| | 01:53 | Themes, I'll scroll down, and instead
of outputting my blog description, I am
| | 01:58 | going to use add_copyright.
| | 02:03 | In order to make this work, I need
to make sure that I first check on my
| | 02:06 | plugin, My copyright plugin, and make
sure that it's activated so that it's
| | 02:10 | actually included in the file.
| | 02:12 | Now that it's activated, I can go to
the front-end of the web site and refresh,
| | 02:16 | and you can see it's included my
template tag with my copyright message.
| | 02:21 | WordPress allows us to
build our own template tags.
| | 02:23 | These are essentially functions that can
be run via PHP from within any template
| | 02:27 | in the WordPress environment.
| | 02:29 | What's great about the plugin API is
that any function in our plugin files
| | 02:33 | will automatically be
included in WordPress requests.
| | 02:35 | So, everything you write can be used this way.
| | 02:37 | The main thing is if you want to expose
these functions to your administrative
| | 02:41 | users, you need to make sure and
provide some sort of documentation so they
| | 02:44 | know what's there.
| | Collapse this transcript |
| Introducing shortcode| 00:00 | Shortcode is a way of allowing non-
coding users of WordPress--since version 2.5--
| | 00:05 | to output some type of
feature into their pages and posts.
| | 00:08 | In this video, we'll discuss how you can create
your own shortcode functions in your plugins.
| | 00:12 | Let's go ahead and log in to my blog
and have a look at one of my posts.
| | 00:18 | If I go and look at the HTML, you can
see I have this tag here with the square
| | 00:23 | brace, caption id, and it has
some attributes assigned to it.
| | 00:28 | Then at the bottom, I have a closing tag.
| | 00:30 | This is a shortcode.
| | 00:31 | What this does is this allows for the
generation of this little tag around it
| | 00:37 | and the placement of the caption underneath.
| | 00:40 | So let's create our own shortcode.
| | 00:43 | I have a function already written
in the plugin, called smp_map_it.
| | 00:48 | What this does currently
is it's just a function,
| | 00:51 | it can be used as a template tag that
takes an address, and from that address it
| | 00:55 | will then output Your map and then a
256x256 image using the Google Maps API.
| | 01:06 | If we want to turn this into a tag,
for starters, we need to remove this
| | 01:10 | attribute, and let's just set a static address.
| | 01:15 | In order to use it then as a tag,
we need to use the special function
| | 01:19 | called add_shortcode.
| | 01:21 | We then define what you want
the shortcode tag to look like.
| | 01:24 | In this case, I am just going to call
'map-it', and then you assign the function
| | 01:28 | name that's going to be
used to output your shortcode--
| | 01:31 | in this case, smp_map_it.
| | 01:39 | Now we'll log into our admin, and
in our Plugins, we'll go ahead and
| | 01:47 | activate our Map plugin.
| | 01:51 | We then need to add
shortcode to one of our Posts.
| | 01:54 | We only have one, so it makes it simple.
| | 01:57 | You need to be in the HTML View.
So make sure you click the HTML tab.
| | 02:01 | Underneath here, we'll just put map-it.
| | 02:05 | We update it, and then load it in the
front page of our site, and you can see it
| | 02:11 | outputs our map with Your Map.
| | 02:13 | Notice however that it outputted above
our content, which isn't necessarily what
| | 02:19 | we want to do, and we
don't really have any control.
| | 02:21 | Maybe we want to have something
other than the White House mapped out.
| | 02:24 | In order to do that, we need to
add some arguments to our function.
| | 02:27 | The first one is going to take our attributes.
| | 02:30 | The second one is going to take content.
| | 02:33 | This is used in the case where
you have an open and a closing tag.
| | 02:36 | The content will represent the data
in between that open and closing tag.
| | 02:40 | To set up your attributes, there is a
special function called shortcode_atts.
| | 02:45 | This allows you to pass an associative
array of variable names that will set up
| | 02:50 | default values for the attributes.
| | 02:53 | So, in this case, I'll create a new array.
| | 02:54 | I am going to create one value called
title and set its default to Your Map.
| | 03:01 | Then I'll create another value called
address and set it to an empty string.
| | 03:06 | Then I pass in my attributes variable.
| | 03:09 | Now what I am going to do is instead of
outputting the HTML directly, I am going
| | 03:13 | to use a return keyword, because this
function is actually going to return the
| | 03:18 | stringed output where our shortcode tag is.
| | 03:21 | So, I am going to first add an <h2> tag,
and then I am going to concatenate on
| | 03:26 | the value from the attributes for title.
| | 03:30 | Then I am going to have all the same
HTML code up to the base_map_url, which is
| | 03:35 | the location of the Google API.
| | 03:37 | So, I am going to close that with a
single quote, concatenate it on, and then I
| | 03:42 | am going to change my address variable
to now look at the attribute address, and
| | 03:48 | I can erase the rest of this PHP code.
| | 03:51 | So there is my string.
| | 03:52 | So now it's returning essentially the
same HTML that was output, but it's returning
| | 03:57 | it as an HTML string.
| | 03:59 | To use this now, I can go back into my
Post, and I can pass in these attributes.
| | 04:05 | So I can say title="Our Location:" and
address='100 Main St. Santa Monica, CA'.
| | 04:15 | We update the post and we refresh,
and now you can see, it's mapped out our
| | 04:23 | Santa Monica location in the
correct place of our content.
| | 04:28 | If I did have something in between the
open and closing code, I can output it at
| | 04:32 | any point in this HTML
using the content attribute.
| | 04:37 | However, be careful, because in this
instance, if you have any shortcode in this
| | 04:42 | content, then it will be ignored.
| | 04:44 | So if you want to make sure that it
gets used, you want to use the do_shortcode
| | 04:49 | command and wrap that around your content.
| | 04:53 | This will allow you to have nested shortcode.
| | 04:55 | The last couple things to mention:
| | 04:57 | if you ever want to remove shortcode,
there is our special remove_shortcode, and
| | 05:02 | it takes the same arguments as the
add_shortcode, and you can also do
| | 05:06 | remove_all_shortcodes in any
sample where you want to use that.
| | 05:10 | So, WordPress gives us the ability to
add functions non-technical admins can
| | 05:14 | use, using simple tags called shortcodes.
| | 05:17 | We can create these as functions and
allow for the setting of attributes
| | 05:20 | in wrapping content.
| | 05:22 | It's yet another tool at the
disposal of WordPress plugin developers.
| | Collapse this transcript |
|
|
4. Using and Creating WordPress WidgetsWidgets and the WordPress Widgets SubPanel| 00:00 | Widgets are just what they sound like:
little widgets of application goodness.
| | 00:05 | Widgets are really just little windows
that plug into different screens of the
| | 00:08 | WordPress environment and allow the user
to see information or interact with
| | 00:12 | WordPress in some way.
| | 00:13 | You might see a widget that shows some
site stats in the admin, or you may want
| | 00:17 | to present a widget in the sidebar that
has links to different category posts.
| | 00:22 | Since WordPress 2.2, widgets
have been a built-in part of the
| | 00:24 | WordPress experience.
| | 00:26 | Let's take a look at widgets.
| | 00:28 | Logging into the WordPress dashboard
is the first time you'll see widgets.
| | 00:32 | All of these are dashboard widgets,
and we'll talk specifically about how to
| | 00:35 | plug those into the WordPress environment later.
| | 00:38 | If you want to go in and see the
widgets for the front-end of the web site,
| | 00:42 | in the Appearance menu, there is a submenu
called Widgets, which will open the Widgets subpanel.
| | 00:48 | On the left will always be a list of
your available widgets and inactive
| | 00:52 | widgets, which you can basically drag
there, and it will keep their settings,
| | 00:56 | but take them off of the interface.
| | 00:59 | On the right side, you'll have
different areas where your widgets can go.
| | 01:03 | What exists here depend
on the theme you're using.
| | 01:06 | In the default Twenty Ten theme that
comes with WordPress 3.0, we have a few
| | 01:11 | different areas where we can place
widgets, but you can see by default most
| | 01:15 | everything is placed in the Primary Widget
Area, which is the right side of the screen.
| | 01:19 | If you want to open your WordPress web
site, you can Command+Click on Mac or
| | 01:23 | Ctrl+Click on Windows to launch a new
tab. You can see over here, these
| | 01:28 | are all of our widgets:
| | 01:29 | Recent Posts, Recent Comments,
Archive, Categories, and Meta.
| | 01:34 | We can edit this information by opening
the widget in the Widget subpanel, and
| | 01:39 | if there are any options, they'll appear.
| | 01:41 | For example, Categories, we can
change to show them as a dropdown.
| | 01:46 | Meta, it doesn't really make sense, when
really these are just Important Links.
| | 01:53 | When I return to the front-end
and refresh it, you'll then see my
| | 01:56 | Categories have appeared in a
dropdown list, and my Link menu has changed
| | 02:01 | to Important Links.
| | 02:03 | If you want to move your widgets into
different areas, you simply open the area
| | 02:08 | where you want to place them,
and drag the widget into there.
| | 02:13 | In addition, you can drop other elements
from here directly into the Widget Area.
| | 02:22 | We'll cover this one later.
| | 02:25 | When you go back to the front-end, you
will then see the new widgets have been
| | 02:28 | added in the appropriate place.
| | 02:31 | Widgets are a way of encapsulating
application bits to be embedded into
| | 02:34 | WordPress in different places.
| | 02:37 | Some widgets, like the WordPress
Stats Widget, work directly in the admin.
| | 02:41 | Others you can embed into your
site in all kinds of different places.
| | 02:44 | It's easy to add and remove widgets
from the site using the Widgets subpanel.
| | 02:49 | All in all, widgets are a flexible
way for administrators to customize
| | 02:52 | their WordPress sites.
| | Collapse this transcript |
| Comparing widgets and plugins| 00:00 | So you might be asking yourself, "What's the
difference between a plugin and a widget?"
| | 00:04 | Well a widget will always be a plugin,
but a plugin isn't always a widget.
| | 00:09 | What I mean to say is a plugin is
something that interacts in one way or
| | 00:13 | another with WordPress.
| | 00:14 | It may or may not be seen.
| | 00:16 | For example, here are the plugins I
have installed on my mmmstuff web site.
| | 00:21 | The plugin Tweetly Updater posts an update to
Twitter anytime I create or edit a blog entry.
| | 00:28 | On the other hand, WordPress Stats
allows me to see information about WordPress.
| | 00:33 | WordPress Stats is a plugin, but
part of the plugin is that it has a
| | 00:38 | widget built into it.
| | 00:41 | So widgets use the plugin API,
| | 00:43 | so they technically are plugins but
widget's specific function are to work in
| | 00:48 | these dashboard-like applications or to
work on the front-end of the web site to
| | 00:53 | perform different functions.
| | 00:54 | So just remember, if you build a
plugin it might be widget, or it might
| | 00:59 | contain a widget within it;
| | 01:00 | however, some plugins don't use widgets at all.
| | 01:03 | Widgets are simply one of the tools
available to WordPress plugin developers.
| | Collapse this transcript |
| Using and customizing built-in widgets| 00:00 | WordPress has some built-in widgets
that can be installed with little or
| | 00:03 | no programming at all.
| | 00:05 | Some allow for using data that's in WordPress,
like Archive posts, the blogroll or Pages.
| | 00:11 | Others allow you to add HTML and
JavaScript snippets, or even use RSS feeds from
| | 00:16 | other blogs and other web sites.
| | 00:18 | Let's go to the WordPress Widget panel.
| | 00:20 | It's located under the Appearance
menu, and you can see here we have our
| | 00:25 | available widgets, inactive widgets,
and then we have all of our different
| | 00:29 | widget areas based on our theme.
| | 00:32 | If we want to add new widgets to our
theme, we can simply drag them from
| | 00:36 | here over to there.
| | 00:37 | For example, I want to add some links
so I can just grab the Links widget, and
| | 00:44 | it appears over here with all
the options that are editable.
| | 00:47 | These, by the way, are all the widgets that
are available in the WordPress 3.0 installation.
| | 00:52 | If you have plugins, you may see more.
| | 00:55 | If you want to customize anything in
your Links widget, you can go and do that
| | 00:58 | here and click Save.
| | 01:01 | To view it on the front-end, simply
open the web site, scroll down, and you can
| | 01:07 | see it's added, with this title of Blogroll.
| | 01:12 | To remove widgets,
there's two ways you can do it.
| | 01:15 | One way is you can grab it and drag it
over into the Available Widgets page,
| | 01:19 | which will essentially just remove it forever.
| | 01:21 | The other way is you can drag it into
the Inactive Widgets, which will save the
| | 01:26 | settings but remove it from the web site.
| | 01:28 | In the case of links, we were just
playing around, so we are just going to
| | 01:30 | remove that entirely.
| | 01:32 | You may have seen how some web sites
have their Facebook information or have
| | 01:36 | some kind of plugins
from social media web sites.
| | 01:39 | The way they do that is they
use the built-in text widget.
| | 01:42 | So I am going to drag that over here.
| | 01:45 | I am going to open it up, and I am going
to use this to display my Facebook widget.
| | 01:49 | So I will just put 'My Facebook page,' and
then I will go up to the Badges page of
| | 01:56 | Facebook, and you can see it gives
you some different types that are
| | 02:00 | specifically made for those types of blogs.
| | 02:03 | In this case, we can just copy the
text and paste it right into our text
| | 02:09 | widget, save it, go back to our web
site, refresh it, and you can see it adds
| | 02:16 | my Facebook widget.
| | 02:17 | So let's go ahead and take our
Facebook widget, and let's put it in Inactive
| | 02:24 | Widgets in case we want to bring it back.
| | 02:26 | This will save all the settings for us.
And then we are going to grab an RSS
| | 02:29 | widget, so that we can plug
a feed into our web site.
| | 02:33 | I like this Gizmodo feed from gawker.com,
| | 02:36 | so I am going to copy the feed URL,
paste it in here, and just call it Gizmodo.
| | 02:41 | I am only going to display five items;
| | 02:44 | ten items seems a little extraneous. Save it.
| | 02:47 | I am back at my web site.
| | 02:49 | You can see it now adds Gizmodo, and
you can click any of these, and it will
| | 02:55 | bring you to that web site.
| | 02:57 | So WordPress has a number of built-in
widgets that allow you to do a lot of
| | 03:00 | customization without any programming knowledge.
| | 03:04 | We looked at how to create these to
use site information like the Blogroll.
| | 03:08 | You can also do things with pages and posts.
| | 03:11 | We also look at how to do widgets that
come from other sites using the plain
| | 03:15 | text widget or the RSS Feed widget.
| | Collapse this transcript |
| Creating a new widget| 00:00 | Building a WordPress widget is pretty
much the process of building a plugin, but
| | 00:05 | we use some special techniques to do it.
| | 00:08 | Everything is going to happen in a
single file using the WordPress Widget API.
| | 00:12 | As long as you know the basic framework,
everything will fall right into place.
| | 00:16 | You need to code your widget
using three major functions:
| | 00:20 | Widget, Update, and Form.
| | 00:22 | In this unit, we are going to discuss
generating the widget interface using widget
| | 00:25 | and registering the widget.
| | 00:26 | So let's to into PDT eclipse, and
you can see I have created a new file
| | 00:31 | called simpleWidget, and I have put
all my comments in it, just like I would
| | 00:35 | have with any other plugin.
| | 00:37 | Since WordPress 2.8, they added an object-
oriented methodology for creating widgets.
| | 00:42 | There is another way to do it, and
you can see it online in the main
| | 00:46 | Widgets page in the Codex.
| | 00:48 | There's a special section about creating
widgets before 2.8, and this is a fine way to do it;
| | 00:56 | however, creating it the object-
oriented way is a lot cleaner and neater, and is
| | 01:00 | considered the best practice.
| | 01:02 | So the way to do this is we
actually create a class file.
| | 01:07 | So creating classes in PHP is a
matter of declaring the name of your class,
| | 01:12 | giving it a name--in this case, we
will call it SimpleWidget--and if it's
| | 01:16 | going to extend any specific class,
that is, if it's going to inherent things
| | 01:21 | from another class, then you need to
define it by saying extends, and then
| | 01:25 | in this case, there's a special
class called WP_Widget, which is made
| | 01:30 | specifically for creating widgets.
| | 01:35 | So this is a basic class definition,
and you can write other plugins
| | 01:38 | using classes as well.
| | 01:39 | However, in this case we are
just going to do it for the widget.
| | 01:43 | Every class has a basic function
called the constructor, and this is a class
| | 01:47 | that's called when you create
a new instance of this class.
| | 01:50 | So we are going to declare ours as SimpleWidget.
| | 01:54 | Notice that it matches
exactly the name of the class.
| | 01:58 | Then we need to declare three special
functions, and these are what make widgets work.
| | 02:04 | The first function is widget.
| | 02:08 | The widget function is going
to output the user interface.
| | 02:12 | We also have an update function, which
will be used for handling any update
| | 02:17 | functionality, and finally a form
function, which will be used if we have any
| | 02:24 | configuration options.
| | 02:26 | Once you have all these declared, the
next main step is going to be to create
| | 02:31 | the actual user interface
using the widget function.
| | 02:35 | So this function is going to take two arguments.
| | 02:38 | The first one is called args, which are
basically going to be the arguments from the theme.
| | 02:44 | So this function is going to get called
internally whenever a widget is pulled
| | 02:49 | into the user interface, and when it
calls it, it's going to pass to it the
| | 02:53 | arguments from the theme which allow
us to get some specific information from
| | 02:57 | that theme, like all of the HTML that
comes before the widget, all HTML that
| | 03:02 | comes after it, the title
and some other information.
| | 03:06 | So we declare that, and
then we declare an instance.
| | 03:09 | An instance is going to give us
essentially an instance of the class.
| | 03:15 | In here, the first thing we want to do,
to make our lives easier we can use a
| | 03:18 | special function called extract.
| | 03:21 | Extract will take whatever
you pass it as an object,
| | 03:25 | it will parse it out, and it will then
put it into variables that you can use in
| | 03:29 | your function so that we don't
always have to use the prefix.
| | 03:33 | So we are going to essentially take
all the args out and make them local
| | 03:36 | variables, and we are going
to use this EXTR_SKIP constant.
| | 03:42 | We are going to pass to it as well.
| | 03:44 | That will essentially
protect any existing variables.
| | 03:49 | Now we can set our title equal to, and
this is a funny little bit of code.
| | 03:56 | So we are looking at the instance property, and
we're going to see if there's a title in here.
| | 04:00 | So notice how it's wrapped in parentheses.
| | 04:05 | Basically what we are doing here,
this is a shorthand if-else statement.
| | 04:10 | So we are saying if there is something
in this instance title, then we are going
| | 04:15 | to set our local title
variable equal to that value.
| | 04:22 | Else we are going to set it to "A simple widget."
| | 04:26 | So this is essentially setting a default title.
| | 04:33 | In addition, we are going to create
a body and do the same basic process.
| | 04:40 | Look to the instance and see if
there's a body property, and if there is, then
| | 04:47 | we will set the body equal to that property,
and if not, the body will just some simple text.
| | 04:54 | On your example you might want to say,
let's say your widget is outputting some
| | 04:59 | kind of list of e-mails or something,
| | 05:01 | you might want to have a default
message that says, "No e-mails available,"
| | 05:04 | because if there's no body then that
means there's obvious nothing to output.
| | 05:08 | So now what we are going to do is since I
am going to be writing some HTML--because
| | 05:12 | this widget function is actually
outputting user interface--I am going to close
| | 05:17 | my PHP, and that then allows me to just
write as if I'm in a regular PHP page.
| | 05:24 | So I am going to echo this special
variable, before_widget, and this came
| | 05:31 | from our arguments, and I can access
it like a local variable because I used
| | 05:36 | this extract function.
| | 05:39 | Then I am going to output before the
title, and I am going to append to it the
| | 05:47 | title and append to it after title.
| | 05:53 | So that's going to essentially
output the title and then wrap it in this
| | 05:57 | before_title and after_title, which is
usually some form of div tag or some kind of HTML.
| | 06:04 | Then I am going to write a paragraph,
and inside the paragraph, I am going to
| | 06:09 | echo whatever is in the body, which
is going to be, of course, whatever was
| | 06:14 | passed into this instance of the
widget, or it's going to just put the
| | 06:18 | default if nothing was set, and
| | 06:22 | then once I am done, make sure to reopen
the PHP, so that I can continue to parse
| | 06:28 | the rest of the page.
| | 06:29 | So this is the basics of putting
together a widget using WordPress's Widget API.
| | 06:34 | We will talk about how to
register this widget and use it in a
| | 06:38 | WordPress environment later.
| | 06:40 | I'll note that widgets are meant
to go hand-in-hand with themes.
| | 06:44 | If you want to know more information
on developing themes and using themes,
| | 06:48 | please refer to the
lynda.com course on that topic.
| | 06:51 | So overall building a widget using
Widget API requires a little understanding of
| | 06:55 | object-oriented programming. Because we
are extending this built-in WP_Widget
| | 06:59 | class, we have these functions available
to us that ensure everything is created
| | 07:05 | in a consistent manner.
| | 07:06 | In this unit, we use the widget
method to output the widget body itself.
| | 07:11 | In the next unit units, we are going to
talk about how to create update and how to
| | 07:14 | create forms to allow users to edit
some configuration options and save those
| | 07:19 | to the database.
| | Collapse this transcript |
| Writing the constructor and registering widgets| 00:00 | In order for a widget to be used in the
WordPress environment, we need to first register it.
| | 00:05 | This is going to be done using a
WordPress action called widgets init.
| | 00:09 | Additionally, if we want to set up any
configuration elements, we need to do
| | 00:13 | this in the widget itself.
| | 00:14 | We are going to do it in the constructor.
| | 00:16 | So let's go back to our class.
| | 00:18 | You can see we have declared our
SimpleWidget class that extends the WP_Widget class.
| | 00:23 | We created an empty constructor,
and we've also created the functions,
| | 00:27 | widget, update, and form.
| | 00:28 | So now to register it,
| | 00:31 | we are going to create a function
that's going to do the registering.
| | 00:34 | We want to make sure to do this
outside of the class, so that it gets
| | 00:38 | executed when we activate.
| | 00:40 | So we will declare function.
| | 00:41 | We will call it simple_widget_init, and
in here, we will just call the special
| | 00:49 | register_widget class, and we
pass to it the name of the class.
| | 00:56 | So make sure that that simple widget
matches the class that you have up here,
| | 01:01 | because that class definition is
going to set up when your class gets run.
| | 01:06 | Then we need to add the action for widgets_init.
| | 01:13 | We want to call the simple_widget_init.
| | 01:20 | So this should set up our widget and
make it so that we can use it in the
| | 01:23 | WordPress environment.
| | 01:24 | So let's go back to the administrator.
| | 01:26 | If we scroll down, we will see our Simple
Widget is listed here, but it's not activated yet.
| | 01:32 | So let's go ahead and activate it, which
will run the code, which will call that
| | 01:36 | function once the widgets_init method gets run.
| | 01:40 | So let's go into the widgets, and
we should see our widget registered.
| | 01:44 | Now you wouldn't know it, but it is here.
| | 01:47 | It's this one. Because we didn't set up
any of the configurable elements, some of
| | 01:52 | which will actually display here,
| | 01:54 | it doesn't say anything, and we
will look at doing that in a second.
| | 01:57 | But let's go ahead and just grab it and
drag it over here, and you can see that
| | 02:01 | it will actually work.
| | 02:03 | So if we go back to the front-end of
our web site and refresh it, you can see
| | 02:09 | it appears down below, with the
default information that we had displayed.
| | 02:14 | If you want to display some of those
options, which you most likely do, we are
| | 02:18 | going to do that by
setting it up in the constructor.
| | 02:21 | Specifically, what we are going to
do is we're going to call the parent
| | 02:25 | constructor of the WP_Widget class.
| | 02:27 | You can find information for
the WordPress classes online at
| | 02:31 | phpdoc.wordpress.org.
| | 02:34 | This is the definition for the WP_Widget
class, and you can see it will tell you
| | 02:38 | how you use the class, and it also
tell you the inheritance chain, but in
| | 02:42 | addition, it will tell you how the
constructor works, you can see the
| | 02:46 | constructor is going to take the ID,
a name, and then some options in an
| | 02:50 | associative array, both
widget options and control options.
| | 02:54 | The widget options are going to have
information metadata about the class, and
| | 02:58 | the control options will have size information.
| | 03:01 | So let's first create a
variable to hold our widget options.
| | 03:05 | We are going to set this equal to an
associative array, and we are going to set
| | 03:12 | up a classname and set
that equal to simple-widget.
| | 03:23 | We are then going to set up a description,
and we will call this "Just a simple widget."
| | 03:36 | So there is our metadata.
| | 03:37 | Now we need to pass this into the
parent class by calling the super constructor.
| | 03:42 | The way you access the parent class
is you use a special parent keyword,
| | 03:47 | then these two colons, and then you can
determine which method you want to run.
| | 03:51 | In this case, we're going to run the
constructor, so it will look like we are
| | 03:56 | calling a method with the same name
as the class. And we pass in the ID--
| | 04:00 | you want to make sure that this is unique--
| | 04:03 | the title--this is what's going to get
displayed on the bar of your widget when
| | 04:08 | you're in the back-end--and then any of our
options. In this case, we have just a widget options.
| | 04:16 | You could, additionally, pass the
configuration option with the size information.
| | 04:21 | Make sure that this variable here matches this.
| | 04:23 | You can see I made a mistake.
| | 04:25 | It should have an S there.
| | 04:27 | So let's go back to the administrator,
let's remove our widget, and let's go
| | 04:31 | ahead and refresh the widget page,
so our simple widget will appear.
| | 04:36 | It's not in the top any longer
because they're in alphabetical order.
| | 04:39 | So now you see it's down here
after the RSS, and after the Search.
| | 04:43 | Simple Widget, which was the title, and Just
a simple widget came from the description.
| | 04:47 | It will still behave the same, and I
don't have any configuration options.
| | 04:51 | We will talk about those later.
| | 04:53 | So that's the basics of adding a
custom widget to the WordPress installation.
| | 04:58 | Basically we do it like we
do a lot of other plugins:
| | 05:01 | We add an action, and that's
specifically is the widgets in that action.
| | 05:04 | We are going to then, inside that
action function, we are going to call the
| | 05:08 | register widget method,
| | 05:10 | which is going to set up our widget for use.
| | 05:12 | Finally, if we want to do any
configuration options, we can do those by calling
| | 05:16 | the super constructor inside
of the constructor class.
| | Collapse this transcript |
| Enabling configuration of widgets| 00:00 | In many widgets, it will be crucial to
have some kind of settings that enable the
| | 00:03 | administrator to set
configuration options of the widget.
| | 00:06 | A weather widget for example is going
to have a setting to allow you to enter
| | 00:10 | the zip code to know what weather to display.
| | 00:13 | The WordPress Widget API gives us a couple
key functions in the WP_Widget class to do this:
| | 00:18 | the form function and the update function.
| | 00:20 | Let's take a look at how those work.
| | 00:22 | So here's our simple widget that we
created that extends the widget class.
| | 00:25 | We have already created the setup options and
registered the widget with the administrator.
| | 00:30 | So let's go ahead and go into
our form and first things first:
| | 00:34 | let's go ahead and close the PHP.
| | 00:37 | This will essentially allow us to type
anything after here as if we are typing
| | 00:41 | in a PHP file, because
it's going to output HTML.
| | 00:45 | Just so we don't forget later, let's
go ahead and add that PHP opening tag
| | 00:50 | again, so that it continues to
parse the rest of the document normally.
| | 00:54 | We don't have to worry about
the actual Form tag itself;
| | 00:58 | that will be already handled by the Widget API.
| | 01:01 | We do need to write whatever
fields we want to be editable.
| | 01:03 | So I am going to create a label, and
this is going to be a label for--and then I
| | 01:08 | want to output the ID for the Title
field because we're going to allow the user
| | 01:12 | to edit the title and the body.
| | 01:13 | So to output that, I use echo, and then
I use this which refers to the instance of
| | 01:18 | this class, and I use get_field_ID, a
built-in method that allows me to get just
| | 01:27 | these types of data, and then we'll
close our for and close the label tag.
| | 01:35 | Then we'll input our Input field, and we are
going to get the ID in exactly the same way.
| | 01:41 | In fact, you can literally
just copy it and paste it.
| | 01:46 | We'd also need to get the Name field,
and we do that in a similar way, although
| | 01:51 | we actually use the get_field_name
method, and it's for the same field.
| | 02:01 | The last thing is to output the
value, and we are going to get that
| | 02:04 | directly from the instance.
| | 02:05 | So that's actually going to get the
value that's saved in the instance. And to
| | 02:09 | get the instance, we can pass it to the form.
| | 02:14 | In fact, this is going to get
passed to the form whenever it's called
| | 02:18 | internally by the Widget API.
| | 02:21 | So in here we're going to use php echo,
and then we will use instance and access
| | 02:27 | it by its name, title.
| | 02:30 | A good idea, whenever you're accessing
strings that the user entered into HTML of
| | 02:35 | some kind, is to actually escape the HTML,
and we can use that using the
| | 02:40 | esc_attr function.
| | 02:42 | So we will just wrap that around the variable.
| | 02:44 | So I am going to do the same basic thing
for the body tag, so I am just going to
| | 02:48 | go head and copy this and paste it in,
| | 02:52 | but I am going to change this label to body.
| | 02:56 | I will change this to read body, and
instead of using an input, I am actually
| | 03:01 | going to use a textarea.
| | 03:04 | The textarea is going to have an ID of
get_field_ID('body') and the field name
| | 03:10 | is going to be get_field_name('body').
| | 03:13 | However, the difference between text
area and input is that we don't use
| | 03:17 | the value property.
| | 03:18 | We instead put the value in between
the open and closing text area tags.
| | 03:24 | So in here, we will output
echo esc_attr, instance, body.
| | 03:36 | So there we have it.
| | 03:37 | I think we're all ready to go.
| | 03:38 | Let's have one last final look,
and make sure it's all clean.
| | 03:41 | So let's save it and go back to our
administrator, and let's refresh the Widget page.
| | 03:48 | We can now grab our
widget and drop it over here.
| | 03:52 | So you can see I now have
my Form that I input here.
| | 03:55 | I have my title, and I
can say "My Message:" "Hello."
| | 04:02 | But when I save it, nothing happens.
| | 04:05 | The reason is that it's calling the
update method to save this, and our
| | 04:10 | update method is empty.
| | 04:12 | The beauty of inheritance in object
oriented-programming is that we inherit the
| | 04:16 | built-in functionality of the original class.
| | 04:20 | In this case, we're overwriting it
because that is exactly what customizes it.
| | 04:25 | So we create our widget.
| | 04:26 | We create our form because we want
to create forms and widgets that are
| | 04:30 | specific to this widget.
| | 04:32 | However, update, we just want to save
this data, and we can actually use the
| | 04:36 | built-in update method to do that.
| | 04:38 | So I am actually going to delete
the update method from my class.
| | 04:42 | I am going to go back into my
Widget class and re-enter my data.
| | 04:46 | So I will put "Today's Message,"
| | 04:51 | "Sunny in Ventura, CA."
| | 04:56 | Since it called Today's Message, it
then save this information and if I were
| | 05:01 | to open this in my browser, you
could see that it output "Today's Message,
| | 05:08 | Sunny in Ventura, CA."
| | 05:09 | So it saved it for me.
| | 05:11 | If you wanted to, you could
actually create an update function.
| | 05:15 | It's going to take two arguments:
| | 05:16 | it's going to take the old instance
and the new instance. And you can then do
| | 05:20 | some validation and then
use data from either one.
| | 05:24 | It's a good way if you want to do
validation or some kind of data scrubbing in between.
| | 05:29 | But if you just want to use it out
of the box, there's no need to use it.
| | 05:33 | So the WordPress Widget API allows
developers to add configuration options that
| | 05:37 | will be stored in the instance array.
| | 05:40 | This is done through the form function,
which essentially is going to output the
| | 05:44 | user interface in the form, which you
can use get_field_ID and get_field_name
| | 05:49 | of this to get your data.
| | 05:51 | And finally, you are going to use
the update function to save your data.
| | 05:56 | If you want to overwrite the update
function, you can do that as well, to
| | 05:59 | perform validation in such.
| | Collapse this transcript |
|
|
5. Plugin Options and AdministrationCreating an admin interface| 00:00 | A lot of times plugins are going to
require some sort of configuration options.
| | 00:04 | They might require that the site
administrator enters something in order
| | 00:07 | that they work properly.
| | 00:08 | For example, if you use some remote
service like Twitter or Flicker or
| | 00:12 | Rhapsody, you are going to need their
authentication information to go out and get their data.
| | 00:16 | If this is a case with your plugins,
you're probably going to want to create an
| | 00:20 | admin interface that plugs directly
into WordPress's built-in admin interface.
| | 00:24 | There are three basic steps to do that:
| | 00:27 | The first is we are going to create a
function that outputs the user interface,
| | 00:31 | and the second we're going to write
another function that uses one of many
| | 00:34 | functions to create a link
inside of the Admin menu.
| | 00:38 | The last thing is we are going
to use a hook to tie this in.
| | 00:42 | So let's start at the beginning and write a
function that's going to output our Options page.
| | 00:46 | So we'll call it cccom_option_page.
| | 00:53 | I like to give a prefix like cccom
whenever I am using functions to keep from
| | 00:57 | collision--that is, interfering with other
functions in the WordPress environment.
| | 01:01 | So in here is going to be user interface.
| | 01:03 | So I am going to close the PHP that's
opened at the top of the page, and I am
| | 01:08 | just going to open another
one for the rest of the page.
| | 01:10 | That way, in between, I
can just use straight HTML.
| | 01:14 | So I am going to create a div first
and use the wrap class, which is just a
| | 01:18 | built-in style inside of WordPress.
| | 01:21 | Then I am going to use the special
function called screen_icon, which will output
| | 01:30 | the special icon from whichever of the
admin items is currently being viewed.
| | 01:35 | I will create a little header, and
I will create a quick description.
| | 01:44 | So I am basically going to
say, "Welcome to the CC Comments plugin.
| | 01:55 | Here you can edit the e-mail(s) to CC."
| | 02:01 | All right, it's a dangling preposition, but
we're not going to pick nits here.
| | 02:06 | So that's a basic function;
| | 02:07 | it outputs a really basic UI.
| | 02:09 | Like I said, we'll add the input
fields in the updating process later.
| | 02:14 | Then we want to create another function,
and this function is going to register
| | 02:21 | with the Admin menu.
| | 02:22 | There are a number of different functions
available, which we will explore in a later video.
| | 02:28 | For this one, we are going to add
it right into the Settings options.
| | 02:31 | So we are going to use a special
function called add_options_page, and then we
| | 02:37 | are going to pass the page title.
| | 02:39 | We are going to pass what
we want to see in the menu.
| | 02:44 | We are going to pass the capabilities.
| | 02:50 | This is essentially the
roles from the user information.
| | 02:55 | WordPress has a bunch of information on
the Codex about the different types of
| | 02:59 | capabilities there are.
| | 03:02 | It lists them all, and you can see which ones
apply to whom and what they mean exactly here.
| | 03:08 | Let's just set it to Manage Options.
| | 03:10 | Then we are going to add a special menu
slug that's essentially going to be like
| | 03:17 | an ID for the menu item.
| | 03:18 | So we'll call it cc-comments-plugin.
| | 03:23 | And the last thing we'll add is a link
to the function that generates the page,
| | 03:29 | which is this one here.
So let's go ahead and copy it.
| | 03:34 | I often have typing problems, so I
like to just copy and paste when I can.
| | 03:41 | So this will register
that item with an Admin menu.
| | 03:45 | So the last thing we need to do is
make sure that this function gets called
| | 03:49 | for the right hook. So add_action--
| | 03:53 | should look familiar by now--called
admin_menu, and it's going to call this
| | 04:01 | function right here.
| | 04:03 | So that's all it takes. We added this action, which
when it generates the admin menu, WordPress will
| | 04:09 | then call this function, which will add
this information to the Options portion
| | 04:14 | of the administrator.
| | 04:16 | When the user clicks on it, it will then
call this function, which will open this
| | 04:20 | and use this to generate the screen.
| | 04:22 | So let's see how that looks.
| | 04:23 | So here is our WordPress dashboard.
| | 04:26 | Right now, I don't have any link in
here, so let's go ahead and refresh it.
| | 04:32 | You can see now I have
the CC Comments down here.
| | 04:36 | When I clicked on it, it called the CC
Comments Options, and it said, "Welcome to
| | 04:41 | the CC Comments plugin."
| | 04:43 | Notice this is what I got from the screen icon.
| | 04:45 | So you can see it adds it
under the Settings menu--
| | 04:49 | that's because I use Add Options page--
and then it generated this page, and it
| | 04:55 | used the screen icon to generate this.
| | 04:57 | If I were to move this to a different
section, it would use the appropriate icon.
| | 05:01 | That's why that's a great and helpful function.
| | 05:04 | Many WordPress plugins require that the
administrator does some kind of adding in
| | 05:08 | order for it to work.
| | 05:09 | Creating your own page in the WordPress
admin is a matter of writing a function
| | 05:13 | that will output the page, writing
another function that's going to place a link
| | 05:18 | into one of these menus, and then
finally adding a hook into an admin menu.
| | Collapse this transcript |
| Saving data to the database| 00:00 | When we have created a plugin that
requires configuration options, it's going to
| | 00:04 | be necessary to store the
options that the user enters.
| | 00:07 | There is a couple of ways you can do that.
| | 00:08 | One, if you have a lot of information
that you are storing, you will probably
| | 00:12 | want to create your own table, and
we'll talk about interacting with the
| | 00:15 | WordPress database in future units.
| | 00:18 | The other way you can do it is you can
create your own fields in the options database.
| | 00:23 | We are going to look at how to do that.
| | 00:25 | There are actually a couple of ways to do it.
| | 00:27 | One way is the deprecated pre-WordPress
2.7 way, and I want to go through that,
| | 00:32 | not because it's a great way, but
because you'll see it a lot--it's a very
| | 00:36 | common way of doing it--and also it
allows us to get into nonces, and talk about
| | 00:39 | what those are and how they work.
| | 00:41 | So I am just going to get you
introduced and started on that way, but just keep
| | 00:45 | in mind that this isn't a secure
way, and this isn't a best practice.
| | 00:48 | But it is a way that works
if you want to do it this way.
| | 00:51 | So let's look at our cc_comments plugin.
| | 00:53 | We've already got it plugged in, and we've
already got it set so we have an options page.
| | 00:58 | So what we really need to
do now is create a form.
| | 01:01 | So we'll write form, action.
| | 01:03 | We'll leave that empty, which means
it's going to submit to the same page.
| | 01:08 | That allows us to do the processing from
within the same function. And the method is
| | 01:11 | going to be post, id.
| | 01:15 | It's possible that there could be other forms
on the page, so it's good to keep it unique.
| | 01:22 | So there is our form.
| | 01:23 | Now, we will create a header, and here we
are going to say, call the field cc_e-mail.
| | 01:31 | So we can link to it that way, and
we'll go ahead and say, "Email to send CC to,"
| | 01:41 | and then stay in the h3, so it's on the
same line, and we'll add an input tag.
| | 01:45 | So text input, id, cc_e-mail, the name
would be the same, and then for the value we
| | 01:56 | are going to output the result of
calling the special function get_option, and
| | 02:02 | we are going to give the option a name.
| | 02:03 | In this case, we're going
to call it cccomm_cc_e-mail.
| | 02:09 | Notice I am using the prefix here, cccomm.
| | 02:11 | I do that because it keeps it unique,
so that way all these options are
| | 02:15 | stored in the database.
| | 02:17 | So I want to make sure I don't override
or get something from some other plugin.
| | 02:21 | So I am also going to use the Escape
function to essentially get rid of any
| | 02:27 | HTML tags or something.
| | 02:28 | Anytime there's a user-edited
field, it's a good idea to do that.
| | 02:32 | So that's my value field and the end of my input.
| | 02:36 | Now, I just need to put in a
submit tag, and we're good to go.
| | 02:50 | So let's go back to our form in the admin.
| | 02:53 | Notice I didn't have anything here.
| | 02:55 | So now we can see I have a form.
| | 02:57 | Of course, I'm not saving it yet.
| | 03:00 | In order to do that, I
have to do a couple of things.
| | 03:02 | Like I said, this isn't the best way--
| | 03:04 | I forgot to close that P.
This is the old way to do it.
| | 03:08 | You put a hidden form, and we'll call
it cccomm_hidden, and the value will be
| | 03:17 | Y. Then what we can do is when it's
submitted, we can look to see if it exists
| | 03:26 | in the post--single quote there, cccom_
hidden and equals Y. If it does, then
| | 03:37 | we'll do our processing.
| | 03:39 | The processing is easy.
| | 03:40 | There are two functions you can call:
| | 03:42 | add option and update option.
| | 03:45 | Update option is a good case for what
we are doing here because if it doesn't
| | 03:49 | exist, it will automatically create it.
| | 03:51 | Add option is something you might want
to use if you're setting something up
| | 03:55 | maybe on activation.
| | 03:56 | So we will just put update_option.
| | 04:00 | The name of the option is going to
match what we are using here in the get,
| | 04:04 | so you can just copy that, and the
value is going to be what's submitted for
| | 04:12 | the post in cc_e-mail.
That's it. So it's saved.
| | 04:19 | So now, I am just going to output some
simple message that the user knows that
| | 04:26 | it worked, and this updated class is
part of the style sheet of the admin.
| | 04:35 | Let's see what it looks like.
| | 04:37 | So now, I'll save it, and I can go back here.
| | 04:42 | Now, I want to make sure that I
refresh it, because I want to make sure that I
| | 04:46 | get that hidden field.
| | 04:48 | So you can see here is where my
function is outputting, and you can see I
| | 04:51 | have my hidden field.
| | 04:54 | Then we enter database and save it, and
you can see it tells me it's saved, and
| | 05:01 | the get option gets it, and now puts it here.
| | 05:04 | So for plugins that require editing,
we have the ability to edit directly to
| | 05:08 | options database in WordPress.
| | 05:10 | It's pretty straightforward.
| | 05:12 | In the old way, we create a form, and
we also create the form processing, and
| | 05:17 | use update option to update that option.
| | 05:20 | We can use get option to
retrieve the option whenever we want.
| | 05:23 | The way that we did it here is insecure
because anyone could spoof that they're
| | 05:29 | coming to this and submitting data,
and that could cause a problem.
| | 05:34 | We'll talk about how to avoid that
in the next video when we use nonces.
| | Collapse this transcript |
| Securing form submission with nonces| 00:00 | One problem with performing database
interactions from form pages is that it can
| | 00:04 | subject our site to potential attacks.
| | 00:07 | There is a particular type of attack
called a cross-site request forgery, or CSRF.
| | 00:12 | It's basically where someone spoofs a
request to make it look like it's coming
| | 00:16 | from your form page and going to your
submission page, and then they can wreak
| | 00:20 | all kinds of havoc that way.
| | 00:22 | WordPress has a built-in methodology
to handle this called nonces. And even
| | 00:26 | though the form submission that we are
using in our cc-comments plugin is the
| | 00:30 | pre-2.7 way, I wanted to show it to you
for the simple reason that understanding
| | 00:35 | nonces work can be really helpful.
| | 00:38 | So let's go back and take a look at our form.
| | 00:41 | What we were doing was we were
submitting this hidden field, and this hidden
| | 00:45 | field we'd then check for and then submit it.
| | 00:47 | Well, anyone could pretend to
generate this form and send it.
| | 00:51 | However, if we use a special function
call wp_nonce_field, we can essentially
| | 00:58 | have it generate a hidden field, and a key
will be populated, a nonce, or a number used once.
| | 01:03 | So we are going to give it a specific id.
| | 01:05 | So cccomm_admin_options-update.
| | 01:13 | So this will generate our field for us.
| | 01:15 | Then to validate it on the
submission side, we can use a special function
| | 01:21 | called check_admin_referer, and then we pass to
it the same ID that we used for submitting it.
| | 01:30 | So what it will do then is it will look
to see that it's a valid key that it has
| | 01:36 | generated, and it will then process this.
| | 01:39 | So this allows for a more secure way to do it.
| | 01:42 | One of the advantages of understanding
nonces is that when you get into jQuery
| | 01:46 | and using AJAX--or you can use one of
the other libraries with AJAX--it's a good
| | 01:51 | practice to use nonces, and this check_
admin_referer is basically how you do it.
| | 01:56 | So it's very simple to repeat this
on the same methodology, using AJAX.
| | 02:01 | For maximum security of form
submissions, it's a best practice to use nonces,
| | 02:05 | or numbers used once.
| | 02:07 | WordPress is going to automatically
generate a key, and then it will check for
| | 02:10 | a match on submission.
| | 02:12 | When you do this with post
WordPress 2.7, it's actually quite easier, and we
| | 02:17 | will look at that in the next video.
| | 02:19 | It automatically handles this for you.
| | 02:21 | However, it's good to
understand the concept of nonces.
| | Collapse this transcript |
| Options editing post-WordPress 2.7| 00:01 | If you have been through the
pre-WordPress 2.7 compatible option editing videos,
| | 00:05 | or have ever done option editing
using what is considered the old way--the
| | 00:09 | deprecated way--you'll find that the new
methodology introduced in 2.7 will make
| | 00:14 | your life easier and your code cleaner.
| | 00:17 | Basically, instead of doing all of
these post-checks in creating nonces
| | 00:21 | ourselves, we are essentially going to
register our options with WordPress and
| | 00:25 | let it handle all of the nonce nonsense.
| | 00:29 | So let's take a look at our cc_comment
plugin, and right now we're submitting
| | 00:34 | using the WP nonce field
in the check_admin_referer.
| | 00:36 | Well, instead we are going to do it
using the new settings methodology.
| | 00:42 | So in order for that to work, we
need to register whatever settings are
| | 00:46 | available for the plugin.
| | 00:48 | So let's create a function.
| | 00:49 | We will call it cccomm_init,
because it's essentially just going to
| | 00:56 | initialize our application.
| | 00:59 | Then what we are going to do in here
is we are going to use this special
| | 01:02 | function called register_setting.
| | 01:04 | It's going to take, essentially, the
group of setting that we want to register
| | 01:10 | under and then the specific
setting we want to register.
| | 01:13 | So you may have multiple ones in a
single group, and it allows you to essentially
| | 01:17 | organize them how you want to.
| | 01:19 | So we'll call this group cccomm_
options, and the specific setting we are
| | 01:24 | registering is cccomm _cc_e-mail.
| | 01:30 | Notice that's the same name as the
option we are using before, and that's
| | 01:33 | actually storing it in the same place.
| | 01:37 | In order for this function to run,
we need to register with a hook.
| | 01:41 | So we are going to use the admin
init hook, add_action, admin_init.
| | 01:46 | We are going to call cccomm_init.
| | 01:51 | That will then run this
function, which will register our options.
| | 01:56 | Now there are some things we need to
do to make our form page work correctly.
| | 02:00 | The first thing, let's copy our
settings name and make sure that anywhere where
| | 02:07 | we are referring to that
data, we use that information.
| | 02:11 | So the ID is going to correspond to
the settings name. That's important.
| | 02:17 | Then we can erase the processing,
because WordPress is now going to handle the
| | 02:21 | form submission for us, because we are going
to submit it to the options page, at options.php.
| | 02:28 | We can keep to get_option the same,
because we are actually getting the same thing.
| | 02:32 | Everything else will basically work.
| | 02:34 | We no longer need to introduce nonces,
but we do need to put a call to the
| | 02:41 | settings_fields option, and this
method is going to output nonces and
| | 02:50 | everything for the entire group.
| | 02:52 | So notice this is the
group that we are referring to.
| | 02:54 | So you might have a number of fields
that you're grouping together, and you only
| | 02:58 | have to run this function once.
| | 03:00 | So by using the Settings field, we can
go back to our WordPress admin, we can
| | 03:05 | change this to whatever we want to, and
submit it just like we did before, and
| | 03:10 | it will save the settings.
| | 03:12 | If you look in the source, notice it's
submitting the options PHP, and notice
| | 03:19 | that it's generating this nonce information.
| | 03:24 | So that's automatically happening because
we're running that settings field function.
| | 03:30 | So as you can see, this is a much
cleaner and easier way to do it.
| | 03:34 | So if you're developing a plugin
options page currently and don't need to worry
| | 03:38 | about compatibility with WordPress 2.7 prior to,
| | 03:42 | then it's better to use this API.
| | 03:44 | The old method is deprecated, which
means it's no longer supported and at some
| | 03:48 | point they may remove it
from the WordPress code.
| | 03:51 | In addition, you can call, if you want to,
a register setting function that allows
| | 03:56 | you to specify a function that you can
use to do any sort of sanitizing of the
| | 04:00 | data before you submit it to the options.
| | 04:03 | So all in all, this is a much cleaner
and better way for saving your options in
| | 04:06 | the WordPress database.
| | Collapse this transcript |
| Integrating with the WordPress admin menus| 00:00 | It was easy enough to add a page into
the WordPress admin under the Settings
| | 00:04 | menu, using the Add Options page function.
| | 00:07 | There might, however, be other times
when you want to do something more or
| | 00:10 | something different,
| | 00:10 | for example, if you want to create a
link under the user section or under media
| | 00:15 | section or maybe you have bunch of
options pages, and you want to create a whole
| | 00:19 | new menu setting with submenus.
| | 00:21 | We can do all these things.
| | 00:22 | Let's go back to our cc_comments plugin.
| | 00:26 | I want to show you that I've
taken the plugin and moved it into a
| | 00:30 | separate subdirectory.
| | 00:32 | I have also created a little icon,
which we'll talk about in the second.
| | 00:36 | The reason why I did this is because I
have a couple of files, and I didn't want
| | 00:39 | these files to get all mixed
up with all the other plugins.
| | 00:42 | So it's easy to organize them in a
single directory, and it's actually
| | 00:45 | good practice to do so.
| | 00:47 | If you've already created your file in
the root directory, and you want to move
| | 00:51 | it, just make sure to reactivate
your plugin, because it won't find the
| | 00:55 | original one and will deactivate it.
| | 00:57 | It will find the new one, but it will
detect it as if it's a new plugin.
| | 01:00 | Here is our old function
that was generating our menu.
| | 01:03 | It's calling add_options_page.
| | 01:05 | There are a number of different
other functions you can call other
| | 01:08 | than add_options_page.
| | 01:10 | If you remember this one, put it
inside of the Settings down here, but we can
| | 01:17 | also move it and put it somewhere else.
| | 01:22 | There's an add_media page, an add_post
page, an add_themes page, an add_links
| | 01:26 | page, add_users page, add_plugins page,
and there's even an ad_dashboard page,
| | 01:32 | which allows you to put it in that submenu.
| | 01:35 | So all of these special functions are
built-in for these specific menus, and you
| | 01:40 | can see it added up here. Notice also that
| | 01:43 | that screen icon function I used will
actually change based on where you move it to.
| | 01:48 | If however you want to create your own
menu, you are going to have to use a new
| | 01:52 | function called add_menu page.
| | 01:57 | Most of these are the same.
| | 01:59 | You are going to have the name of your menu--
| | 02:01 | let's just keep it cc_comments--you
are going to have whatever you want to
| | 02:04 | show up in the menu,
| | 02:05 | you are going to have whatever the
capabilities of the user are, some kind of
| | 02:10 | handle, and then whatever function
you want to run to generate the page.
| | 02:15 | In addition, you're able to specify an
icon, and I put this one in wordpress/
| | 02:24 | wp-content/plugins/cc_comments/cc_icon.png.
| | 02:34 | Of course, there will be particular
installations, and you could put a dynamic
| | 02:37 | variable here, but for simplicity's
sake I am just going to type it in.
| | 02:41 | Make sure you separate that with a comma,
and now when I refresh it, you should
| | 02:49 | see that it's added on an entirely new
section with my icon, which will link
| | 02:55 | directly to that page.
| | 02:57 | You can also use a second option here,
which is a priority, to determine where
| | 03:02 | it's going to show up in the menu.
| | 03:04 | You can see it moved it up here.
| | 03:07 | You can change and lower the numbers
to determine where it's going to fit
| | 03:10 | inside of your menu.
| | 03:12 | So WordPress gives us a number of
options for quickly plugging option screens
| | 03:15 | into the admin menu.
| | 03:17 | You can use any of the built-in
functions, such as add_options page or add_theme
| | 03:22 | page, or you can use the add_menu page,
and there's another one, add_submenu page,
| | 03:27 | if you want to add additional submenus.
| | 03:30 | Whatever it is you want to do,
WordPress has the flexibility to do it.
| | Collapse this transcript |
| WordPress admin dashboard API| 00:01 | Since version 2.7, the WordPress
development team gave us the ability to
| | 00:05 | customize our own dashboards.
| | 00:07 | What this means is we can add our own
dashboard widgets into the WordPress admin.
| | 00:11 | These widgets work pretty much the same
as the ones we looked at earlier, only
| | 00:15 | they are plugged into admin
dashboard instead of the front of the web site.
| | 00:19 | They can be really useful in some
plugins because they allow for displaying
| | 00:22 | statistical data, or they
allow for quick updates.
| | 00:25 | So, let's take a look at the dashboard.
| | 00:27 | Here we are in the admin, and
you have probably seen this before.
| | 00:31 | We have all of these different widgets.
| | 00:32 | You can move them around if you want to.
| | 00:35 | Some of them have configuration options
you can edit that determine how much you
| | 00:40 | want to see, where you want to
get data from, however that works.
| | 00:45 | If you go into Screen Options, you can
turn these on and off, and do whatever
| | 00:52 | you want, basically, to customize it.
| | 00:55 | If you want to create your
own, you can create a plugin.
| | 00:58 | We have created one here, a simple_db_widget.
| | 01:02 | We can see, we've created it
just like any other plugin.
| | 01:04 | You are going to write a function
that's going to output whatever appears on
| | 01:09 | the dashboard widget.
| | 01:10 | So simple_dashboard_widget.
| | 01:14 | So in here I am just going
to create some visual codes.
| | 01:17 | I am going to go ahead and do my tags.
| | 01:20 | I'll just say, "Simple Dashboard
Widget," "Welcome to WordPress development."
| | 01:36 | And then, if you want, you
can do things like add links.
| | 01:38 | You can add dynamic stuff in here, but
for now we are just going keep it as a
| | 01:41 | simple static wizard.
| | 01:43 | There we are, good.
| | 01:45 | So there's our widget, pretty straightforward.
| | 01:48 | In order to add this into the WordPress
admin, we are going to need to register it.
| | 01:53 | So we are going to create
a function to register it.
| | 01:56 | I am going to use sdbw as the prefix,
| | 01:59 | so we can keep it clean.
| | 02:01 | It's called register_widget,
and then in here, we can say
| | 02:05 | wp_add_dashboard_widget, and this is
our special dashboard widget function.
| | 02:13 | It takes the ID of the dashboard widget.
| | 02:16 | We will call it simple-dashboard-
widget, and you may refer to this in other
| | 02:20 | places so make sure you choose
something unique and something you can
| | 02:22 | remember, and then whatever the name
is. This is just going to be sort of a
| | 02:26 | user-friendly name.
| | 02:27 | This will be what you see in the screen options.
| | 02:30 | Then you will pass in the function
that's going to be used to generate the widget
| | 02:35 | itself, which is simple.
| | 02:37 | It's a function we already created.
| | 02:39 | You might also pass in a control
function, which will handle editing of
| | 02:42 | options, but we are not
going to worry about that.
| | 02:45 | The last thing to do is to add an
action, and this action is going to be in
| | 02:50 | wp_dashboard_setup, and it's going
to call the function we just created.
| | 03:01 | This will then call this function when
this hook is triggered, which will then
| | 03:05 | set this function up to
display in the dashboard.
| | 03:08 | So let's go into our admin, and go
into the plugins page and activate our
| | 03:13 | simple dashboard widget.
| | 03:16 | Now when we return of the dashboard, we
can see our simple dashboard widget had
| | 03:20 | been added, and we can minimize it, and
we can move around just like we can any
| | 03:25 | of the other widgets, and if we go
screen options, you can see we can turn it on
| | 03:28 | and off from up here.
| | 03:31 | If you want to find out more about WordPress
admin widgets, you can find it at the Codex.
| | 03:37 | There is a whole page at
WordPress.org that will tell you about it.
| | 03:41 | You can learn about how to move these
around and do all kinds of other stuff.
| | 03:45 | Since version 2.7, WordPress gives you
the ability to add your own widgets to the
| | 03:50 | WordPress admin dashboard.
| | 03:51 | It's basically a three step process:
| | 03:53 | You write a function that outputs your widget,
| | 03:56 | you write a function to register the
widget, and then you add an action for
| | 03:59 | Add Dashboard Widget.
| | 04:01 | Once you add it in, you can then
see your widget in the dashboard.
| | Collapse this transcript |
| Using existing options and option editing pages in WordPress| 00:00 | The WordPress options database has
a number of options stored in it.
| | 00:05 | Some of these are built into
WordPress, and they might be handy to use in
| | 00:08 | your own applications.
| | 00:10 | In addition, you might want to be
saving your own settings in here, and having
| | 00:15 | them displayed in the built-
in setting pages in the admin.
| | 00:18 | So we're going to talk about how
to integrate with these options.
| | 00:21 | Let's go into the WordPress admin
and take a look. There is a page you can link to--
| | 00:26 | you have to go there directly;
| | 00:27 | there is not actually a link--in the
admin menu called options.php, which contains
| | 00:32 | all the settings in the database.
| | 00:33 | So you can see this is all here.
| | 00:37 | Some of these are key, and you may want to
access at different points in your application.
| | 00:41 | You can always use get_option to refer to
these just like we referred to our own options.
| | 00:45 | So you can see the admin_e-mail is a good one.
| | 00:48 | The blogdescription can be
helpful. The blogname can be helpful.
| | 00:54 | We also have information about
the web site, what the URL is,
| | 00:59 | stylesheet, all kinds of good information.
| | 01:01 | In this page itself, you can
actually edit this data directly.
| | 01:05 | So if you ever want to just quick change
an option, you can do it right from here.
| | 01:09 | If you want to integrate your own
options into the built-in Settings pages, you
| | 01:15 | can do that, if you remember our cc_
comment plugin that we created allows us to
| | 01:20 | edit a cccomm_cc_e-mail.
| | 01:23 | Let's move this into the settings page.
| | 01:26 | So first we can delete our existing form page.
| | 01:30 | We won't need any longer.
| | 01:31 | Then we can delete what's in the
existing function to handle adding it to the
| | 01:38 | menu, because it won't need
to be in the menu any longer.
| | 01:41 | The first thing we're going to need
to do is create a function that will
| | 01:45 | generate an input field to handle this setting.
| | 01:49 | So we'll create this, and
we'll call it cccomm_setting_field.
| | 01:56 | In here we're simply going to create
input type = "text" name = "cccomm_cc_e-mail"
| | 02:08 | id = "cccomm_cc_e-mail," and the
value we're going to use get_option.
| | 02:19 | So echo get_option cccomm_cc_e-mail, and
then close a tag, and then we'll want to
| | 02:29 | of course go back into php.
| | 02:32 | So we don't need to do anything else with this.
| | 02:35 | You just need to make sure that the ID
and the name field match the option.
| | 02:39 | Then to add this into the
Settings page, we're going to use the
| | 02:43 | special add_settings_field.
| | 02:48 | You can specify an id, cccomm_cc_e-mail.
| | 02:55 | You're going to specify what you want
to read for the label of that field.
| | 03:04 | Then you want to specify the
function that's going to generate the field.
| | 03:08 | So this is going to be cccomm_setting_
field, and finally the section it's going to
| | 03:15 | be, which will be the general section.
| | 03:19 | Notice we're already adding this into
the admin_menu hook, so that should put it
| | 03:23 | into our menu for us.
| | 03:26 | So if we go back to our
General Settings and we refresh it and
| | 03:30 | we scroll down, we should see our CC
Comments has now been added to this page.
| | 03:36 | If you want to have multiple settings
and create different sections, there is
| | 03:40 | another function that enables you to
create an entirely new section heading.
| | 03:45 | So you'll create a function that
outputs the section, and here you can just do
| | 03:54 | something simple Settings.
| | 04:03 | Then we'll use this add_settings
_section to add it directly in.
| | 04:13 | So we say cccomm, which is an ID
of the section. We have a name.
| | 04:22 | We have the function that's going to generate.
| | 04:25 | It's going to run once, essentially,
at the beginning of this heading.
| | 04:28 | So this will be cccomm_setting_section, what we
just wrote, and where you want it to appear,
| | 04:37 | in this case in the general section.
| | 04:39 | The only other thing you need to do at
this point is specify if your fields are
| | 04:43 | going to fall under that section.
| | 04:45 | So there is another option here where
you can specify that, and we just use the
| | 04:50 | ID that we created for that section.
| | 04:53 | Now if we go back to our Settings page,
we can reload, and you'll see we have our
| | 04:58 | CC Comments section.
| | 04:59 | Notice it outputs the name and then
whatever you had in your code, and then we
| | 05:04 | would have whatever fields afterwards.
| | 05:06 | So we can access any of these settings
that are stored in the options database.
| | 05:11 | We also, since WordPress 2.7, have the
ability to add our own items directly
| | 05:16 | into the Settings pages.
| | Collapse this transcript |
| Using jQuery and AJAX for administration| 00:00 | WordPress developers are
increasingly looking to use AJAX.
| | 00:04 | AJAX stands for Asynchronous JavaScript and XML.
| | 00:07 | It's a term that essentially defines
the methodology of having JavaScript make
| | 00:12 | calls to services to get data, and
that way you can update the user interface
| | 00:17 | without having to go to the server
and regenerate an entire new HTML page.
| | 00:22 | Overall this makes for a faster and
better user experience. Fortunately,
| | 00:26 | WordPress has his built-in, so we can
use AJAX calls directly, and it also has a
| | 00:32 | number of libraries, like JQuery.
| | 00:33 | So let's look at how to put
those into our admin pages.
| | 00:37 | To start, WordPress has a special
file called adminAJAX.php that's used for
| | 00:43 | all the AJAX calls.
| | 00:44 | We can write functions in our PHP that
can be used by this file to return some
| | 00:50 | kind of data, to do
whatever it is we need to do.
| | 00:52 | So we are going to use AJAX
to do some e-mail validation.
| | 00:57 | We are going to do some simple scripts,
and truth be told, you could probably do
| | 01:00 | this directly in JavaScript, but it's a
good way to illustrate the power of it.
| | 01:05 | And in addition, when you call to a
server like this, you can also make checks
| | 01:09 | to see if an e-mail exists in the
database or do a little bit more heavy
| | 01:13 | crunching than you might be
able to do just in JavaScript.
| | 01:16 | WordPress allows us to create
functions that can be called on via the
| | 01:19 | admin AJAX.php file.
| | 01:23 | These functions are essentially going
to get data posted to them, and then they
| | 01:26 | can then out put some data, XML,
JSON, or some other information.
| | 01:31 | So let's go ahead and write one
that does can validate e-mail for us.
| | 01:34 | So we will call it cccomm_e-mail_check.
| | 01:41 | And first what we are going to
do is we are going to set a variable
| | 01:43 | called e-mail, and what we can do is
we are going to set it equal to either
| | 01:47 | an e-mail that's been posted or null,
depending on whether it has been posted or not.
| | 01:52 | So we can do this little check, is
set--it's a handy little function if
| | 01:56 | you've never used it--
| | 01:58 | _post, which is where all of our
post data comes to, and we'll say
| | 02:02 | cccomm_cc_e-mail. So this actually
matches the name of our field that we
| | 02:10 | created for our settings.
| | 02:13 | So if it is set, then were going
to set the variable equal to that.
| | 02:18 | If you remember, we are using
the shorthand 'if-else' statement.
| | 02:23 | So, basically this is the check, and
this is the 'if', and then we can do an
| | 02:28 | 'else', and if it isn't found,
then we will just set it to null.
| | 02:32 | Then we are going to create the second
variable called message, and in there we
| | 02:37 | are going to default it to invalid--
| | 02:39 | in other words, guilty until proven innocent--
and then we can go ahead and do our check.
| | 02:45 | So will say if e-mail, and what
that statement does is that will test
| | 02:49 | whether it's null or not.
| | 02:51 | So if it's null, then this will fail.
| | 02:54 | If it's not null, then that
means we have something set in there,
| | 02:57 | so now we can validate it. And
there's a special function built-in into
| | 03:01 | WordPress called is_e-mail, which
will perform the validation for us.
| | 03:08 | If it is an e-mail, than we just simply
set message equal to valid, and in the
| | 03:14 | end, we are going to out put whatever
in our message string and then die, and
| | 03:21 | make sure you do this.
| | 03:23 | This essentially stops processing so that
nothing else inside the M and AJAX give process.
| | 03:28 | It's a good idea, because if you don't
do this you might find you get a zero, or
| | 03:32 | -1, or something weird at the end of your call.
| | 03:36 | So that's basically it, on
the server side of things.
| | 03:39 | On the client side of
things, there's a little bit more.
| | 03:42 | We need to create a JavaScript.
| | 03:45 | So let's go ahead and go to New > File,
and we'll create cc_comment.js, and make
| | 03:53 | sure it's in the same
directory, the cc_comment directory.
| | 03:57 | This might look a little weird at first.
| | 03:59 | This is jQuery syntax. It takes a little
getting used to, but once you used to, it make sense.
| | 04:03 | We are basically going to say, when
jQuery is ready, then we are going to
| | 04:09 | call this function.
| | 04:12 | Now because jQuery in WordPress runs
in what's called no conflict mode, you
| | 04:17 | usually can't use this special dollar
sign prefix, but if you pass it to this
| | 04:22 | function, then you'll be
able to use it throughout.
| | 04:25 | So let's go ahead and pass it to this function.
| | 04:30 | Now what we are going to do is, once
it's ready, we're now going to set up an
| | 04:33 | event handler to handle when the user
tabs out or somehow loses focus once
| | 04:39 | they've gone into the e-mail input.
| | 04:41 | So what we do is we use our $ sign--
| | 04:43 | it's a signifier to jQuery--and we'll
specify that we want to refer to an input
| | 04:51 | in our document where the name=cccomm_cc_e-mail,
| | 05:00 | which not coincidentally is
what our option input is called.
| | 05:03 | So this should find that input in our
document, and then we are going to add a
| | 05:08 | blur event handler to that. And
in the blur event handler, we are going
| | 05:15 | to do our AJAX call.
| | 05:18 | So there's an AJAX method, and the
way it works is it takes a little object
| | 05:24 | inside of which you set the type,
and we are going to send it POST.
| | 05:30 | You can set the data that you want to send.
| | 05:35 | In this case, I'm basically going to
build like a little URL string, so I am
| | 05:39 | going to say cccomm_cc_e-mail is equal to,
and then I am going to concatenate on this.
| | 05:51 | This in this case refers to the input,
because that is essentially what this
| | 05:56 | method is running on.
| | 05:58 | And then we are going to get the value
attribute, whatever is stored in there,
| | 06:05 | which should be your e-mail, correct?
| | 06:06 | And then we are going to add on what
the action is, cccomm_e-mail_check, to URL.
| | 06:20 | Just type in ajaxurl just like that.
| | 06:23 | It's an auto magic variable that
exists in there, because the WordPress
| | 06:28 | environment sets it up for us.
| | 06:32 | Now we are going to set a special the
beforeSend. The beforeSend is what's going
| | 06:37 | to happen, essentially,
before we make this AJAX call.
| | 06:41 | And what we are going to do is
we are going to say, e-mailInfo.
| | 06:46 | We are going to prefix this with
a pound, which just like css
| | 06:51 | that means it is going to refer to
something with the ID of e-mail info.html.
| | 06:58 | Then we'll say, "Checking e-mail," and
that's going to refer to a div tag.
| | 07:04 | I didn't add it earlier, but
we'll go in and add it in the second.
| | 07:07 | So that's beforeSend, now we can do the success.
| | 07:12 | So success is when our data comes back,
and the handler for success can take an
| | 07:18 | argument of data, which is going to
be the actual data that we get back.
| | 07:24 | The data we get back is going to
either be the string valid or the string
| | 07:28 | invalid, depending whether or not it passed.
| | 07:30 | So we can do that test here.
| | 07:32 | We can say if data=valid.
| | 07:37 | Then we can say, #e-mailInfo.html,
"Email OK" else e-mailInfo.html, "You have
| | 07:56 | entered an invalid e-mail."
| | 08:01 | So that's basically it.
Let's go ahead and clean that up.
| | 08:04 | Let's make sure we've got
everything in order here, and see we have our
| | 08:08 | if-else, we got that brace.
| | 08:11 | This brace refers to our AJAX call,
this one do our beforeSend, this one to the
| | 08:17 | function on the blur, and then this last
one to the jQuery. And we can end each
| | 08:22 | of these with a semicolon, just to keep a clean.
| | 08:26 | Just go ahead and save the script.
| | 08:28 | Let's go back into our PHP file. Right
up here where the setting field is, you
| | 08:36 | can see I have added a div
file, with an id of e-mailInfo.
| | 08:41 | This is where I am going
to output that information.
| | 08:44 | If you haven't added that,
make sure to add that now.
| | 08:47 | The last step then in making this all
work is to include all of these scripts.
| | 08:53 | So to include our AJAX call, we use the
action wp_ajax_--and this is a special one,
| | 09:04 | it's dynamic.
| | 09:05 | So wherever you want the action to be
in that AJAXadmin or adminajaxphp, you
| | 09:10 | want to put it here, so we called it
cccomm_e-mail_check, and then the function
| | 09:18 | you want to run, which is
going to be cccomm_e-mail_check.
| | 09:25 | So note that whatever comes after
wpajax_ here is going to match the action
| | 09:32 | that you specified here.
| | 09:36 | So that sets up the server side of
things. Now, we are going to add an action
| | 09:42 | for including scripts, so the action is called
| | 09:45 | admin_print_scripts-options-general.
php, and then we are going to specify a
| | 09:56 | function that we haven't created yet
but we will create right now, called
| | 09:59 | cccomm_e-mail_check, and you
can go ahead and copy that.
| | 10:08 | So look at this action here.
| | 10:10 | This is another dynamic one: admin print
scripts is used to include JavaScripts.
| | 10:15 | You can also specify a page.
| | 10:17 | If I don't specify it, it will include
on every admin page. But since I'm only
| | 10:21 | using it on options general page, then
I can specify only to include it there.
| | 10:26 | So the last thing is to write this
function to set up my scripts, and the way
| | 10:32 | this function works is there's a
special function called wp_enqueueu_script, and you
| | 10:39 | specify the name of the script.
| | 10:44 | And then you specify where the script is.
| | 10:47 | In the last unit, we just output a static icon.
| | 10:51 | Well, I could have done it dynamically,
and this is what it would have looked like if
| | 10:54 | you want to access something dynamically.
| | 10:57 | So we put path_join, and basically what
we can do is we're going to get the base
| | 11:03 | of the plugin path, and then
we're going to add /our JavaScript.
| | 11:10 | So we'll say path_join.
| | 11:12 | We can use this special wp_pluginurl
to specify that we are going to go into
| | 11:19 | the plugin directory.
| | 11:20 | Then we will say base name, and then we
will say directory name for the current
| | 11:26 | file, and then right here we can append
cc_comment.js, so that we will get our script.
| | 11:40 | And then lastly, we can also go
out and get additional libraries.
| | 11:47 | So I am going to create an array, and I
am going to specify in this array--actually, I'll use
| | 11:50 | single quote--'jQuery'.
| | 11:55 | There are other ones available to access.
| | 11:58 | If you go into The Function Reference/wp
enqueue at the WordPress Codex, you can
| | 12:04 | see it will not only tell you what all
these mean exactly, and how to use them,
| | 12:07 | but it will also tell you
which specific ones are available.
| | 12:11 | You can see we have these Scriptaculous
ones, SWFObject for embedding SWFs, and
| | 12:17 | we have a number of
different jQuery libraries as well.
| | 12:19 | In addition, we have all the built-
in things that are used by WordPress;
| | 12:23 | you can access any of these in your files.
| | 12:26 | So I have got this all set up.
| | 12:28 | I think I spelled enqueue
wrong, but it looks good.
| | 12:33 | So let's go ahead and save it, and
let's go back into the admin, and make
| | 12:37 | sure our plugin is activated, cccomm,
and it is, so in our settings file we
| | 12:44 | should see our comment, and one
really helpful thing is you see this little
| | 12:48 | bug I have right here.
| | 12:50 | This is the firebug plugin
that you can get from Firefox.
| | 12:54 | This can be really helpful if there's
ever any issues, because it will tell you
| | 12:57 | what requests and responses are being made.
| | 12:59 | It will give you specifics about
JavaScript errors; otherwise is very hard to debug.
| | 13:04 | So if I'm tabbed in here, and I tab out, I
got this message here that I have three errors.
| | 13:08 | This is thank you to firebug, so
you can see it's giving me error.
| | 13:13 | This is not defined.
| | 13:15 | So let's go back and see
where that's being called.
| | 13:18 | I think I made a typo.
| | 13:21 | See how the $ sign is inside of this?
| | 13:23 | It should actually be outside of it.
| | 13:26 | It comes before it.
| | 13:27 | So let's go ahead and save it,
and make sure you refresh the page.
| | 13:33 | I like to hold the shift key down with Firefox.
| | 13:35 | It will make sure that it clears out
anything that's in memory as well and
| | 13:39 | loads a fresh version.
| | 13:40 | So now I will go into My Comments.
| | 13:42 | When I tab out, it tells me it goes to
check it, and the e-mail comes back okay.
| | 13:47 | And if you look in firebug, on the
console, you'll see that I have a post.
| | 13:51 | It will tell me what was posted, and
then it will tell me what was returned,
| | 13:55 | which is valid is, which is what I would expect.
| | 13:57 | However, if I typed in an invalid e-mail,
you can see it went out, and it returned
| | 14:05 | invalid, and gave me the
correct message. So, all in all,
| | 14:09 | I did that without having to refresh the page,
and that's the power of AJAX and jQuery.
| | 14:14 | So WordPress has integrated AJAX and
jQuery into the admin, so that we can
| | 14:18 | integrate this and ultimately create
a smoother and better experience for
| | 14:22 | our users.
| | Collapse this transcript |
|
|
6. Using the WordPress DatabaseAccessing the WordPress database| 00:00 | WordPress is powered by a MySQL database.
| | 00:03 | The main way that we can access this
database directly is using the special wpdb
| | 00:08 | class, which is loosely based on EasySQL.
| | 00:11 | It's an abstraction of the SQL
language for MySQL, and it does require a
| | 00:15 | little bit of knowledge of
Structured Query Language.
| | 00:18 | Keep in mind that while you can
access most of the data in the database
| | 00:21 | directly, you probably don't want to do.
| | 00:23 | There are a lot of different functions
made there to get options and get posts
| | 00:27 | and pages and things like that.
| | 00:28 | You want to use those where possible.
| | 00:30 | Eventually, you may be creating
your own database tables, and this can
| | 00:33 | be helpful to know.
| | 00:34 | I have a dbinfo.php plugin that I
created in our plugins directory, and it's
| | 00:41 | set up to be a widget in the admin.
| | 00:43 | So you can see I've added this
dashboard widget function which registers that
| | 00:48 | function, and then I added the action.
| | 00:50 | So I am all set up, just like we
learned how to do in the admin widgets video.
| | 00:55 | What I am going to do now is I am
going to access the wpdb class, so the first
| | 00:59 | thing I need to do is set it
into the global scope.
| | 01:04 | That allows me to access it at will.
| | 01:06 | Now I am going to output some data.
| | 01:09 | First, I am put a little title, "DB Info
Dashboard Widget," and under here--let's
| | 01:15 | make sure to close that out because
I am going to be using a PHP in here.
| | 01:22 | And let's go ahead and just output this
directly, so we'll just put little pre,
| | 01:25 | and we'll just say php echo.
And there is special function
| | 01:29 | called var_dump, which allows you to see
the properties of any object, and we'll
| | 01:34 | just pass in $wpdb.
| | 01:38 | So we'll save it, and let's go into the
Plugin screen and activate it, and then
| | 01:41 | we can go to our dashboard,
and we should see it up here.
| | 01:46 | So you can see, it's output all this data.
| | 01:50 | We have show_errors, suppressed_errors,
last_error, num_queries, num_rows,
| | 01:54 | rows_affected, and all kinds of different
information that tell us about the database.
| | 02:00 | All the different fields
are available as properties.
| | 02:02 | You can see I have the categories field.
| | 02:04 | I have some other things, the users
table, the taxonomy table--all this
| | 02:10 | information I can access.
| | 02:12 | We don't need to see all that though, but
maybe we do want to see a couple of things.
| | 02:16 | So let's add something
that will output the last query.
| | 02:22 | So to do that, we simply echo $wpdb-->last_query.
| | 02:29 | I am going to close the paragraph.
| | 02:31 | We'll do another one that will show the last error.
| | 02:38 | It's just for admin users, so they can
see what's going on in the database.
| | 02:44 | Let's go ahead and refresh.
| | 02:45 | So you can see we have our last
query, which is something in regards to
| | 02:51 | generating the menu, and the last
error, which is nothing, because we haven't
| | 02:57 | had any errors yet.
| | 02:58 | All right, so let's go ahead
and get some more information.
| | 03:02 | There's a special query method that
will run the query, but it'll returned how
| | 03:04 | many records were affected by that
query. And a lot of times we use this for
| | 03:08 | insert and updates and things.
| | 03:10 | But it can be a good way
to get a count of something.
| | 03:12 | So Total Users, and then we can just
say echo $wpdb-->query and
| | 03:21 | then in here, we can just say
SELECT ID from wp_users.
| | 03:27 | And you can type in the
fields directly, although usually you're
| | 03:30 | going to want to use these
variables, which I'll show you in a second.
| | 03:32 | So you can see I have two
users currently in the database.
| | 03:43 | If you want to access data from the database,
there's basically four ways you can do it:
| | 03:47 | You can get a single field from the database,
| | 03:50 | you can get a single column, you can
get an entire row, or you can get a whole
| | 03:54 | result set from a query.
| | 03:56 | So if I wanted to just get a single
field, I am going to ahead and get the Last
| | 04:01 | post, and we are just going to say
echo $wpdb-->get_var, and then
| | 04:09 | I want to say SELECT post_title FROM
and then to use table names that are
| | 04:17 | built in, you can just concatenate on
the properties, wpdb, and this is going to
| | 04:22 | be in posts, dot.
| | 04:23 | And then you can add a where clause:
| | 04:27 | WHERE post_author=.
Let's got ahead and put this on a
| | 04:32 | new line so we can read it.
| | 04:35 | Make sure you have enough space in
between here. Now, I want to get the ID of the
| | 04:39 | current user, and I can do that by
globalizing the current user property.
| | 04:44 | So now I can just concatenate in here, the ID.
| | 04:48 | So this will tell whoever's looking at
the query the last post that they made,
| | 04:53 | and then we'll close the paragraph. Refresh it.
| | 04:59 | So the last post was Hello world!
which is the only post because we're just
| | 05:05 | using the default installation.
| | 05:07 | When you go into get an entire column,
an entire row, or a result set, you are
| | 05:12 | going to use Get call, Get row, or Get results.
| | 05:16 | They basically work the same way
where we are going to pass a query, only
| | 05:19 | instead of returning a single value,
they're actually going to arrays, and
| | 05:23 | you can control how that's output, and
we'll look at how to use those in future videos.
| | 05:28 | So WordPress has the built-in wpdb
class that allows us to access the
| | 05:33 | built-in WordPress database.
| | 05:34 | In addition to the number of properties
it has that can give you all kinds of
| | 05:37 | information about the database,
| | 05:39 | it also has a number of methods that
allow you to query the database in a number
| | 05:43 | of different ways directly.
| | Collapse this transcript |
| Using the built-in schema| 00:00 | So WordPress is powered by a MySQL database.
| | 00:03 | This database stores all the posts, all
the users, all the comments, the tags,
| | 00:08 | the categories--everything you
see in the WordPress environment.
| | 00:12 | It can be really helpful to
know the structure of this in your
| | 00:14 | Plugin development.
| | 00:15 | You can find this all at the Codex.
| | 00:17 | There is a special page dedicated just
to the database description, and you can
| | 00:22 | see here, there's different versions.
| | 00:24 | So the database is continually
changing and evolving, which means when
| | 00:28 | possible you want to use the
functions created specifically to access the
| | 00:31 | database instead of
accessing the database directly.
| | 00:34 | If you do need to know the structure,
you can download that schema at the Codex,
| | 00:38 | and you can see it here.
| | 00:40 | You can see we have a posts.
| | 00:42 | We have a users; that's where the main
data is stored. The options are stored in a
| | 00:47 | separate file, and links
are stored here as well.
| | 00:50 | We also have some other
data types that are stored.
| | 00:53 | Some of the meta comments,
| | 00:55 | these are basically used for custom
fields, so wp_usermeta is used whenever you
| | 01:00 | create a custom field for a user, just like
postmeta is created as custom fields for posts.
| | 01:06 | Keep in mind that you wouldn't have
to access wp_posts; you could use the
| | 01:11 | wpdbpost property to get
the name of that database.
| | 01:15 | In case that should never change in the
future, it would keep your code from breaking.
| | 01:19 | If you want to look at your database
directly, along with the MAMP installation,
| | 01:24 | they have an install of phpMyAdmin.
| | 01:27 | This will give you access to your database.
| | 01:30 | You can see it listed here. Whatever
name you gave it when you first start it
| | 01:33 | up, you'll to see it.
| | 01:34 | When you click on it, you'll be able
to access the different tables, and from
| | 01:38 | there you, can see the types of data that
are in each table, and you're also able
| | 01:43 | to go through and view what's in the fields.
| | 01:46 | You can browse the table itself, and
you can also go in and run SQL on it, and
| | 01:51 | do all kinds of other tests.
| | 01:53 | So the built-in database stores all
kinds of information that's useful when
| | 01:57 | you're working in WordPress.
| | 01:59 | This includes anything from users
to pages to comments and links.
| | 02:03 | Understanding the structure of the
database might be helpful for plugin
| | 02:05 | development, if you should
need to access things directly.
| | 02:09 | But be careful; there are many times
when you can get this data and interact
| | 02:12 | this data without actually having to
access it directly using the built-in
| | 02:16 | functions, and when that's the case,
it's usually a best practice to do so.
| | Collapse this transcript |
| Accessing data using $wpdb| 00:00 | You can access the WordPress database directly.
| | 00:02 | We'll look at other and better ways of
accessing data, such as accessing posts
| | 00:06 | and pages through the loop and other units.
| | 00:08 | But there might come a time when you
need to go down there and get right into
| | 00:12 | the data, and you don't
want to use the WordPress API.
| | 00:15 | In such cases, you have the ability
to use the wpdb class and SQL to get
| | 00:20 | your data directly.
| | 00:22 | So, if you recall, we built this dbinfo
plugin. It creates a little Dashboard
| | 00:27 | Widget that output some
information about the database.
| | 00:30 | We're going to use this
plugin to do some further querying.
| | 00:34 | To get a single field of data, we use
the get_var method of the wpdb class.
| | 00:39 | However, if we want to get more data, we
have a couple other classes we can refer to.
| | 00:44 | We have a class called get_col,
which will get an entire column of data.
| | 00:49 | So, if we want to get, for example, all
the e-mails for a user in the database,
| | 00:54 | so we'll create a variable called
User Emails, and we'll call get_col, and
| | 00:59 | then we type in our SQL.
| | 01:02 | So we'll say 'SELECT user_e-mail FROM,'
and it's always a best practice to use
| | 01:07 | the variables in the wpdb class for
the table names, just in case they change
| | 01:13 | in future versions.
| | 01:14 | Oops, I misspelled this.
| | 01:16 | Make sure you spell this
correctly, user_e-mails.
| | 01:19 | So now we're going to take that data
and just output it using the <pre> tag.
| | 01:26 | So, go ahead and say echo
var_dump($user_e-mails).
| | 01:34 | Go ahead and save it and refresh, and
you can see it outputs these two variables.
| | 01:43 | In addition to get_col, we also have get_
row, which will return a single row of data.
| | 01:49 | So, if you wanted to see your user
information, you could say "Your user info:"
| | 01:58 | and then we can use my--I'm just
creating a variable here--user_data equals
| | 02:05 | wpdb, and then we use get_row and we
say, SELECT *--which is every field--
| | 02:14 | FROM, and again we use the properties
users, WHERE ID is equal to, and then I
| | 02:23 | can get my own user ID by referring to
this current_user object we created up
| | 02:28 | here, saying current_user->ID.
| | 02:32 | Now, there is an optional variable
you can append to this, which will tell
| | 02:37 | whether you want to get your values
in numbers or as an associative array.
| | 02:42 | So, if we append ARRAY_N, that will
then get our data as an associative array.
| | 02:47 | So when we output it--
| | 02:49 | I've got a little L in
there instead of a semicolon--
| | 02:57 | so let's go ahead and refresh,
Your user info, Array. Oh!
| | 03:08 | I forgot to wrap this in var_dump.
| | 03:13 | Important piece there, because that
will actually parse and output the data;
| | 03:17 | otherwise it just outputs either the
variable value, if it's a simple variable,
| | 03:21 | or the type of variable it is.
| | 03:23 | So let's go ahead and refresh.
| | 03:25 | So you can see it's numeric: 0, 1, 2.
| | 03:30 | If instead I want to get the field
names and have it set up as an associative
| | 03:34 | array, I just change its value to
ARRAY_A, and now I get the value.
| | 03:42 | Usually with queries, this is a more
user-friendly way to get it, but it does
| | 03:46 | give you the option to get it
in other ways if you want to.
| | 03:49 | The last one I want to look at
is getting an entire result set.
| | 03:54 | So, I'm going to go into the Terms database
and get all of the post terms in the database.
| | 03:59 | Let's copy this so it's bolded.
| | 04:05 | We can go ahead, create a new
variable called terms, and set it equal to
| | 04:10 | $wpdb->get_results SELECT * FROM,
and again, we concatenate on terms, and we
| | 04:22 | don't need to specify.
| | 04:23 | We'll let it take the default. And then
we can actually just echo it right here;
| | 04:28 | you don't need to create another.
| | 04:29 | So, go ahead and save it and refresh
it, and you can see here is our terms.
| | 04:38 | Now, I didn't wrap it in <pre>, so, it
does not look as nice and pretty as this
| | 04:41 | does, but you get the idea.
| | 04:43 | We get all of our information, and
it's basically an array of variables, and
| | 04:48 | inside there's an associative array.
| | 04:51 | So the wpdb class gives us a few
different ways to get data out of the database.
| | 04:56 | In this video, we learned how to use
this class to access either a single data
| | 05:00 | point, a column of data, a row
of data, or a full record set.
| | 05:04 | Remember, it's a best practice to
access the database through the built-in
| | 05:08 | functions if you can.
| | 05:10 | However, you do have these available to
you, especially if you create your own
| | 05:13 | tables in the WordPress database.
| | Collapse this transcript |
| Creating new tables| 00:00 | The reason we've been looking at the
WordPress database and why we might want
| | 00:03 | to use it is because oftentimes our plugins
might actually need their own data structures.
| | 00:08 | Think about a program that collects
statistics, or maybe you want to build a
| | 00:12 | whole product database to display and
integrate for a client that you have.
| | 00:15 | Whatever the reason, WordPress gives
us a bunch of tools to create our own
| | 00:18 | tables in the WordPress database.
| | 00:20 | To create our data structure,
we're going to need to write a function
| | 00:23 | that creates it in SQL.
| | 00:25 | I've created here a plugin, and this
will basically save the user agent from
| | 00:29 | the browsers when they come to the site.
| | 00:31 | We can then parse it out later and show
whatever statistics we want about what
| | 00:35 | types of browsers are visiting our
site, whether people are using iPhone,
| | 00:39 | Android, or a regular computer.
| | 00:41 | So, in order to access the database, I
need to globalize the wpdb variable, so
| | 00:47 | that I can access it in my function.
| | 00:49 | Then I'm going to create a name for my table.
| | 00:52 | So I have a variable that I'm creating
called table_name, and I'm going to use
| | 00:55 | this special property called prefix,
to get the prefix of the database.
| | 01:00 | This is a best practice, because
oftentimes people will have a special prefix
| | 01:04 | they store in their WordPress installation.
| | 01:06 | So that way every table inside of the
WordPress database will have a prefix.
| | 01:10 | It's usually WP by default, but this
allows them to have databases that share
| | 01:16 | WordPress but also other functionality
as well. And we're going to create our
| | 01:19 | own table name and call it
"bdetector" to store our information.
| | 01:26 | So now what we're going to do is
we're going to go in and determine if the
| | 01:29 | table already exists.
| | 01:32 | If it exists, then we won't create it.
| | 01:34 | However, if it doesn't exist,
we're going to want to create it.
| | 01:36 | So, I'm going to create an if statement,
and the way I determine if the table
| | 01:40 | exists is I'm going to use the wpdb
class, and I'm going to call the get_var.
| | 01:46 | If you remember, this is what I used
to get a single field from the database.
| | 01:50 | Now I'm going to run some SQL, and
particularly I'm going to call 'SHOW TABLES
| | 01:55 | LIKE ', and then I'm going
to append on my table_name.
| | 02:00 | So, if this is not equal to my table_name,
then that means it didn't find it in the database.
| | 02:07 | So it's either going to be the table_
name if it exists, or it's going to be
| | 02:10 | empty if it doesn't exist.
| | 02:12 | If it doesn't exist, I'm
then going to run my query.
| | 02:16 | So first I'm going to set up my query.
| | 02:18 | I'm just going to create a variable
called sql, and I'm going to write it out.
| | 02:21 | So we're going to say 'CREATE TABLE ', and
remember you always want to have a space in here.
| | 02:28 | Otherwise, when you append variables,
the text is going to run up against one
| | 02:31 | another and cause database errors.
| | 02:33 | So, I'm going to put my table_name in
here, and now I'm going to write out what
| | 02:37 | the table looks like.
| | 02:38 | There's going to be an id, which is going
to be an INTEGER of size 10. It's UNSIGNED;
| | 02:44 | in other word, it is not going to be negative.
And we're going to set it to be AUTO_INCREMENT.
| | 02:49 | This is our key essentially.
| | 02:50 | I'm going to have a hit_date.
| | 02:53 | So I'm going to store when the user
came, that's going to be a TIMESTAMP, and
| | 02:56 | we're going to default it to CURRENT_TIMESTAMP.
| | 03:00 | What that means is the database is
automatically going to create this value if
| | 03:05 | one doesn't exist for the current time.
| | 03:07 | So, all I need to do is insert a record
in here, and it will timestamp it for me.
| | 03:12 | The user_agent is what I'm going to
store, and that I'm going to get from the
| | 03:15 | browser. And that's going to be a
string, and I'm just going to give it 255.
| | 03:21 | Most of them aren't going to be that
long, but it gives me some flexibility.
| | 03:24 | And then lastly, I'm going to
declare my PRIMARY KEY to be the id.
| | 03:29 | You may need to make sure that
there is a couple of spaces in there.
| | 03:33 | Okay, so there is my query.
| | 03:35 | Now, in order to actually do this, I'm going
to use this special function called dbDelta.
| | 03:41 | This offers some assistance.
| | 03:43 | Essentially what it will do is it'll
take this pattern here--and you want to
| | 03:47 | write it just like this with a new line
for each of the columns you're going to
| | 03:51 | create in the database--
| | 03:52 | dbDelta will essentially, if there is
any changes, it will update the table.
| | 03:57 | If not, it will just create it as is.
| | 03:59 | If it's the same, it won't do anything.
| | 04:01 | It's a very helpful function.
| | 04:03 | In order to use it, I'm going to have
to include it, and the way we include
| | 04:07 | things is to use this require_once function.
| | 04:10 | I'll specify the absolute path,
which is the absolute path of my
| | 04:14 | WordPress installation.
| | 04:16 | Then I'm going to say in the
WordPress admin directory, in the includes
| | 04:20 | directory, and it's called upgrade.php.
| | 04:25 | Incidentally, when you create your
own plugins, you're going to want to
| | 04:28 | use this same methodology to include
additional files if you break it up
| | 04:32 | into multiple files.
| | 04:34 | So now that we've included this, we can
call dbDelta, and we'll pass to it our query.
| | 04:42 | So, this will then create our database.
| | 04:45 | Another good idea to do, and this
is optional, is we're going to add
| | 04:49 | an additional option.
| | 04:51 | So we're going to use the option
database to set up an option so that we can
| | 04:55 | have a version of this database,
| | 04:57 | so that if we do want to do updates to
this particular plugin in the future,
| | 05:01 | we can simply look at our option and
see what version the database is and
| | 05:04 | update if necessary.
| | 05:06 | So, I'm going to call the add_
option function, and I'm going to call it
| | 05:10 | bdetector, so it's unique and then
database_version, and we'll just set it to 1.0.
| | 05:19 | So, now that I have all this set up,
I'm going to make sure that this runs for
| | 05:24 | the activation action.
| | 05:27 | So, if you recall, the way we do that
is we call register_activation_hook.
| | 05:33 | We pass the file, and we can use file,
which represents the current file, and
| | 05:37 | then the function that we want to
execute when we activate this plugin.
| | 05:41 | So, bdetector_activate.
| | 05:45 | So that's all we need.
| | 05:47 | This is our plugin, and this
will essentially create the database.
| | 05:50 | Let's go ahead and go into our WordPress
admin, go to the Plugins page, find our
| | 05:57 | Browser Detector Plugin, which is
right here, and go ahead and activate it.
| | 06:02 | When it was activated, it should
have created this table in the database.
| | 06:06 | So let's go ahead and look
at our MAMP installation.
| | 06:10 | Let's go into phpMyAdmin, look at wp
_test, and you can see we have this
| | 06:21 | table wp_bdetector.
| | 06:24 | When I click on it, you can see it
created an id, a hit_date, and a user_agent.
| | 06:30 | So, to create your own database in
WordPress, it's a good idea to use that
| | 06:34 | dbDelta class in upgrade.php.
| | 06:37 | This is going to upgrade the table
using SQL query, and typically we're going to
| | 06:41 | add this as an activation hook.
| | 06:43 | And now you've got your own database
table, so you can start storing things
| | 06:46 | with your plugins.
| | 06:47 | Creating your own database
table in WordPress is a fairly
| | 06:50 | straightforward process.
| | 06:51 | You need to create your SQL that's
going to create the table using the
| | 06:55 | CREATE TABLE statement.
| | 06:57 | Make sure in your table_name, you use
the wpdb prefix property to get the prefix
| | 07:03 | that the user is using for
their WordPress installation.
| | 07:06 | When your statement is ready, simply
call the dbDelta function that you can find
| | 07:10 | in the upgrade.php class.
| | 07:12 | Now let's go on and look how we
can insert and update data into our
| | 07:16 | database table.
| | Collapse this transcript |
| Inserting data| 00:00 | If you've created your own table in
WordPress, you can insert and update data
| | 00:04 | from it using the same wp_db
class we used to get data out.
| | 00:08 | We'll look at how to use the functions
to do that, and I also want to discuss
| | 00:11 | how to protect your
application from SQL injection attacks.
| | 00:15 | A quick note: just because you can
insert an update directly to the WordPress
| | 00:19 | database, it's a better practice to use
the functions that are there to do this.
| | 00:23 | That way if the table names ever change
in future versions, your code won't break.
| | 00:27 | So this is our plugin that
we've created to detect browsers.
| | 00:31 | Currently, we have a
database that's been created.
| | 00:33 | Now we can use this plugin
functionality to actually go in and update the
| | 00:39 | database whenever a new
user comes to the web site.
| | 00:42 | So let's create a statement that's going
to insert data into our database table.
| | 00:47 | So the first step is we are going to
create a function, and this is really going
| | 00:51 | to be the hook that's going to be called.
| | 00:54 | We are going to set it to the wp_footer hook.
| | 00:57 | That action is used when
the footer is generated,
| | 01:00 | so it's a good time to essentially
insert into our database that a new user has
| | 01:04 | come to the web site. So I am going to
call the function bdetector_insert_useragent.
| | 01:11 | Again, I am going to use the
wpdb class to access my data.
| | 01:15 | So I am going to declare it in the global scope.
| | 01:18 | So, now I have access to it.
| | 01:20 | I am going to create my table name and
set it equal to wpdb->prefix, and I am
| | 01:28 | going to add on bdetector.
| | 01:30 | The next step is to use the insert
function of the wpdb class to insert the
| | 01:35 | data into the database.
| | 01:37 | This is what it looks like: wpdb insert.
| | 01:42 | You pass the table_name that you want
to insert into, and then you create an
| | 01:47 | array, and in that array are going
to be all the fields that you want to
| | 01:51 | enter and their values.
| | 01:53 | So it's going to be an associative array.
| | 01:55 | So it looks like this, array.
| | 01:57 | We are going to enter the user_
agent, and I didn't just make that up;
| | 02:03 | this is this field here that I
created earlier in my database.
| | 02:05 | I am going to set the value to the
$_SERVER string--this is a global PHP
| | 02:13 | variable--and I'm going
to get the HTTP_USER_AGENT.
| | 02:19 | There are number of things in that
server scope, and most of these are obtained
| | 02:23 | from browser header.
| | 02:24 | So this should then insert
that data into the database.
| | 02:28 | The last thing I need to do is simply
register this in a wp_footer action.
| | 02:33 | So I'll call the add_action function,
pass wp_footer, and I am going to call
| | 02:40 | bdetector_insert_useragent.
| | 02:45 | The next time I visit this site, this
data should get inserted into the table.
| | 02:50 | So let's go ahead and visit
our site and see what happens.
| | 02:53 | So, I am going to open our site from the
WordPress admin by clicking on the title.
| | 03:00 | That should have loaded it.
| | 03:02 | You can see it loaded.
| | 03:03 | So hopefully it should be
entered into the database.
| | 03:06 | I can go in to my MAMP screen.
| | 03:09 | This is my table from my database.
| | 03:11 | If I click on the Browse tab, it should
make a selection and get data out, and
| | 03:16 | you can see indeed it did.
| | 03:18 | It gave it an id of 1, it inserted the
hit_date because I told it to default to
| | 03:23 | the current date and time when the data
was entered, and it input my user_agent.
| | 03:27 | So you can see I am using this Mozilla
/5.0, which is Firefox browser, and it
| | 03:33 | tells me my operating system, and
there's a bunch of other information we can
| | 03:36 | glean from this at a later date
when we build the reporting tools.
| | 03:40 | One other note: when you do insert like
this, you can always access the data that
| | 03:45 | was inserted by referring to
the insert_id property of wpdb.
| | 03:52 | So if you need to get that for any reason,
you can access it using this methodology.
| | 03:57 | One other thing to go over quickly is
in order to secure things, you want to
| | 04:02 | make sure that you
specify the types that come in.
| | 04:05 | In this example, we're getting
something from a server scope, but if we are
| | 04:09 | getting something that's user entered,
it's possible that they can do what's
| | 04:12 | called the SQL injection attack.
| | 04:14 | What this will do is they essentially
append SQL on here that can do deleterious
| | 04:19 | things to your database.
| | 04:21 | It's not something to be looking forward
to, and the way you can get around this
| | 04:26 | is this insert method actually allows
you to pass what types of data you're
| | 04:30 | entering as variables.
| | 04:32 | So that way anything that comes it
will verify that the date you entered is
| | 04:37 | indeed the right type.
| | 04:38 | So what you do is you add another
argument after this and you specify for the
| | 04:43 | array what the different data types are,
and they're always going to start with
| | 04:47 | the percent sign, and then you can do
S for a string, D for decimal, and F for a
| | 04:52 | Float, so I would add an array.
| | 04:54 | Since I am just inserting the single string, I
am just going to verify that this is a string.
| | 04:58 | That will enforce this data type and make
sure that no one entered any SQL into here.
| | 05:06 | So if I were to run it again, it
would work the same way, and you'd see it
| | 05:12 | enters another bit of data, but in that
instance it verified that it was that type of data.
| | 05:17 | There is also a prepare method that you
can use if you're doing a select statement.
| | 05:22 | It's not necessary to insert an
update because they're safe; however, if
| | 05:26 | you're running a select query with
dynamic variables, it's good to use the
| | 05:30 | prepare statement.
| | 05:31 | It works in basically the same way,
only you write your SQL and afterwards,
| | 05:36 | you append an array of the values you need.
| | 05:39 | There is further information if you
look in the function reference for wpdb.
| | 05:43 | You should be able to find the
information about that function.
| | 05:47 | So, the WordPress wpdb has insert and
update methods that essentially allow us to
| | 05:52 | enter data into the database safely and easily.
| | 05:55 | We can also use the prepare method
to clean other dynamic SQL statements.
| | 06:00 | The update method works basically the same way.
| | 06:02 | The difference is there's a third
argument to the update method that will take
| | 06:06 | the where clause information--
essentially the ID and value that you want to use
| | 06:10 | to update--and then your data
types will be in the fourth argument.
| | 06:14 | We'll look at the prepare statement,
and we'll talk more about SQL injection
| | 06:18 | hacks when we get into
the Security video later on.
| | 06:21 | So the WordPress database class comes
with some special functions--insert and
| | 06:26 | update--to edit the data in your database.
| | 06:29 | This can be extremely helpful,
and it can also keep you secure from
| | 06:32 | SQL injection hacks.
| | Collapse this transcript |
|
|
7. The Loop, Posts, and PagesIntroducing the Loop| 00:01 | At some point when you are working
with WordPress, you're going to come to a
| | 00:03 | point where you want to work with the posts.
| | 00:06 | This is, after all, blog
software, and post of blogs are all about.
| | 00:10 | WordPress has a special
construct to hold this data.
| | 00:13 | It's called the loop.
| | 00:14 | It's used to hold page data as well.
| | 00:16 | In the video, we are going to
discuss this key piece of the
| | 00:18 | WordPress architecture.
| | 00:20 | I've created a simple widget here
that's going to be used on the front-end.
| | 00:24 | Note, I've use the old widget methodology.
| | 00:27 | This way has been deprecated, and we
looked at the new widget API, but it's
| | 00:31 | kind of good to see how it works, in
case you see this in some other plugin.
| | 00:34 | What I am going to do is I am going to
loop through the loop, and I am going
| | 00:38 | to output information.
| | 00:39 | So, by default, the loop is going to hold
whatever data is being used on that page.
| | 00:45 | On the front page, it's going to have however
many post the user specified. The default is 10.
| | 00:50 | It's going to start with sticky posts
at the top, ones that have been marked
| | 00:53 | as sticky, and then it's going to go through
in descending order of when they were entered.
| | 00:58 | On other pages, it's going to differ.
| | 01:00 | If you go to a custom page, for example,
the loop will just be populated with
| | 01:04 | the data from that page.
| | 01:06 | If you go to a specific post page, it
will be populated with just that post.
| | 01:11 | So let's go ahead and output this widget.
| | 01:12 | This widget is essentially going
to show us what's in the loop for
| | 01:15 | each particular page.
| | 01:17 | The way you loop through it is you
actually don't access anything called
| | 01:21 | the loop or anything.
| | 01:22 | There's a special function called have_
posts that we can use to loop through it.
| | 01:28 | So the first time you use it;
| | 01:30 | it's always going to go out
and get the next available post.
| | 01:33 | If there are no posts at all in the
loop, then it will return nothing.
| | 01:37 | So what we can do is we can use this
in an if statement, and say if have posts
| | 01:44 | and then do some
particular form of code execution.
| | 01:47 | So if there are no posts, after this
it will stop, and we'll be done.
| | 01:51 | However, if there are any posts, we can
use the while loop and basically say as
| | 01:57 | long as there's another post in
here, go ahead and loop through it.
| | 02:01 | What we are going to do then is we are
going to access the posts by calling the
| | 02:05 | special function, the_post.
| | 02:09 | That will queue up the post and populate
a number of template tags with post data.
| | 02:15 | If you remember template tags, these are
these functions that we can use to access data.
| | 02:20 | They're built into WordPress.
| | 02:21 | A lot of these work with data
that's in the current value of the loop.
| | 02:26 | For example, this comment data is
going to come from comments that are in the
| | 02:31 | loop, the_content is going to come from
existing content for the current item in
| | 02:36 | the loop, the_title--same thing.
| | 02:39 | So we can use these template tags
to access data inside of the loop.
| | 02:43 | So in our function here, we have our
if statement and our while statement
| | 02:47 | looping through the_post.
| | 02:49 | So now we can output what's inside of the post.
| | 02:52 | So we are going to create a div tag for
each entry, and inside of this div, we are
| | 03:00 | going to have a link--a href--and the
link is going to refer to the permalink for
| | 03:06 | the post, and the way we access that is using a
template tag--echo the_permalink. There is our link.
| | 03:17 | We'll set the title property of our
href to the title of the post, and again,
| | 03:23 | we use a template tag.
| | 03:28 | We'll set the same value in between the
open and closing a. So, php echo the_title.
| | 03:40 | The last thing we are going to do is
we are going to output however many
| | 03:43 | comments are in this current post.
| | 03:45 | So we'll create our parentheses, and
then we'll put it in here using another
| | 03:51 | function call comments_number.
| | 03:58 | The last thing we need to do is
close the loops that we have going on.
| | 04:03 | So after this final div tag, we'll say
endwhile, which will end our loop, and endif,
| | 04:13 | which will end our if statement.
| | 04:16 | So this is our basic loop that will go through
the loop for whatever is on the current page.
| | 04:21 | So, let's go ahead and go
into the WordPress admin.
| | 04:23 | We are going to look for
our plugin called top posts.
| | 04:27 | We are going to activate it.
| | 04:29 | This will register the widget.
| | 04:31 | So now we need to go into the Widgets
page, look for our Top Posts widget, here
| | 04:36 | it is, and drag it into our web site.
| | 04:41 | If we go down to the front of our web site, we
should see our plugin in action. Indeed, here it is.
| | 04:48 | You can see Posts on this page, our
Hello world, and there are 3 comments.
| | 04:53 | Note that comments number doesn't
just output the number, but it actually
| | 04:56 | outputs the word 'comments' as well.
| | 04:58 | So it's meant for visual display.
| | 04:59 | So, let's go back in,
and let's add another post.
| | 05:04 | If we go to the dashboard, we
have this QuickPress plugin.
| | 05:08 | We can use this to quickly add a post.
| | 05:10 | We'll just call this "Update for Today,"
"More sunny weather in Ventura," Publish.
| | 05:23 | So, now it's been published.
| | 05:24 | If we reload, you can see it's been updated.
| | 05:27 | It's been moved to the top of the list,
because by default it's in descending
| | 05:30 | order, and you can see down in
our output, it does the same.
| | 05:35 | If I were to go into one of these,
I would also see only that item.
| | 05:40 | Notice the other one disappeared,
because on this particular page, the loop was
| | 05:44 | only populated with that data.
| | 05:46 | It's true for pages.
| | 05:48 | The page information is stored just like
a post is, inside of the loop, so you can
| | 05:53 | see About gets listed for the loop on this page.
| | 05:55 | If you ever want to start over in
your loop, if for some reason you need to
| | 05:59 | do multiple loops, you can use a function
called rewind posts to go back to the beginning.
| | 06:05 | So the WordPress loop offers
information for WordPress developers to access the
| | 06:09 | posts and the pages inside of WordPress.
| | 06:13 | We can use this have_posts method to
iterate through them, the_post to get it,
| | 06:17 | and then any number of template tags
to access all the data inside of it.
| | Collapse this transcript |
| Using WP_Query()| 00:01 | As we've learned, every page
in WordPress has its own loop.
| | 00:04 | This contains the data relevant to that page.
| | 00:07 | At some point, we might want to
query our own loop and essentially access
| | 00:11 | the same kind of post and page data, but not
have it be whatever is on the current page.
| | 00:17 | There's a special class built into
WordPress called WP_Query that we can use for this.
| | 00:22 | If you remember, we've built this top_
posts widget, which will output information
| | 00:26 | about each post that's on the current page.
| | 00:29 | So as you can see, on the default page,
it's outputting the two items. But if
| | 00:34 | I go to the About page, it outputs the
About page itself, which is stored in that loop.
| | 00:40 | What it's doing is it's calling these
methods, have_posts and the_post, on the
| | 00:45 | special default WP_Query
class that's built into WordPress.
| | 00:50 | This class gets its data in the header,
and it gets it depending on the file
| | 00:55 | you're in and any URL variables
that might have been passed to it.
| | 00:59 | If we want to create our own object,
we can essentially create a variable and
| | 01:06 | set it equal to the WP_Query class.
| | 01:13 | This class is made to store this data,
and it's much cleaner and easier and
| | 01:18 | better to use than
accessing the database directly.
| | 01:22 | So what we do to populate it is we
simply call the get_posts method of
| | 01:29 | that object.
| | 01:32 | This will go out and get posts.
| | 01:34 | You can apply filters if you want to,
and we'll talk about that later.
| | 01:37 | For now, it's just going to populate it
with the default post data, essentially
| | 01:41 | what would display on the first page:
| | 01:43 | any sticky posts and then
other posts in descending order.
| | 01:49 | To output in our loop, we now need to
access the post data from this query.
| | 01:54 | So just change it so you are
calling the same methods of the query.
| | 02:00 | So now it's getting data from our posts.
| | 02:11 | The post itself will always populate
the default post, and that is what's
| | 02:15 | accessible by these template tags.
| | 02:17 | So you don't have to do any
changes to the template tags;
| | 02:20 | just make sure you prefix your have_posts
and the_post with your specific post object.
| | 02:26 | So let's go back to our site, and
let's go ahead and refresh the homepage.
| | 02:32 | You'll see I have "Update
for Today" and "Hello world!"
| | 02:35 | These are the default posts, which is
what I'd expect because those are the post
| | 02:38 | available on the main page.
| | 02:40 | However, if I go into the About page,
you'll see that I still have the same
| | 02:44 | posts, because it's now getting
these posts from our get_posts call.
| | 02:50 | So, WordPress offers us the ability to
create our own customized post and page
| | 02:55 | data by using this WP_Query class.
| | 02:59 | We can then call the get_posts method to
populate it, and we loop through it just
| | 03:03 | like we did with the main loop, using
have_posts and ultimately setting the post
| | 03:07 | information to the current
page by calling the_post.
| | Collapse this transcript |
| Custom filtering and sticky posts| 00:01 | Calling the get_post method of the
WP_Query class will essentially just get you
| | 00:04 | the same data that's on
the main page of your blog.
| | 00:07 | However, there's a lot more
customization you can do, in terms of applying
| | 00:11 | filters to the data you get back.
| | 00:13 | You can filter by category or title or author.
| | 00:16 | You can get sticky posts or a specific
page or any number of other queries.
| | 00:21 | This can be done on a default loop using
a special method called query_post, and
| | 00:27 | this is a function that's built into WordPress.
| | 00:30 | The same parameters are used when we
call on our own WP_Query class, so if you
| | 00:35 | look in the Codex you can see
the parameters that it will take.
| | 00:38 | If you are going to use the query method,
you can call it on your object instead
| | 00:43 | of get_post, and you can pass to it a
special query parsing object, and inside of
| | 00:50 | it, it is going to have what looks like
a URL parameter, and that URL parameter
| | 00:54 | will have the data you want to filter by.
| | 00:57 | So you start with an ampersand and you
say posts_per_page, which is one option.
| | 01:03 | And again, these options are listed on
the query post, referenced in the Codex.
| | 01:07 | So a posts_per_page we will set equal
to five, and then separate each one with
| | 01:13 | an ampersand, and we'll say we want to
orderby=comment_count, and then we want
| | 01:23 | to order in descending order.
| | 01:27 | So before I save it, let's
take a look at our original query.
| | 01:31 | So you can see it's in the
order of what comes first.
| | 01:36 | So I have this "Restaurant View,"
"Update Today," and "Hello World!"
| | 01:39 | However, none of these have comments,
and really, if I want to make this about
| | 01:43 | displaying comments, the ones that are
the most active, then I am going to want
| | 01:47 | to order by comments.
| | 01:49 | So that's what I added into here by
ordering it in descending order by comment count.
| | 01:54 | So when I save this and go back and
refresh it, you will see that Hello World!
| | 01:58 | comes up top because this
one is the most commented on.
| | 02:02 | So we can actually change the title of this.
| | 02:05 | Instead of saying Posts on page, we
can change this to say Top Posts, because
| | 02:11 | now it's accurately reflecting the top posts.
| | 02:13 | An even easier way is instead of
writing your options in the query method, when
| | 02:19 | you create your WP_Query object,
you can pass them in as an array of
| | 02:23 | associative objects.
| | 02:24 | So we will say array and we'll say,
posts_per_page=5, then I like to keep them
| | 02:36 | lined up in this way, and we will say
'orderby' => 'comment_count', and the
| | 02:48 | order is descending.
| | 02:52 | So now we don't have to
call the query method at all.
| | 02:55 | When I initialize this WP_Query object,
it will actually populate our query
| | 03:00 | based on these parameters.
| | 03:02 | When I refresh, it doesn't change,
although our title changed because we change
| | 03:06 | that. But the order is the same
because it's applying that filter.
| | 03:10 | The other option is sticky posts.
| | 03:13 | Sometimes you want to mark a post as
sticky, and a lot of theme supports sticky
| | 03:17 | posts to highlight them as if they
are headlines, or things like that.
| | 03:21 | They allow you to have some
posts that are treated specially.
| | 03:25 | In order to make them sticky, the
easiest way is to go into the main Posts page,
| | 03:29 | in the Quick Edit, there's an
option to make the post sticky.
| | 03:34 | When you update it, you'll see on your
post that this is a sticky one, so you
| | 03:38 | can quickly review.
| | 03:40 | If I want to filter by it, I
simply add another parameter.
| | 03:43 | There is a special parameter called
'post__in' which says I want to get all the
| | 03:52 | posts that are in a specific list.
| | 03:54 | We are going to get a list of IDs using
the sticky posts option, and it's stored
| | 03:59 | in the option database.
| | 04:00 | So we use the get_option method to call
on it, and the name of it is sticky_posts.
| | 04:08 | We will now save it.
| | 04:09 | It will now only report
those items that are sticky.
| | 04:15 | So when we see it, you can
see I now only get "Hello World!"
| | 04:19 | because that was the only sticky one that I had.
| | 04:21 | So as you can see, the WP_Query class gives us
a lot of options for filtering our loop data.
| | 04:28 | We can control how many posts we are
going to get, we can control the order,
| | 04:32 | and we can filter by category, author,
title, or sticky posts, as well as a
| | 04:36 | number of other options.
| | 04:38 | The way that we set this up is we
can either pass our query data into the
| | 04:41 | WP_Query constructor or into the query method.
| | 04:45 | We can pass them as an associative
array of elements, or we can also pass them
| | 04:50 | as a URL variable string.
| | 04:52 | However we do it, this provides us
with a lot of flexibility in how we
| | 04:55 | output our posts.
| | Collapse this transcript |
| Using jQuery and AJAX for posts and pages| 00:01 | With the advent of AJAX--Asynchronous
JavaScript and XML--and the numerous
| | 00:05 | JavaScript libraries that are out there,
like JQuery, that make it easy to use,
| | 00:09 | web sites are quickly losing that
slow request and response mechanism, and
| | 00:13 | becoming more interactive and faster.
| | 00:16 | WordPress utilizes these technologies.
| | 00:18 | So as WordPress developers, we can
use this in our client-side software.
| | 00:22 | I'm going to take a look at
our posts widget that we had.
| | 00:26 | What I want to do is add some preview
possibilities, so that when the user
| | 00:31 | mouses over one of the items, they'll
then be able to see a preview of what's in
| | 00:36 | that particular post.
| | 00:37 | There are a couple of steps to
making AJAX work on the front-end of
| | 00:42 | WordPress databases.
| | 00:43 | The first step is we need to write a function.
| | 00:47 | This function is going to be
registered with the AJAX handler.
| | 00:51 | So what this function should do is it
should essentially get some post data, and
| | 00:56 | then it should output something
that can be used by the JQuery request.
| | 01:01 | So we're going to write a function tpp_
posts_comments_return, and in here, we're
| | 01:09 | going to set the variable post_id.
| | 01:12 | This is going to store the ID.
| | 01:14 | First, we're going to look to see if
the post has a value called post_id.
| | 01:24 | So if this is set, then we can go ahead
and set it equal to that value. Make sure to
| | 01:30 | wrap that in quotation.
| | 01:35 | If it's not set, then we'll set it to zero.
| | 01:37 | Since our ID starts at one, we'll know if
it's set to zero, that it's not a valid post_id.
| | 01:42 | So then we can say if $post_id is
greater than zero, then let's go ahead and get
| | 01:49 | the post and return some information.
| | 01:51 | So I'm going to create a variable called
post and set it equal to the result of
| | 01:56 | calling this get_post function.
| | 01:58 | The get_post function takes a post_id
and will return in the post data for
| | 02:04 | the ID that matches.
| | 02:06 | I then want to write out some HTML, and
it's going to be pretty straightforward.
| | 02:11 | I'm going to give it an ID of post, a
div tag, and then I'm just going to output
| | 02:15 | the actual content of that post.
| | 02:17 | The way I do that is I just echo, and
then I use my post variable, and I output
| | 02:22 | a property inside of it called post_content.
| | 02:27 | If you look up the get_post
function in the Codex, you'll find the
| | 02:30 | definition for all of this.
| | 02:32 | So let's go ahead and open our PHP up
again and make sure, after this if
| | 02:38 | statement, to call the die method.
| | 02:41 | This is going to stop processing of
the PHP and make sure that the only thing
| | 02:45 | that gets returned when they
call this action is our HTML.
| | 02:49 | So once that function is set up, you then
need to register it with the AJAX engine.
| | 02:53 | So we use an action for that.
| | 02:56 | The name of the action is wp_ajax_nopriv,
which stands for no privileges, which
| | 03:04 | allows you to access the same AJAX
script that we accessed from the back end,
| | 03:08 | only it opens it up, so that things on the
front end of the web site can access it as well.
| | 03:13 | Then we're going to give it an action name.
| | 03:15 | We're going to call it tpp_comments.
| | 03:18 | The action is then going to call
the function that we just wrote.
| | 03:28 | So once that's all set up, we're going
to need to go in, and we're going to need
| | 03:31 | to create a JavaScript file.
| | 03:34 | If you look here, you can see I've
moved the top post into its own folder,
| | 03:37 | because I'm going to create a new file.
| | 03:39 | So it's better for organization.
| | 03:42 | If you already had a top post PHP in
the root of the plugins, make sure that
| | 03:46 | you deactivate it before you create
this new directory and move it in, or it
| | 03:49 | will automatically become deactivated.
| | 03:51 | You're going to need to reactivate
a new one once it's in this folder.
| | 03:56 | Go ahead and right-click on that
folder then and go to New > File.
| | 04:00 | We're going to create a
JavaScript file called top_posts.js.
| | 04:06 | Now before we write this script, we
need to make sure to set up our client here
| | 04:12 | with some identifying information.
| | 04:15 | The reason is with JQuery we have
to access specific items, and in order to
| | 04:19 | do that they have to be in
classes or have IDs to them.
| | 04:22 | So we're going to go ahead and say
the class for this is div is tpp_posts.
| | 04:27 | We're going to set an ID for our href, and
we're going to set it equal to echo the_id.
| | 04:38 | It's a template tag that's for
outputting the ID of the current post.
| | 04:42 | We're also going to assign a class for
this a. We're going to call it comment_link.
| | 04:51 | So those are all defined.
| | 04:53 | Now we can go in and write our JQuery call.
| | 04:57 | This may look a little strange if
you've never worked with JQuery before; it
| | 05:00 | takes a little getting used to.
| | 05:02 | If you've gone through our other unit
on working with JQuery in the admin, it
| | 05:06 | may be a bit helpful.
| | 05:08 | So basically what we're going to do is
we're going to set up an event handler.
| | 05:11 | As soon as JQuery is ready,
we're going to call a function.
| | 05:17 | We're passing the Dollar sign, so that we
can access the shorthand notation that
| | 05:22 | we use for JavaScript.
| | 05:25 | So what I want to do first is I'm going
to set a mouseover event for every div
| | 05:30 | in the class of tpp_posts.
| | 05:34 | So I specify div.tpp_posts.
| | 05:37 | That will get those.
| | 05:39 | Then we can set mouseover, and then this
function will execute, and that occurs.
| | 05:50 | So the first thing I'm going to do is
I'm going to create a variable called div,
| | 05:54 | and just set it equal to the div
who's firing the mouseover event.
| | 06:01 | Then I'm going to call a post.
| | 06:02 | So I'm going to use a Dollar sign to refer
to JQuery, and call post, and then I'm
| | 06:07 | going to go to wp-admin/admin-
ajax.php, which is that one file.
| | 06:14 | Now there are other ways to do this
dynamically, but for the sake of simplicity,
| | 06:17 | I'm just going to do this right here.
| | 06:20 | Another thing to note about
writing this JavaScript is that it's
| | 06:23 | very browser-dependent.
| | 06:25 | So we've tested this with the
latest version of Firefox, 3.6.8.
| | 06:30 | You want to make sure that you're
using that, or you may have issues with it.
| | 06:34 | Action is going to be tpp_comments.
| | 06:39 | So what I'm doing now is I'm setting up
variables that I want to pass in my AJAX request.
| | 06:45 | The action is going to match
whatever I registered after the nopriv.
| | 06:49 | Then I'm going to pass the post_id.
| | 06:51 | I'm going to get this from current div,
and I'm going to look inside of this
| | 06:59 | current object for every a object,
which there will be one in each one, and I'm
| | 07:04 | going to grab the id attribute.
| | 07:07 | If you remember, in that a, I set the ID
equal to the ID of the post, so that's
| | 07:13 | going to return my post_id.
| | 07:16 | So that's the end of my post
object, the data that I want to pass.
| | 07:20 | Now I need to specify what I want
to happen when the result comes back.
| | 07:24 | So I'm going to create a function that
takes an argument data, which will be the
| | 07:27 | result data, and what I'm going to do
is say div, which is my div tag, .append,
| | 07:34 | and then I'm just going to append my data.
| | 07:39 | So I can now close that entirely.
| | 07:44 | Now I've created my post.
| | 07:45 | I want to make sure to return false
for that function, and then I'm going to
| | 07:52 | close this entire section.
| | 07:57 | I'm going to add one other event for
div.tpp_posts, those same div tags.
| | 08:06 | I'm going to add a mouseout event.
| | 08:10 | What this is going to do is this is
essentially just going to erase the data
| | 08:15 | once it's been displayed.
| | 08:16 | So we can just say #post, so that's
going to refer to everything with the
| | 08:21 | post_id, and if you look at what gets
returned, they all have an ID of post.
| | 08:26 | So whichever has id of post, I'm
going to go ahead and remove it.
| | 08:31 | Again, there are always multiple
ways to do these sorts of things.
| | 08:34 | I'm just trying to give you a
simple idea of how to do this.
| | 08:36 | So let's go ahead and save it.
| | 08:39 | Take a quick glance to make
sure that everything is there.
| | 08:41 | I noticed seeing it that I didn't put my
ID in the attribute, but everything else--
| | 08:46 | oh, this should also be a Dollar sign.
| | 08:47 | I think everything else looks pretty good.
| | 08:54 | So let's go ahead and go
back into our client page.
| | 08:57 | Let's now set up our scripts.
| | 09:00 | So if you remember from the AJAX on the
administrative side, you need to create
| | 09:05 | a function that's going to
call the wp_enqueue_script method.
| | 09:09 | This essentially embeds scripts into our file.
| | 09:12 | So we're going to call
get_scripts, so this is our function.
| | 09:17 | I'm going to call enqueue_script, call
this one tpp_posts, and then we have this
| | 09:26 | sort of strange, long string here.
| | 09:29 | Basically, what we're going to do is
point out our current JavaScript using
| | 09:33 | path_join and using the WP_PLUGIN_URL,
the basename function, the directory name
| | 09:42 | function, and the current file. And then
we're going to specify that we want to
| | 09:52 | look into top_posts.js,
right, which is our JavaScript.
| | 09:59 | So this is just a dynamic way of
appending our JavaScript information, and then we
| | 10:03 | also want to specify that we want to
get a JQuery library. So that's all set.
| | 10:12 | So the last thing we do is we add an
action for the wp_print_scripts, and this
| | 10:24 | is what gets executed when we
load scripts into the front side.
| | 10:29 | So we'll say tpp_posts_get_scripts,
which is the function we just wrote.
| | 10:35 | So that will just make sure that our
script gets loaded up every time our page
| | 10:39 | loads on the front end.
| | 10:40 | So now let's go ahead and refresh this page.
| | 10:44 | When I mouse over one of these, I
should now see the post underneath it, but it
| | 10:49 | doesn't seem to appear.
| | 10:50 | If I look down in my firebug, I can
see that it has gone out and made a
| | 10:55 | request, and it looks like
everything is set up appropriately, only it's
| | 10:59 | getting a zero back.
| | 11:00 | This might be because I'm currently
also logged in as admin, and it's trying to
| | 11:04 | do some kind of no privilege.
| | 11:06 | So let's go ahead and log out, so
that we look more like an anonymous user.
| | 11:11 | Now let's try mousing over again.
| | 11:14 | You can see it does appear.
| | 11:15 | So when I mouse over, I get the post,
and when I mouse out, it goes away, and
| | 11:20 | same with this one.
| | 11:23 | So as you can see, AJAX and JQuery
work together to make a really fast and
| | 11:28 | interactive site, and you can use it
with the loop data--or with any data really
| | 11:32 | inside of WordPress environment.
| | 11:34 | All you need to do is set up a
function that's going to return some data, and
| | 11:38 | you're going to use that admin AJAX
PHP, just like we did in the admin.
| | 11:43 | Make sure to register that function
then as an action, and then go ahead and
| | 11:47 | write your JQuery and register that
script using the wp_enqueue scripts.
| | 11:51 | All in all, AJAX and JQuery can make
for a really interactive WordPress web site.
| | Collapse this transcript |
|
|
8. The WordPress Plugin LifecycleRegistering and promoting plugins| 00:00 | So you've done it.
| | 00:01 | You've built the coolest plugin that
enables everyone to do the coolest things
| | 00:05 | imaginable in their WordPress
installations. So, now what?
| | 00:09 | Now it's time to take it on the road.
| | 00:11 | You're going to have to get it
submitted at WordPress.org and get it out there.
| | 00:15 | All the plugins that you look
through in the admin are located at the
| | 00:19 | WordPress.org web site.
| | 00:21 | In order to register in there, you can
go to the About page for the plugins.
| | 00:26 | There's information located at
WordPress.org/extend/plugins/about.
| | 00:33 | It will tell you information
about what you need to do to host your
| | 00:36 | plugins with WordPress.org.
| | 00:38 | There are a few requirements that you
have in order to upload your plugin here.
| | 00:43 | It has to be GNU-compatible.
| | 00:45 | This is a specific licensing
agreement that basically says it is okay for
| | 00:48 | the people to use it.
| | 00:50 | It has to be legal, so you can't
take your code from anywhere else.
| | 00:54 | You have to be able to use
subversion and submit it to their subversion
| | 00:57 | repository, and you can't have
external links built into your plugin, unless
| | 01:02 | you give the developers that use them or
the end users the ability to turn them off.
| | 01:06 | There is a form located at wordpress.org
/extend/plugins/add, and you can see it
| | 01:10 | will give you some
information and tell you how to do it.
| | 01:18 | You have to create an account, and
then you'll fill out a form, and you'll
| | 01:21 | be able to upload it.
| | 01:22 | One of the requirements for having
plugins at the WordPress.org site is
| | 01:27 | creating a readme.txt file.
| | 01:29 | There is a specific standard that they
use, and if you go to that About Plugins
| | 01:34 | page, there is a link to the
standard you can use to start with.
| | 01:38 | It basically just tells you some 'gotchas,'
has some answers and then a changed log.
| | 01:43 | It's a fairly straightforward process, but
make sure to include it, as it's required.
| | 01:47 | Once you've submitted it to the WordPress web
site, you can also submit it at other places.
| | 01:53 | There's a WP-Plugins.net and a
WP-Plugins.org that you can go to.
| | 01:59 | There are some other WordPress sites; pretty
much anywhere where they discuss WordPress,
| | 02:03 | you're welcome to let people know.
| | 02:04 | Bloggingpro.com is a good one.
| | 02:07 | Weblogtoolscollection.com is another.
| | 02:11 | In addition, the WordPress support forums
are open to people announcing new plugins.
| | 02:16 | So there you have it.
| | 02:18 | Once you're done with your plugin,
it's a fairly straightforward process to
| | 02:20 | submit it through the WordPress.org web site.
| | 02:23 | In addition, we recommend
promoting it to other places on the web.
| | Collapse this transcript |
| Creating an uninstall function| 00:00 | One of the potential problems with
open development environments like
| | 00:03 | WordPress is that after a period of
time of using plugins that have options
| | 00:08 | from in the database and new database
tables, and all this sort of thing, and
| | 00:12 | then deciding not to use them, it's
pretty easy to get some database bloat, and
| | 00:16 | have a lot of things hanging out there.
| | 00:18 | So it's a best practice, as plugin
developers, to create some sort of uninstall
| | 00:22 | script that removes these items that
are plugin uses when they're removed.
| | 00:26 | As of WordPress 2.7, we have
a couple of ways to do this.
| | 00:30 | One way is that we can register an
uninstall hook, which will essentially set up
| | 00:34 | a function that will be
executed by WordPress on uninstall.
| | 00:38 | The other way is to
create an uninstall.php file.
| | 00:41 | Let's go back to our CC comment plugin.
| | 00:44 | If you recall, it set up a specific
option called cccomm_cc_e-mail that we use
| | 00:51 | to save the e-mail that the user use.
| | 00:54 | So we want to get rid of this on uninstall.
| | 00:56 | So if you go into your admin, and you
go to the options.php page, you can see
| | 01:02 | there's a cccomm_cc_e-mail that's listed there.
| | 01:06 | So let's make sure that gets removed.
| | 01:08 | The way to do this is you first
create a function that is going to do the
| | 01:13 | removing when the uninstall occurs,
and to delete an option from the options
| | 01:18 | database, you simply say delete_option,
and you pass the name of the option--in
| | 01:23 | this case cccomm_cc_e-mail.
| | 01:29 | You then need to register this, so that
when it uninstalls, it will run this function.
| | 01:34 | So we use a special function
called register_uninstall_hook.
| | 01:38 | We're going to specify that it's
going to run something in this file, and
| | 01:43 | that the function is
going to be cccomm_uninstall.
| | 01:48 | So make sure before you do this
that you back up your CC comment.
| | 01:53 | So go into the plugins directory of
your WordPress installation, copy the
| | 01:59 | CC comment and put it somewhere--
wherever you like: on your desktop, or in
| | 02:04 | your Documents folder.
| | 02:06 | Just remember where you put it,
so you can use it when you go back.
| | 02:10 | So now let's go ahead and go
into our WordPress Administrator.
| | 02:13 | Let's go into the Plugins page, and
let's first deactivate our CC Comment plugin
| | 02:19 | and then go ahead and delete it.
| | 02:21 | It's going to give you a
confirmation, and you're going to say, "Hmm!
| | 02:23 | Do I want to really delete this?"
| | 02:25 | In this case, we do.
| | 02:27 | So it will have deleted all the files.
| | 02:30 | Let's go into the options.php file again.
| | 02:32 | You'll see now that your CC
comments CC e-mail has been deleted.
| | 02:39 | It used to be right about here.
| | 02:41 | So it did indeed work.
| | 02:43 | So let's go ahead and go back into
Eclipse, and you'll see it's giving you
| | 02:47 | information saying these
files are no longer there.
| | 02:50 | If you refresh this, you'll
see that they are indeed gone.
| | 02:55 | So let's restore from the
directory we left it in.
| | 02:57 | So let's go ahead and copy cc_comment.
| | 03:00 | Let's go back into our Plugin
directory and paste it again.
| | 03:07 | So now in Eclipse, we can
refresh, and we'll see it there.
| | 03:11 | You could also incidentally paste it
through this interface, but it's easy
| | 03:14 | enough to do it from
within Macintosh or Windows.
| | 03:17 | So let's go ahead and open this
up again, and let's try using the
| | 03:21 | uninstall.php file.
| | 03:24 | The difference is that in order for
this to execute, it actually does have to
| | 03:28 | run through the script.
| | 03:29 | There might be something you have
going on that you don't want to happen.
| | 03:33 | So the uninstall.php file
gives you a very clean uninstall.
| | 03:38 | So let's go ahead and erase this
uninstall and save it. And let's
| | 03:42 | right-click on the cc_comment folder and go to
New > PHP File, and we'll call it uninstall.php.
| | 03:51 | We can then paste in our delete_option.
| | 03:54 | There's one other thing you should do:
| | 03:57 | you should make sure that it's not
running this somehow from some other way,
| | 04:01 | because you wouldn't want it to
delete the option if the user didn't
| | 04:04 | actually want this to be deleted, and it's
possible somehow that this PHP file could run.
| | 04:09 | So the best way to do that is to check
for the definition of a specific variable.
| | 04:14 | So we'll say if not defined--
and when the uninstall occurs,
| | 04:18 | there is going to be this
constant WP_UNINSTALL_PLUGIN.
| | 04:24 | That's going to exist.
| | 04:26 | So if it doesn't exist, then we
can go ahead and just say, "Hey!
| | 04:30 | Stop it." Then we'll exit.
| | 04:32 | So that will then exit this file, and it
will stop executing right at that point.
| | 04:37 | However, on uninstall, this will be
defined, which means it'll go ahead and go
| | 04:42 | through and execute this line.
| | 04:44 | So if we go back into our Plugins page,
we're going to have to reactivate our
| | 04:50 | cc_comment plugin, and let's
make sure that that option got added.
| | 04:57 | It hasn't yet, because we haven't added it.
| | 04:59 | So let's go into the Settings > General,
and you can see there's our plugin,
| | 05:04 | enter an e-mail, and then
let's go back to the Options page.
| | 05:12 | We should see our e-mail appear here.
| | 05:14 | So now if we go into the uninstall, we
deactivate our plugin and we delete it,
| | 05:24 | then we can go back into the Options
page, and we should see that our CC
| | 05:32 | comments has been removed.
| | 05:34 | So since WordPress 2.7, we've had the ability
to create uninstall scripts for our plugins.
| | 05:40 | It's considered a best practice to
clean up any database tables or any options
| | 05:45 | that you've created in the WordPress database.
| | 05:47 | This is a best practice that keeps
our databases clean, and keeps people
| | 05:51 | using plugins.
| | Collapse this transcript |
| Backward compatibility issues| 00:01 | WordPress has been through many iterations.
| | 00:03 | There have been a number of different versions.
| | 00:05 | Interestingly enough, they all
have code names of jazz musicians,
| | 00:09 | like version 2.7 was code named John
Coltrane, and the most recent 3.0 was code
| | 00:13 | named Thelonious Monk.
| | 00:15 | What's great about having these
different versions is over the time WordPress
| | 00:20 | contributors are constantly making this a
better and better environment to work with.
| | 00:24 | However, because there are always
changes to this environment, it's really
| | 00:28 | important that we pay attention to the
API and do some certain practices that
| | 00:32 | make sure that we can
account for these different versions.
| | 00:35 | If you go to the WordPress web site,
there's a page dedicated specifically
| | 00:40 | to WordPress versions.
| | 00:42 | You can see when the versions were released,
and you can read change logs for each of them.
| | 00:46 | Note you can also see their code names.
| | 00:48 | There have been quite a number of
versions, and as they go from version to
| | 00:53 | version, they can change
the structure of the database.
| | 00:57 | They can change the functions that exist,
actions and hooks changes, and there
| | 01:02 | can be all kinds of
changes in the user interface.
| | 01:04 | So there are a few things that can go
wrong with our code because of this.
| | 01:09 | One is an old version of WordPress can
break when they install your plugin
| | 01:13 | because your plugin doesn't work.
| | 01:15 | Remember, every time you have a
plugin, it gets included in every request,
| | 01:19 | which means that code is
always going to execute.
| | 01:22 | So if there's a problem in that
code, it's literally going to hold
| | 01:25 | production and throw an error.
| | 01:27 | Another thing that can happen is a new
version of WordPress is installed, and it
| | 01:32 | breaks because your plugin
doesn't have compatibility.
| | 01:35 | It's extremely difficult, and a lot of
it is just keeping up with the API, but
| | 01:39 | there are a few things that you can know about.
| | 01:41 | One is there's a special page
dedicated to deprecated functions.
| | 01:45 | These are functions that no longer
exist or are no longer popularly used in
| | 01:50 | the WordPress system.
| | 01:52 | If you need to use them, they're
located in a number of different files, and
| | 01:56 | this page will tell you where to find them.
| | 01:58 | You can always include them in your
script, if it's necessary, and you don't want
| | 02:02 | to rewrite your code.
| | 02:03 | However, it's best to use whatever
they are replaced with, and usually there
| | 02:07 | will be some new solution.
| | 02:09 | Another way to get around this is to
use the function exists function, to test
| | 02:13 | and see if functions are there.
| | 02:15 | Let's go into our cc_comment
plugin that we worked on earlier.
| | 02:23 | One of the things that we did recently
was we registered an uninstall hook.
| | 02:27 | Well, this particular function
register_uninstall_hook didn't exist
| | 02:31 | until WordPress 2.7.
| | 02:33 | So if you try to run this in a previous
version, it would actually throw an error.
| | 02:38 | We don't have to worry about
adding actions and filters.
| | 02:40 | If you try and add an action to a
filter that doesn't exist in a version of
| | 02:44 | WordPress that they're running,
it'll basically just get ignored.
| | 02:48 | However, because this is a function
that's actually being executed, it
| | 02:52 | will throw an error.
| | 02:53 | So what you want to do in instances like
this, if you know you're going to run a
| | 02:57 | function that may not work with the
version of WordPress someone's using, you
| | 03:01 | simply wrap it in if function_exists,
and then just put the name of the function:
| | 03:08 | register_uninstall_hook.
| | 03:13 | If that exists then it will execute
whatever is in this code block, in which
| | 03:18 | case it'll run that function;
otherwise it won't happen, which means they
| | 03:22 | won't be able to uninstall prior to 2.7, but
that's okay, because it wouldn't have worked.
| | 03:28 | So long story short, keeping track
of WordPress versions becomes of utmost
| | 03:33 | importance as a plugin developer, so
you know what exists and what doesn't.
| | 03:37 | The good news is that the Codex
provide a lot of information about functions,
| | 03:41 | their availability, and what
version they do and don't exist in.
| | 03:45 | The bad news is it's all up to you.
| | Collapse this transcript |
|
|
9. Security and ExtensibilityUnderstanding security issues| 00:00 | WordPress--like any other web
software--is subject to attacks.
| | 00:04 | It's public and available, so it's
important to take into consideration and not
| | 00:08 | build plugins that will leave
anyone who uses them vulnerable.
| | 00:12 | The good thing about WordPress is that
there are a lot of security things that
| | 00:15 | are built into it already, so we
don't even have to worry about it.
| | 00:18 | However, there are still a few
things that we need to consider.
| | 00:21 | The main vulnerability in any site is
basically when we process dynamic data,
| | 00:26 | that is data that can be submitted from
the user either via a post or by a get,
| | 00:31 | so in a URL or in a form.
Security on the web site is primarily a
| | 00:36 | data sanitation issue.
| | 00:38 | SQL injection, which is basically
appending deleterious SQL code in a variable,
| | 00:45 | can be dangerous, and there
is a lot of ways around it.
| | 00:48 | Earlier we looked at the browser
detector plugin where we're inserting data in
| | 00:52 | the database, and you remember we use
the Insert method of the WTB object.
| | 00:57 | This is the safe insert because it
parameterizes the items that come in that
| | 01:02 | are dynamic. In this case, it was entering
this USER_AGENT and enforcing as a string.
| | 01:07 | What that will do is make sure that
this string will go in as a string and will
| | 01:12 | be entered into the database.
| | 01:14 | So that way if someone were to
append offensive SQL on it, this would
| | 01:18 | actually just put the SQL onto a database
instead of running it through the database engine.
| | 01:24 | One way to do it when you are not using
insert or update--which are both safe--is
| | 01:29 | to use this special prepare statement.
| | 01:31 | Usually, we are going to use this
on Select statements that do things
| | 01:34 | like filtered searches.
| | 01:36 | But in this case, I am just going to
show you how to do it instead of this
| | 01:39 | insert statement so you get an idea.
| | 01:41 | Basically, the first step that you need to
do is call the prepare method of the wpdb.
| | 01:51 | This will essentially set up a safe
query for you, and what you do is you
| | 01:56 | structure it like this.
| | 01:58 | You put your SQL, so INSERT INTO in
this case, and then we will use our
| | 02:03 | table_name, which we have
already setup right here.
| | 02:07 | So INSERT INTO table_name, and then
we'll say SET user_agent =, and then you
| | 02:16 | start appending on different values.
| | 02:19 | So in this instance, I am putting a
percent sign, the number one, and then I am
| | 02:24 | specifying the type of
data--in this case a string.
| | 02:27 | Now if I had other variables, I would
just say percent sign two and put the type
| | 02:32 | of data, either a float or a decimal number.
| | 02:35 | But since I am only using one,
that's all I need to do in this instance.
| | 02:39 | After that, in the order that they were
entered, you then put the values you want
| | 02:44 | to enter into the database.
| | 02:46 | So in this case, I am using _
SERVER, 'HTTP_USER_AGENT'.
| | 02:54 | If I had additional ones, I would add
them here separated by a comma, but in
| | 02:58 | this case, I only have one.
| | 03:01 | So this will essentially
create and prepare a script for me.
| | 03:05 | Then in the next line, I can go ahead--
looks like I forgot a concatenation here.
| | 03:10 | Notice how I get this red x
that tells me something is wrong.
| | 03:13 | So now I am going to say wpdb, and now I
can run the query, and I am just going to
| | 03:22 | pass the SQL that I generated
using the prepare statement.
| | 03:26 | So I want to first save that into a variable.
| | 03:28 | So I am going to it $safe_sql,
and now I can just pass this directly
| | 03:33 | into my query, and then now I have a safe query.
| | 03:41 | So this is considered a best practice.
| | 03:43 | In fact, if you ever are doing a
select statement that requires you to use
| | 03:47 | dynamic data, you pretty
much must use this methodology.
| | 03:52 | Another way that we can practice security is
by essentially stripping data that goes through.
| | 03:58 | There is a special kind of attack
that's called the cross site request
| | 04:02 | attack, and the way that we can get around
these is by cleansing the data as it comes through.
| | 04:08 | If you remember, we created a widget
before, called simple widget, that allowed an
| | 04:13 | admin user to enter information, a
body, and a title and submit it.
| | 04:17 | Well, since they are entering data and
submitting it, then we probably want to
| | 04:22 | clean it before it goes into the database.
| | 04:26 | We were using the widget API for this,
| | 04:28 | by extending the WP_Widget
class, and then implementing the widget
| | 04:33 | method, the form method, and we are using the
built-in update method to handle the updates.
| | 04:38 | Well, in this instance, I am going to
override the update method, because I want
| | 04:44 | to filter it before it goes into the database.
| | 04:47 | The update method takes two arguments:
new instance and old instance.
| | 04:55 | New instance will have the information
that the user entered, and old will have
| | 04:59 | what originally existed.
| | 05:01 | So the first thing I am going to do is
I am going to create a variable called
| | 05:04 | instance, and I am just going to
set it equal to the old_instance.
| | 05:08 | That way I am secure in that I
am not adding anything from what the
| | 05:12 | user entered in yet.
| | 05:14 | Now I can add what the user
would have entered bit by bit.
| | 05:18 | So first I am going to enter the title.
| | 05:20 | So instance title equals.
| | 05:26 | I am going to use the special PHP
function called strip_tags
| | 05:32 | which will just remove any HTML
tags, and I am going to strip it from
| | 05:36 | $new_instance title.
| | 05:41 | So now I'll have it clean, because there
is no reason why the user should put any
| | 05:47 | kind of tags into the title.
| | 05:49 | In the body, however, we
do want to allow some HTML.
| | 05:53 | Fortunately, WordPress has the special
method called wpkses that will allow you
| | 05:59 | to essentially filter out every
tag except for the ones you specify.
| | 06:04 | Now there is a very specific way
that you specify what's allowed.
| | 06:08 | I create a variable that is going to be
what's allowed, and I declare it as an array.
| | 06:16 | It's an associative array, so I create
a number of different tags so that are
| | 06:20 | available, and if there are any
attributes of those tags I want to allow, then I
| | 06:25 | specify those inside of the tag,
so this is what it looks like.
| | 06:29 | I am going to allow the a tag, and for
each of these items, I want to set an array.
| | 06:37 | If I didn't want to allow any
attributes of the a tag, then I would simply
| | 06:41 | declare an empty array, and that will be good.
| | 06:44 | However, I do want to allow the href
tag so that they can make a link and the
| | 06:49 | title tag so that it can be a
nice link that shows you the hover.
| | 06:53 | So what I do then is I put my
attributes inside of this array.
| | 07:01 | So I say href, and again, it gives you
the ability to granularly go in each one.
| | 07:06 | But for each of these I am just going
to declare an empty array, because there
| | 07:10 | won't be any child elements of them.
| | 07:13 | So, href is allowed and title is going
to be allowed, and again, just an empty
| | 07:21 | array. And that's it. And then I am going to
add the ability so the user can use br tags.
| | 07:30 | But since I am not going to allow any
child attributes or elements of that, then
| | 07:35 | I can go ahead and just declare an empty array.
| | 07:40 | Another one will be strong so they can
bold things, and again, no child elements
| | 07:47 | or attributes and emphasis, if
they want to italicize anything.
| | 07:58 | So this is essentially
specifying what would be allowed.
| | 08:02 | Now, in order to clean it up, I use my
instance variable, and I'll set the body
| | 08:12 | equal to, and then I'll call wp_kses.
And from the new instance, I'll get the
| | 08:21 | body--so that's the text to be scrubbed--
and then I specify what is allowed.
| | 08:30 | If you don't want to allow anything,
you can just pass an empty value into here.
| | 08:36 | And finally, part of this whole update
methodology is I am going to return the
| | 08:42 | new instance with the scrubbed properties.
| | 08:47 | So let's go ahead and
log in to our administrator.
| | 08:49 | Let's check the Plugins page and
make sure that this widget is activated--
| | 08:58 | It's the Simple Widget--and we can see it
is because it gives us the Deactivate option.
| | 09:04 | So let's look at the widgets, and let's
grab our simple widget, and let's drop
| | 09:09 | it into this sidebar.
| | 09:12 | So notice we have this
title, and we have the body.
| | 09:16 | Let's enter something like "Welcome on
Thursday," "It's a nice day." Hopefully you are
| | 09:29 | more creative than that.
| | 09:31 | Notice it's saved it fine, and it works
fine, and if I go to the front-end of the
| | 09:34 | web site, I'll be able to see this:
| | 09:40 | Welcome on Thursday.
| | 09:41 | If the user, however, tries to enter
some kind of tag in here, and submit it, it
| | 09:58 | removes the tag, right?
| | 10:00 | Because tags aren't allowed, so
that strip tags method does that.
| | 10:04 | If in the body they try and enter a tag
however, the a tag should be allowed,
| | 10:14 | as well the br tag; however, if they try
and do a div, that shouldn't be allowed.
| | 10:24 | So let's submit and see what happens.
| | 10:26 | So you can see I have my Google, my br,
but then notice my div tag was stripped out.
| | 10:34 | So this is a great way of keeping clean
code, and especially it can remove other things.
| | 10:40 | You can also use some other functions,
including Validate File, which will check
| | 10:44 | for valid files, escape js
which will escape JavaScript,
| | 10:49 | if you need to save it to
the database; its esc_js.
| | 10:53 | Escape URL, esc_url, and esc_
url_raw for database inserts.
| | 11:01 | You can also check to make sure certain
protocols that are accepted using this
| | 11:05 | kses, http, gopher--things like that.
| | 11:10 | So WordPress has a number of
methodologies built-in for cleaning data and trying
| | 11:13 | to ensure that only trusted and allowed
information goes into the database, and
| | 11:18 | is use in the WordPress environment.
| | Collapse this transcript |
| Internationalizing your plugin| 00:00 | WordPress is used around the world by
people who write blogs in Swedish and
| | 00:04 | French and Farsi, and as such, we want
to build plugins that are going to be
| | 00:10 | easy to internationalize.
| | 00:11 | Internationalization is sometimes called
localization or translation, or referred
| | 00:15 | to from the more technical term of i18n.
| | 00:18 | But whatever we want to call it,
WordPress has a system set up to deal with it.
| | 00:23 | The Codex has some good pages that will
explain more information, if you want to
| | 00:27 | learn more about how to localize.
| | 00:29 | The first one is Translating WordPress,
and it gives sort of an overview of what
| | 00:34 | localization is, what some of the
technical terms are, but it's more high-level.
| | 00:39 | Then there is an i18n for WordPress
developers web site, and this tells more of
| | 00:43 | a technical detailed way of how
WordPress implementation specifically works with
| | 00:49 | internationalization.
| | 00:51 | It's all based on PHP's gettext.
| | 00:54 | The main thing that we need to do as
developers is essentially mark areas in
| | 00:59 | the code where text is being output
that might need to be internationalized.
| | 01:04 | So anywhere you have text that's going
to be used somewhere that someone else
| | 01:09 | might want to put in the different language,
| | 01:11 | you want to wrap it in a special
function: underscore underscore.
| | 01:16 | So in this example, here is some
static text that I am outputting.
| | 01:20 | I want to go ahead and say
underscore underscore and just wrap it.
| | 01:25 | Now this doesn't look like much, and
frankly, it doesn't really do anything
| | 01:32 | unless you are implementing text
domains and what are called Portable Object
| | 01:36 | Translation, or POT files.
| | 01:39 | Those will then store information
about what needs to be replaced where, when
| | 01:43 | different languages are hitting the web site.
| | 01:46 | The idea being that you can have the
same version of a plugin running, and if
| | 01:51 | someone comes from China they'll see a
Chinese language site, and if someone
| | 01:54 | comes from United States, they'll
see an English language site.
| | 01:57 | In addition to the underscore underscore
function, there is also an underscore e function.
| | 02:02 | In this case, I am just
storing the variable local.
| | 02:05 | If I am outputting anything to the
browser using an echo statement of some kind,
| | 02:11 | then I want to make sure to wrap
it in an underscore e function.
| | 02:19 | So from a developer standpoint, these
are the main things that we are going to
| | 02:22 | be doing: just wrapping areas of static
text that might need to be changed if
| | 02:27 | someone from a different language is
viewing it in either the underscore
| | 02:31 | underscore function or
the underscore e function.
| | 02:35 | The next step will be eventually to
generate a POT file, and this is the default
| | 02:40 | POT file that comes with WordPress,
and you can see there are a number of
| | 02:44 | different strings that are stored inside
of the WordPress environment. And it'll
| | 02:48 | even tell you where they are.
| | 02:50 | Now these have all been wrapped in
either the underscore underscore or
| | 02:53 | underscore e functions.
| | 02:56 | So someone else can come and create a
new POT file and assign it to a different
| | 03:00 | text domain, and it will
then be able to translate.
| | 03:03 | There are number of different
softwares that work with that, and we are not
| | 03:05 | going to get into that end of things.
| | 03:07 | I just wanted to show you how to
prepare things so that they can
| | 03:10 | be internationalized,
| | 03:12 | because it's considered a best practice
in plugin development that you should
| | 03:15 | be using the underscore e and the underscore
underscore whenever you output some static text.
| | 03:20 | So overall, WordPress utilizes PHP's get
text translation engine to handle sites
| | 03:26 | using multiple languages.
| | 03:28 | The first step in internationalization
is to mark these different pieces with
| | 03:33 | these special functions.
| | 03:34 | Once you do that, translators will
create POT files and assign text domains, and
| | 03:40 | your site can be
available in different languages.
| | Collapse this transcript |
|
|
ConclusionGoodbye| 00:00 | Thanks for watching
Developing Custom Widgets and Plugins.
| | 00:03 | I hope you gain the tools you need to
customize your own WordPress web sites.
| | 00:07 | I encourage you to check out
some other titles at lynda.com.
| | 00:10 | There is a bunch of them on
WordPress themes, PHP, MySQL and even jQuery.
| | 00:15 | We'll see you next time!
| | Collapse this transcript |
|
|