Building Web Apps With WordPress - kylecoberly/knowledge GitHub Wiki
- In the root directory, the only file you should touch is
wp-config.php. Everything else could be rewritten with an upgrade. -
/wp-adminis the admin dashboard, AJAX calls should all go throughadmin-ajax.php -
/wp-includesis where the built-in functions are -
/wp-contentis where all of the customization is/plugins/themes-
/uploads- Media files -
/mu-plugins- "Must use" - plugins that are autoloaded and don't even show up on the dashboard
-
wp_optionsTable - Sitewide data, plugin settings- Functions are in
/wp-includes/option.php
- Functions are in
-
wp_users- User data, generally managed from dashboard-
wp_usermeta- Extensible user data, use this to add extra attributes without adding more columns to thewp_userstable - Functions are in
/wp-includes/pluggable.phpand/wp-includes/user.php
-
-
wp_posts- Data for posts, pages, menu items, etc. Type is determined by thepost_typecolumn.-
wp_postmeta- Extra data for posts, better than adding more columns towp_posts - Functions are in
/wp-includes/post.php
-
-
wp_comments-
wp_commentmeta- Extra data for comments, better than adding more columns towp_comments - Functions are in
/wp-includes/comment.php
-
-
wp_terms- Stores taxonomies- tags, categories, etc.-
wp_termmeta- Extra data for terms, better than adding more columns towp_terms -
wp_term_taxonomy- Registers new taxonomies -
wp_term_relationships- Stores taxonomy assignments - Functions are in
/wp-includes/taxonomy.php
-
When WP code has a do_action function, you can insert your code to run in it using the add_action function:
add_action('init', 'some_function_name')Filters work on the output of functions, and give you a chance to modify data before it show up on the page or goes into the database:
apply_filters('the_name_of_the_hook, 'a_function_that_will_be_called_with_the_value')composer global require phpunit/phpunit:5.*- Test methods must be prefixed with
test_, and the classes should be suffixed with Test
<?php
class WP_Meta_VerifyTest extends WP_UnitTestCase
{
public function setUp()
{
parent::setUp();
$this->class_instance = new WP_Meta_Verify();
}
public function test_google_site_verification()
{
}
public function test_bing_site_verification()
{
}
}Makes integrating PHPUnit easier
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wpGives you commands like:
wp scaffold plugin-tests name-of-plugin-here- Frontmatter shows up on the dashboard
- You can extend existing plugins with addons, which may use hooks and filters for the plugins
- You should have one primary plugin for your app code
- Any modular thing that could be useful in another project should be a separate plugin
Example:
<?php
/**
* Plugin Name: My Plugin
* Plugin URI: https://bwawwp.com/my-plugin/
* Description: This thing rocks
* Author: Kyle Coberly
* Version: 1.0.0
* Author URI: kylecoberly.com
* License: GPL-2.0+
* License URI: http://ww.gnu.org/licenses/gpl-2.0.txt
*/
function some_plugin(){
echo "<h1>Can't stop; won't stop</h1>";
}
add_action('wp_footer', 'some_plugin')
?>adminpages/ (only backend)
classes/ (should be named class.ClassName.php)
css/
|-admin.css (only what you would need with no theme at all)
|-frontend.css (only what you would need with no theme at all)
js/
images/
includes/ (all PHP files needed by your plugin)
|-lib/ (third-party)
|-functions.php (helper code, not core logic)
pages/ (only frontend)
services/ (PHP code for AJAX calls)
scheduled/ (for crons or other intervals)
my-plugin.php (entrypoint)
Loading CSS and JS:
function load_a_style(){
wp_enqueue_style(
'name-of-script',
plugins_url('css/file-path.css, __FILE__),
array(),
VERSION_NUMBER_HERE,
'screen'
);
}
function load_a_script(){
wp_enqueue_script(
'name-of-script',
plugins_url('js/file-path.js', __FILE__),
array('dependent-script'),
VERSION_NUMBER_HERE
);
}
function add_a_menu_page()
add_menu_page(
'Page Title',
'Menu Title',
'capability_required_to_show_page', // eg. manage_options
'menu-slug',
'reports_page' // callable
);
}
function reports_page(){
require_once dirname( __FILE__ ) . "/adminpages/reports.php";
}
add_action('wp_enquque_scripts', 'load_a_script');
add_action('wp_enquque_scripts', 'load_a_style);WordPress Loop:
global $post; // All post data
global $authordata; // Author of a post
global $wp_query // All post content for the page you're on
global $current_userglobal $wpdb
$wpdb->query() // Query the DB directly, returns a bunch of different things
$wpdb->prepare($query, $params) // Prepared statements, uses %s, %f, %s, and the literal %%
$wpdb->result()
$wpdb->insert_id()
$wpdb->get_results($query, $output_type) // number/associative, array/object
$wpdb->get_col($query, $column_offset) // Pluck, eg. ids
$wpdb->get_row($query, $output_type, 0) // Get first record
$wpdb->insert(
$wpdb->my_table_name
array("name" => $name, "id" => $id),
array($s, $d)
) // Auto-escaped
$wpdb->replace($name, $data, $types) // Overwrites any row with same keys as $data
$wpdb->update($table, $data, $where)- You should have one primary theme for the frontend.
- WordPress scans all of the
.phpfiles in your active theme's directory for templates. Any file withTemplate Name: Whateverin the frontmatter will be available as a template - If your users must activate a plugin for a theme to work, you should probably put the plugin related stuff in a parent theme and the view stuff in a child theme.
-
index.phpis the fallback for all page loads, and withstyle.cssis the only required file for a theme - You can make single- and archive- versions of any custom post type:
single-<post-type>.php,archive-<post-type>.php - Templates are loaded after WordPress's
initandwpactions have fired
index.php404.phpauthor.phparchive.phpattachment.phpcomments.phpdate.phpfooter.phpfront-page.phpfunctions.phpheader.phphome.phpimage.phpsearch.phpsidebar.phpcategory.phptag.phptaxonomy.phpsingle.phpsingle-{post-type}.phppage.php
To load a file, use the get_{type}() method:
get_header(); // Loads `header.php`
get_header("alternate"); // Loads `header-alternate.php`
comments_template(); // Loads `comments.php`
get_search_form(); // Loads `searchform.php`/includes/functions.php
/includes/settings.php
/includes/sidebars.php
-
_s(Underscores) - Not a parent theme, but a starting place for building a parent theme - Memberlite - For member-driven sites, good for designers
- Genesis - Parent theme, very abstracted, good for lite customization
You can use the the_content hook to wrap content:
<?php
function template($content){
ob_start();
?>
<p>This will go after whatever</p>
<?php
$template_content = ob_get_contents();
ob_end_clean();
return $content . $template_content;
}
?>- You can achieve something similar with "short codes", which are simple syntax for embedding images, quizzes, API data, etc.
- You can use
locate_templateto find something that may have been overridden by a user - You can also look up specific templates and send data to them:
get_template_part('templates/some_content', 'function_to_process_template')- Allows users to control items from dashboard
// Register
register_nav_menu($slug, $long_name);
register_nav_menus(array($slug => $long_name));
// Consume
wp_nav_menu(array('theme_location' => 'main'));- Loaded in a
style.cssfile, which is automatically enqueued. - Version your CSS so the files can be fingerprinted
- You can use
wp_enqueue_style()to load up individual CSS files - You can use media queries for responsiveness, and also pass them into
wp_enqueue_style
Looks for the following frontmatter:
/*
Theme Name: Name
Theme URI: https://uri
Author: Kyle Coberly
Author URI: https://kylecoberly.com
Description: Site
Version: 1.4
License: MIT
License URI: https://mitlicense.org
Text Domain: name
Tags: comma, separated, list
*/Built-in globals:
$is_lynx$is_gecko$is_winIE$is_macIE$is_opera$is_NS4$is_safari$is_chrome$is_iphone$is_IE$is_apache$is_IIS$is_iis7wp_is_mobile()-
get_browser()// Use with caution
- Admin Columns - Manages what columns are displayed on posts, users, comments, media, and CPT
- Advanced Custom Fields - Adds custom fields for any post type
- BadgeOS/GamiPress - Adds achievements
- Posts 2 Posts - M:N Relationships between posts
- Members - User roles
- W3 Total Cache - Caching for performance
- Yoast SEO - Auto SEO optimization
- Gravity Forms - Custom contact forms
- BackupBuddy - Backup your WP instance
- WP All Import - Import CSV or XML data into WP
- BuddyPress - Social Media