Let’s start by defining what a web app is and how it differs from a website or a web service.
In reality, this book will help you build anything with WordPress: websites, themes, plugins, web services, and web apps. We chose to focus on web apps because they can be seen as super websites that make use of all of the techniques we’ll cover.
There are many people who believe that WordPress isn’t powerful enough or meant for building web apps, and we’ll get into that more later. We’ve been building web apps with WordPress for many years and know that it absolutely is possible to build scalable applications using WordPress.
In this chapter, we’ll cover why WordPress is a great framework for building web apps. We’ll also cover some situations where using WordPress wouldn’t be the best way to build your web app.
You can also think of a web app as a website, plus more application-like stuff.
There is no exact line where a website becomes a web app. It’s one of those things where you know it when you see it.
What we can do is explain some of the features of a web app, give you some examples, and then try to come up with a shorthand definition so you know generally what we are talking about as we use the term throughout the book.
You will see references to SchoolPress while reading this book. SchoolPress is a web application we are building to help schools and educators manage their students and curricula. All of the code examples are geared toward functionality that may exist in SchoolPress. We will talk more about the overall concept of SchoolPress later in this chapter.
The following are some features generally associated with web apps and applications in general. The more of these features present in a website, the more appropriate it is to upgrade its label to a web app.
A typical website experience involves navigating through page loads, scrolling, and clicking hyperlinks. Web apps can have links and scrolling as well, but will tend to use other methods of navigating through the app.
Websites with forms offer transactional experiences. An example would be a contact form on a website or an application form on the careers page of a company website. Forms allow users to interact with a site using something more than a click.
Web apps will have even more interactive UI elements. Examples include toolbars, drag and drop elements, rich text editors, and sliders.
Remember, web apps are “designed to help the user to perform specific tasks.” Google Maps users get driving directions. Gmail users write emails. Trello users manage lists. SchoolPress users comment on class discussions.
Some apps are still content focused. A typical session with a Facebook or Twitter app involves about 90% reading. However, the apps themselves present a way of browsing content different from the typical web browsing experience.
Logins and accounts allow a web app to save information about its users. This information is used to facilitate the main tasks of the app and enable a persistent experience. When logged in, SchoolPress users can see which discussions are unread. They also have a username that identifies their activity within the app.
Web apps can also have tiers of users. SchoolPress will have admins controlling the inner workings of the app, teachers setting up classes, and students participating in class discussions.
Whenever possible, it’s a good idea to make your web apps work offline. Sure, the interactivity of the Internet is what defines that “web” part of web app, but a site that doesn’t stop working when someone drives through a tunnel will feel more like an app.
Emails can be drafted offline in Gmail. Evernote will allow you to create and edit notes offline and sync them to the Internet when connectivity comes back.
No single programming language or software tool will be right for every job. We’ll cover why you may not want to use WordPress in a bit, but for now, let’s go over some situations where using WordPress to build your web app would be a good choice.
If you are already using WordPress for your main site, you might just be a quick plugin away from adding the functionality you need. WordPress has great plugins for ecommerce (Jigoshop), forums (bbPress), membership sites (Paid Memberships Pro), social networking functionality (BuddyPress), and gamification (BadgeOS).
Building your app into your existing WordPress site will save you time and make things easier on your users. So if your application is fairly straightforward, you can create a custom plugin on your WordPress site to program the functionality of your web app.
If you are happy with WordPress for your existing site, don’t be confused if people say that you need to upgrade to something else to add certain functionality to your site. It’s probably not true. You don’t have to throw out all of the work you’ve done on WordPress already, and all of the following are great reasons to stick with WordPress.
WordPress was developed first as a blogging platform, but through the years and with the introduction of custom post types (CPTs) in version 3.0, it has evolved into a fully functional content management system (CMS). Any page or post can be edited by administrators via the dashboard, which can be accessed through your web browser. You will learn about working with CPTs in Chapter 5.
WordPress makes adding and editing content easy via a WYSIWYG editor, so you don’t have to use web designers every time you want to make a simple change to your site. You can also create custom menus and navigation elements for your site without touching any code.
If your web app focuses around bits of content (e.g., our SchoolPress app is focused on assignments and discussions), the Custom Post Types API for WordPress (covered in Chapter 5) makes it easy to quickly set up and manage this custom content.
Even apps that are more task oriented will typically have a few pages for information, documentation, and sales. Using WordPress for your app will give you one place to manage your app and all of your content.
In addition to controlling access to content, the Roles and Capabilities system in WordPress is extensible and allows you to control what actions are available for certain groups of users. For example, by default, users with the contributor role can add new posts, but can’t publish them. Similarly, you can create new roles and capabilities to manage who has access to your custom functionality.
Plugins like Paid Memberships Pro can be used to extend the built-in user management to allow you to designate members of different levels and control what content users have access to. For example, you can create a level to give paying members access to premium content on your WordPress site.
There are over 27,000 free plugins in the WordPress repository. There are many more plugins, both free and premium, on various sites around the Internet. When you have an idea for an extension to your website, there is a good chance that there’s a plugin for that, which will save you time and money.
There are a handful of indispensable plugins that we end up using on almost every site and web application we build.
For most websites you create, you’ll want to cache output for faster browsing, use tools like Google Analytics for visitor tracking, create sitemaps, and tweak page settings for search engine optimization (SEO), along with a number of other common tasks.
There are many well-supported plugins for all of these functions. We suggest our favorites throughout this book; you can find a list of them on this book’s website.
WordPress and PHP/MySQL in general aren’t perfect for every task, but they are well suited for a wide range of tasks. Having one platform that will grow with your business can allow you to execute and pivot faster.
The neat thing about moving through the path is that at every step along the way, you have the same database of users and are using the same development platform.
The fact that WordPress is used on millions of sites makes it a target for hackers trying to break through its security. Some of those hackers have been successful in the past; however, the developers behind WordPress are quick to address vulnerabilities and release updates to fix them. It’s like having millions of people constantly testing and fixing your software, because that’s exactly what is happening.
The underlying architecture of WordPress makes applying these updates a quick and painless process that even novice web users can perform. If you are smart about how you set up WordPress and upgrade to the latest versions when they become available, WordPress is a far more secure platform for your site than anything else available. Security is discussed in more detail in Chapter 8.
WordPress is free. PHP is free. MySQL is free. Most plugins are free. Hosting costs money. But depending on how big your web application is and how much traffic you get, it can be relatively inexpensive. If you require custom functionality not found in any existing plugins, you may need to pay a developer to build it. Or if you are a developer yourself, it will cost you some time.
In short, you can build any size application on top of WordPress and nine times out of 10, it will cost less money and take less time to develop than on any other platform.
There are some highly vocal critics of WordPress who will say that WordPress isn’t a good framework for building web apps, or that WordPress isn’t a framework at all. With all due respect to those with these opinions, we’d like to go over why we disagree. Here are some common criticisms:
Statements like this were true a few years ago, but WordPress has since implemented strong CMS functionality, making it useful for other content-focused sites. WordPress is now the most popular CMS in use, with over 50% market share.
Figure 1-1 shows a slide from Matt Mullenweg’s “State of WordPress” presentation from WordCamp San Francisco 2013. The upside-down pyramid on the left represents a circa 2006 WordPress, with most of the code devoted to the blog application and a little bit of CMS and platform code holding it up. The pyramid on the right represents the current state of the WordPress platform, where most of the code is in the platform itself, with a CMS layer on top of that, and the blog application running on top of the CMS layer. WordPress is a much more stable platform than it was just a few years ago.
The Custom Post Types API can be used to tweak your WordPress install to support other content types besides blog posts or pages. This is covered in detail in Chapter 5.
WordPress is the clear choice for any content-related website. However, as we’ll go over in detail in this very book, WordPress is a great framework for building more interactive web applications as well.
The main feature allowing WordPress to be used as a framework is the plugins API, which allows you to hook into how WordPress works by default and change things. Not only can you use the thousands of plugins available in the WordPress repository and elsewhere on the Internet, you can use the plugins API to write your own custom plugins to make WordPress do anything possible in PHP/MySQL.
WordPress doesn’t scale. Some will point to a default WordPress install running on low-end hosting, note how the site slows down or crashes under heavy load, and conclude that WordPress doesn’t scale.
This statement is provably false. WordPress.com runs on the same basic software as any WordPress site and at the time of this writing is somewhere between the 13th most- and 22nd-most-visited website in the world.
The issues with scaling WordPress are the same issues you have scaling any application: caching pages and data and handling database calls more rapidly. We can learn by how large sites like WordPress.com, TechCrunch, and the New York Times blogs have scaled on WordPress. Similarly, most of the lessons learned scaling PHP/MySQL applications in general apply to WordPress as well. Scaling WordPress apps is covered in detail in Chapter 16.
On the one hand, because WordPress is so popular, it will be the target of hackers looking for security exploits. And because the code is open source, these exploits will be easier to discover.
On the other hand, because WordPress is open source, you will hear about it when these exploits become public, and someone else will probably fix the exploit for you.
We feel more secure knowing that there are lots of people out there trying to exploit WordPress and just as many people working to make WordPress secure against those exploits. We don’t believe in “security through obscurity” except as an additional measure. We’d rather have the security holes in our software come out in the open rather than go undetected until the worst possible moment.
Chapter 8 will cover security issues in more detail, including a list of best practices to harden your WordPress install and how to code in a secure manner.
WordPress plugins are crap. The plugin API in WordPress and the thousands of plugins that have been developed using it are the secret sauce and in our opinion the number one reason that WordPress has become so popular and is so successful as a website platform.
Some people will say, “Sure, there are thousands of plugins, but they are all crap.”
OK, some of the plugins out there are crap. But there are a lot of plugins that are most definitely not crap.
Paid Memberships Pro, developed by our coauthor Jason Coleman, is not crap. Using Paid Memberships Pro to handle your member billing and management will allow you to focus your development efforts on your app’s core competency instead of how to integrate your site with a payment gateway.
A lot of plugins do something very simple (e.g., hiding the admin bar from nonadmins), work exactly as advertised, and don’t really have room for being crap.
Even the crappy plugins can be fixed, rewritten, or borrowed from to work better. You may find it easier sometimes to rewrite a bad plugin instead of fixing it. However, you’re still further ahead than you would be if you had to write everything yourself from scratch.
No one is forcing you to use WordPress plugins without vetting them yourself. If you are building a serious web app, you’re going to check out the plugin code yourself, fix it up to meet your standards, and move on with development.
WordPress uses the GNU General Public License, version 2 (GPLv2), which has restrictions on how you distribute any software that you build with it. Namely, you cannot restrict what people do with your software once you sell or distribute it to them.
This is a complicated topic, but the basic idea is if you are only selling or giving away access to your application, you won’t have to worry about the GPLv2. However, if you are selling or distributing the underlying source code of your application, the GPLv2 will apply to the code you distribute.
For example, if we host SchoolPress on our own servers and sell accounts to access the app, that doesn’t count as distribution, and the GPLv2 doesn’t impact our business at all.
However, if we wanted to allow schools to install the software to run on their own servers, we would have to share the source code with them. This would count as an act of distribution. Our customers would be able to legally give our source code away for free even if we had initially charged them for the software. We’d have to use the GPLv2 license, which wouldn’t allow us to restrict what they do with the code after they downloaded it.
If you have a team of experienced Ruby developers, you should use Ruby to build your web app. If there is a platform, framework, or bundle that includes 80% of the features you need for your web app and WordPress doesn’t have anything similar, you should probably use that other platform.
One of the greatest features of a WordPress site is the ability to change parts of your website to better fit your needs quickly. For example, if Facebook “likes” stop driving traffic, you can uninstall your Facebook connect plugin and install a Google+ one.
Generally, updating your theme or swapping plugins on a WordPress site will be faster than developing features from scratch on another platform.
However, in cases where optimization and performance are more important than being able to quickly update the application, programming a native app or programming in straight PHP, is going to be the better choice.
For example, if your app is going to do one simple thing (say just display the current time), you will want to build your app at a lower level. Similarly, if you have Facebook’s resources, you can afford to build everything by hand and use custom PHP-to-C compilers to shave a few milliseconds off your website load times.
One of the potential downsides of WordPress, which we will get into later, is its reliance on the typical web server architecture. In the typical WordPress setup, a user visits a URL, which hits a web server (like Apache) over HTTP, kicks off a PHP script to generate the page, and then returns the full page to the user.
There are ways to improve the performance of this architecture using caching techniques and/or optimized server setups. You can make WordPress asynchronous by using using AJAX calls or accessing the database with alternative clients. However, if your application needs to be real-time and fully asynchronous (e.g., a chatroom-like app or a multiplayer game), you have our blessing to think twice about using WordPress.
Many WordPress developers, including Matt Mullenweg, the founder and spiritual leader of WordPress, understand this limitation. It is very likely that the WordPress core will be updated over time to work better for real-time asynchronous apps (the Heartbeat API released in version 3.6 of WordPress is a good step in this direction), but currently you’re going to face an uphill battle trying to get WordPress to work asynchronously with the same performance as a native app or something built using Node.js or other technologies specifically suited to real-time applications.
Content management systems like WordPress, Drupal, and Joomla often get left out of the framework discussion, but in reality, WordPress (in particular) is really great for what frameworks are supposed to be about: quickly building applications.
Within minutes, you can set up WordPress and have a fully functional app with user signups, session management, content management, and a dashboard to monitor site activity.
The various APIs, common objects, and helper functions covered throughout this book allow you to code complex applications faster without having to worry about lower-level systems integration.
Figure 1-2 shows that right triangle from Mullengweg’s 2013 “State of WordPress” presentation depicting a stable WordPress platform with a CMS layer built on top and a blogging application built on top of the CMS layer.
The reality is that the majority of the current WordPress codebase supports the underlying application platform. You can think of each WordPress release as a application framework with a sample blogging app bundled in.
MVC stands for model-view-controller and is a common design pattern used in many software development frameworks. The main benefits of using an MVC architecture are code reusability and separation of concerns. WordPress doesn’t use an MVC architecture, but does in its own way encourage code reuse and separation of concerns.
I’ll explain the MVC architecture very briefly and how it maps to a WordPress development process. This section should help readers who are familiar with MVC-based frameworks understand how to approach WordPress development in a similar way.
Figure 1-3 describes a typical MVC-based application. The end user uses a controller, which manipulates the application state and data via a model, which then updates a view that is shown to the user. For example, in a blog application, a user might be looking at the recent posts page (a view). The user would click a post title, which would take the user to a new URL (a controller) that would load the post data (in a model) and display the single post (a different view).
The MVC architecture supports code reusability by allowing the models, views, and controllers to interact. For example, both the recent posts view and the single posts view might use the same post model when displaying post data. The same models might be used in the frontend to display posts and in the backend to edit them.
The MVC architecture supports separation of concerns by allowing designers to focus their attention on the views, while programmers focus their attention on the models.
You could try to use an MVC architecture within WordPress. There are a number of projects to help you do just that; however, we think trying to strap MVC onto WordPress could lead to issues unless the WordPress core were to officially support MVC. Instead, we suggest following the “WordPress Way,” as outlined in this book.
There are a couple of ways to map an MVC process to WordPress.
In WordPress, plugins are the proper place to store new data structures, complex business logic, and custom post type definitions.
This comparison breaks down in a couple of ways. First, many plugins add view-like functionality and contain design elements. Take any plugin that adds a widget to be used in your pages. Second, forms and other design components used in the WordPress dashboard are generally handled in plugins as well.
One way to make the separation of concerns more clear when adding view-like components to your WordPress plugins is to create a “templates” or “pages” folder and put your frontend code into it. Common practice is to allow templates to override the template used by the plugin. For example, when using WordPress with the Paid Memberships Pro plugin, you can place a folder called “paid-memberships-pro/pages” into your active theme to override the default page templates.
Again, the comparison here doesn’t map one to one, but “views = themes” is a good starting point.
In an MVC framework, the code to process user input (in the form of URLs or
$_POST data) and decide which models and views to use to handle a request are stored in the controllers. Controller code is generally handled by a programmer and often set up once and forgotten about. The meat of the programming in an MVC application happens in the models and views.
In WordPress, all page requests (unless they are accessing a cached .html file) are processed through the index.php file and processed by WordPress according to the Template Hierarchy. The template loader figures out which file in the template should be used to display the page to the end user. For example, use search.php to show search results, single.php to show a single post, etc.
The default behavior can be further customized via the WP_Rewrite API (covered in Chapter 7) and other hooks and filters.
For a better understanding of how MVC frameworks work, the PHP framework Yii has a great resource explaining how to best use their MVC architecture.
For a better understanding of how to develop web applications using WordPress as a framework, continue reading this book.
In this section, we’ll describe the app we built as a companion for this book: SchoolPress. We’ll cover the intended functionality of SchoolPress, how it will work and who will use it, and—most importantly for this book—how each piece of the app will be built in WordPress.
Don’t be alarmed if you don’t understand some of the following terminology. In later chapters, we will go over everything introduced here in more detail. Whenever possible, we’ll point to the chapter of this book that corresponds to the feature being discussed.
SchoolPress is a web app that makes it easy for teachers to interact with their students outside of the classroom. Teachers can create classes and invite their students to them. Each class has a forum for ad hoc discussion and also a more structured system for teachers to post assignments and have students turn in their work.
SchoolPress runs a multisite version of WordPress. The main site at schoolpress.me hosts free accounts where teachers can sign up and start managing their classes. It also has all of the marketing information for separate school sites on the network, including the page to sign up and checkout for a paid membership level.
Schools can pay an annual fee to create a unique subdomain for their school, like yourschool.schoolpress.me, that will house classes for their teachers and offers finer control and reporting for all classes across the entire school. Details on using a multisite network with WordPress can be found in Chapter 13.
Schools can purchase a unique subdomain for their school for an annual fee. No other SchoolPress users pay for access.
When school admins sign up, they can specify a school name and slug for their subdomain (
myschool.schoolpress.me). A new network site is set up for them and they are given access to a streamlined version of the WordPress dashboard for their site.
The school admin then invites teachers into the system. Teachers can also request an invitation to a school that must be approved by the school admin.
Teachers can invite students to the classes they create. Students can also request an invitation to a class that must be approved by the teacher.
Teachers can also sign up for free to host their classes at
schoolpress.me. Pages hosted on this subdomain may run ads or other monetization schemes. Details on how to setup ecommerce with WordPress can be found in Chapter 15.
Teachers are given a Teacher membership level (through Paid Memberships Pro) and a custom role called “Teacher” that gives them access to create and edit their classes, moderate discussion in their class forums, and create and manage assignments for their classes.
Teachers do not have access to the WordPress dashboard. They create and manage their classes and assignments through frontend forms created for this purpose.
Students are given a “Student” membership level and the default “Subscriber” role in WordPress. Students only have access to view and participate in classes they are invited to by their teachers. Details on user roles and capabilities can be found in Chapter 6. Details on using membership levels to control access can be found in Chapter 15.
When teachers create “classes,” they are really creating BuddyPress groups and inviting their students to the group. Using BuddyPress, we get class forums, private messaging, and a nice way to organize our users.
The class discussion forums are powered by the bbPress plugin. A new forum is generated for each class, and BuddyPress manages access to the forums. Details on leveraging third-party plugins like BuddyPress and bbPress can be found in Chapter 3.
Assignments are a custom post type (CPT), with a frontend submission form for teachers to post new assignments. Assignments are just like the default blog posts in WordPress, with a title, body content, and attached files. The teacher posting the assignment is the author of the post.
WordPress has built-in post types like posts and pages and built-in taxonomies like categories and tags. For SchoolPress, we are creating our own CPTs and taxonomies. Details on creating custom post types and taxonomies can be found in Chapter 5.
Students can post comments on an assignment, and they can also choose to post their official submission for the assignment through another form on the frontend.
Submissions, like assignments, are also CPTs. Submissions are linked to assignments by setting the submission’s
post_parent field to the ID of the assignment it was submitted to. Students can post text content and also add one or more attachments to a submission.
A custom taxonomy called “Semester” is set up for the group/class CPT. School admins can add new semesters to their sites. For example, a “fall 2013” semester could be created and teachers could assign this semester when creating their classes. Students can then easily view a list of all fall 2013 classes to browse through.
A custom taxonomy called “Department” is also set up for the group/class CPT. This is also available as a dropdown for teachers when creating their classes and allows for a browsable list of classes by department.
Behind the scenes, the custom bits of the SchoolPress app are controlled from a single custom plugin called SchoolPress. This — the main plugin — includes the definitions for the various custom post types, taxonomies, and user roles. It also contains the code to tweak the third-party plugins SchoolPress uses like Paid Memberships Pro and BuddyPress.
The main plugin also contains classes for school admins, teachers, and students that extend the WP_User class and classes for classes, assignments, and submissions that wrap the WP_Post class. These (PHP) classes allow us to organize our code in an object-oriented way that makes it easier to control how our various customizations work together and will make it easier to extend our code in the future. These classes are fun to work with and allow for the code that you see in Example 1-1.
//this is the teacher, show them teacher stuff
//this is a student in the class, show them student stuff
//not logged in, send them to the login form with a redirect back here
//not a member of this class, redirect them to the invite page
Occasionally a bit of code will be developed for a particular app that would also be useful on other projects. If the code can be contained enough that it can run outside of the context of the current app and main plugin, it can be built into a separate custom plugin.
An example of this would be the force-first-name-last-name plugin that was a requirement for this project. It didn’t require any of the main plugin code to run and is useful for other WordPress sites outside of the context of the SchoolPress app.
The main schoolpress.me site runs on a customized StartBox child theme. If a school signs up for a premium subdomain, it can choose from a variety of StartBox child themes; it also has the ability to change any of the theme’s colors, fonts, and logos to better fit its branding.
All themes use a responsive design that ensures the site will look good on mobile and tablet displays as well as desktop displays.
The code in the StartBox theme is very strictly limited to display-related programming. The theme code obviously includes the HTML and CSS for the site’s layout, but also contains some simple logic that integrates with the main SchoolPress plugin (like the preceding branching code). However, any piece of code that manipulates the custom post types or user roles or involves a lot of calculation is delegated to the SchoolPress plugin.
 Many of the ideas in this section are influenced by these blog posts: “What is a Web Application?” by Dominique Hazaël-Massieux and “What is a Web Application?” by Bob Baxley.