Как получить чёрный пояс
по WordPress?
Евгений КотельницкийWordCamp Russia 2015
Евгений Котельницкий
+YevhenKotelnytskyi
@yeeevhenhttp://4coder.info/me
План1. Что определяет уровень разработчика?
2. Через что проходит WP разработчик?
3. Что дальше?
Шаг 1 - Регестрируем блог на WP.com
Шаг 2 - Поднимаем WP на Shared-хостинге
Шаг 3 - Устанавливаем темы
Шаг 4 - Вносим правки в тему
Шаг 5 - Устанавливаем плагины
Шаг 6 - Изучаем админку
WordPress User Roles
User Roles
● Super Admin – site network administration;
● Administrator – administration features within a single site;
● Editor – can publish and manage posts of other users;
● Author – can publish and manage their own posts;
● Contributor – can write posts but cannot publish them;
● Subscriber – can only manage their profile.
Первый пояс есть!
FTP / SFTP
PhpMyAdmin
Начинаем создавать темы осмысленно
Знакомимся с теорией:
● http://codex.wordpress.org/Theme_Development● http://codex.wordpress.org/Template_Hierarchy● http://codex.wordpress.org/Conditional_Tags● ...
Plugins & MU plugins
Post Types
● Post (Post Type: 'post')
● Page (Post Type: 'page')
● Attachment (Post Type: 'attachment')
● Revision (Post Type: 'revision')
● Navigation menu (Post Type: 'nav_menu_item')
● Custom Post Type (CPT): register_post_type()
Taxonomies
● Category (taxonomy: 'category')
● Tag (taxonomy: 'post_tag')
● Link Category (taxonomy: 'link_category')
● Post Formats (taxonomy: 'post_format')
● Custom Taxonomies: register_taxonomy()
Data Access API
● WP_Query● WP_Tax_Query● WP_User_Query● get_posts ()● get_terms ()● get_option ()● get_post_meta ()● get_user_meta ()● ...
Второй пояс получен!
Database Structure
Direct Database Access abstraction
<?php
global $wpdb;
$wpdb->query(
$wpdb->prepare(
"DELETE FROM $wpdb->postmeta
WHERE post_id = %d
AND meta_key = %s",
13, 'gargle' ) );
?>
/**
* WordPress Database Access Abstraction
*/
class wpdb {
public function prepare( $query, $args );
public function show_errors( $show = true );
public function query( $query );
public function get_results( $query = null, $output = OBJECT ) {
public function get_row( $query = null, $output = OBJECT, $y = 0 );
public function get_col( $query = null , $x = 0 );
public function get_var( $query = null, $x = 0, $y = 0 );
public function update( $table, $data, $where, $format = null, $where_format = null );
...
Direct Database Access abstraction
Система хуков
<?php
do_action( $tag, $arg_a, $arg_b, $etc );
add_action( $tag, $function_to_add, $priority = 10, $accepted_args = 1 );
?>
<?php
apply_filters( $tag, $value );
add_filter( $tag, $function_to_add, $priority, $accepted_args );
?>
Actions
Filters
Достигнут новый пояс!
Source Code Management Systems
Стандарты кодирования
PHP Coding Standards
HTML Coding Standards
CSS Coding Standards
JavaScript Standards
Localization
Localization
<?php
load_textdomain( $domain, $mofile );
load_plugin_textdomain( $domain, $abs_rel_path, $plugin_rel_path );
?>
<?php
$translated = __( 'Hello World!', 'domain' );
?>
<?php _e( 'Hello World!', 'domain' ) ?>
Localization & JS
<?php
// Register the script first
wp_register_script( 'some_handle', 'path/to/myscript.js' );
// Now we can localize the script with our data
$translation = array(
'some_str' => __( 'Some string', 'domain' ),
'a_value' => '10'
);
wp_localize_script( 'handle', 'object_name', $translation );
// The script can be enqueued now or later
wp_enqueue_script( 'handle' );
Зелёный пояс!
WP Network
WP Network
<?php
switch_to_blog( $blog_id );
// Do something
restore_current_blog();
?>
Network Database
● wp_blogs
● wp_blog_versions
● wp_registration_log
● wp_signups
● wp_site
● wp_sitemeta
Быстродействие
Синий пояс!
WordPress User Roles
Super Admin capabilities
● manage_network
● manage_sites
● manage_network_users
● manage_network_plugins
● manage_network_themes
● manage_network_options
● ...
Subscriber capabilities
● read
WordPress User Roles
class WP_Roles {
/**
* Add role name with capabilities to list.
*/
public function add_role( $role, $display_name, $capabilities = array() );
public function remove_role( $role );
/**
* Add capability to role.
*/
public function add_cap( $role, $cap, $grant = true );
public function remove_cap( $role, $cap );
...
WordPress User class
class WP_User {
/**
* Add role to user.
*/
public function add_role( $role );
public function remove_role( $role );
public function set_role( $role );
/**
* Add capability and grant or deny access to capability.
*/
public function add_cap( $cap, $grant = true );
public function remove_cap( $cap );
...
class WP_User {
/**
* Whether user has capability or role name.
* @return bool True, if user has capability;
* false, if user does not have capability.
*/
public function has_cap( $cap ) {
$caps = call_user_func_array( 'map_meta_cap', $args );
...
// Must have ALL requested caps
$capabilities = apply_filters(
'user_has_cap', $this->allcaps,
$caps, $args, $this );
...
WordPress User class
Впервые задумываемся о безопасности
Коричневый пояс!
Как работает WordPress?WordPress environment setup class
class WP {
/**
* Sets up all of the variables required by the WordPress environment.
* @param string|array $query_args Passed to {@link parse_request()}
*/
public function main($query_args = '') {
$this->init();
$this->parse_request($query_args);
$this->send_headers();
$this->query_posts();
$this->handle_404();
$this->register_globals();
do_action_ref_array( 'wp', array( &$this ) );
}
...
WP_Rewrite - “Роутинг”
WP_Rewrite - “Роутинг”
class WP_Rewrite {
/**
* Retrieve the rewrite rules.
* @return array Rewrite rules.
*/
public function wp_rewrite_rules() {
$this->rules = get_option('rewrite_rules');
if ( empty($this->rules) ) {
$this->matches = 'matches';
$this->rewrite_rules();
update_option('rewrite_rules', $this->rules);
}
return $this->rules;
}
...
WP_Rewrite - “Роутинг”Rewrite Rules
<?php
$rewrite = $wp_rewrite->wp_rewrite_rules();
array(
[robots\.txt$] => index.php?robots=1
[category/(.+?)/?$] => index.php?category_name=$matches[1]
[page/?([0-9]{1,})/?$] => index.php?&paged=$matches[1]
[search/(.+)/?$] => index.php?s=$matches[1]
[([0-9]{4})/?$] => index.php?year=$matches[1]
[.?.+?/attachment/([^/]+)/?$] => index.php?attachment=$matches[1]
[(.?.+?)(/[0-9]+)?/?$] => index.php?pagename=$matches[1]&page=$matches[2]
...
WP_Rewrite - “Роутинг”Rewrite Rules filters
1. apply_filters( 'post_rewrite_rules', $post_rewrite );
2. apply_filters( 'date_rewrite_rules', $date_rewrite );
3. apply_filters( 'root_rewrite_rules', $root_rewrite );
4. apply_filters( 'comments_rewrite_rules', $comments_rewrite );
5. apply_filters( 'search_rewrite_rules', $search_rewrite );
6. apply_filters( 'author_rewrite_rules', $author_rewrite );
7. apply_filters( 'page_rewrite_rules', $page_rewrite );
8. apply_filters( $permastructname . '_rewrite_rules', $rules );
9. apply_filters( 'rewrite_rules_array', $this->rules );
WP_Rewrite - “Роутинг”WP_Rewrite::add_rule ()
// http://example.com/properties/123/
add_action( 'init', '_rewrites_init' );
function _rewrites_init() {
add_rewrite_rule(
'properties/([0-9]+)/?$',
'index.php?pagename=properties&property_id=$matches[1]', 'top' );
}
add_filter( 'query_vars', '_query_vars' );
function _query_vars( $query_vars ) {
$query_vars[] = 'property_id';
return $query_vars;
}
WP_Rewrite - “Роутинг”WP_Rewrite::add_permastruct ()
<?php
class WP_Rewrite {
/**
* Add a new permalink structure.
*/
public function add_permastruct( $name, $struct, $args = array() ) {
...
$this->extra_permastructs[ $name ] = $args;
}
...
?>
WP_Rewrite - “Роутинг”WP_Rewrite::add_permastruct ()
<?php
// http://example.com/au/some-prize-category/some-competition/
$wp_rewrite->add_rewrite_tag('%competition%', '([^/]+)', 'competition=');
$wp_rewrite->add_rewrite_tag('%prize_category%', '([^/]+)', 'prize_category=');
$wp_rewrite->add_permastruct(
'competition',
'/au/%prize_category%/%competition%/',
array( 'walk_dirs' => false ));
?>
WP_Query - The Query classWordPress environment setup class
class WP {
/**
* Sets up all of the variables required by the WordPress environment.
* @param string|array $query_args Passed to {@link parse_request()}
*/
public function main($query_args = '') {
$this->init();
$this->parse_request($query_args);
$this->send_headers();
$this->query_posts();
$this->handle_404();
$this->register_globals();
do_action_ref_array( 'wp', array( &$this ) );
}
...
WP_Query - The Query classThe Main Query
/**
* WordPress environment setup class.
*/
class WP {
/**
* Set up the Loop based on the query variables.
*/
public function query_posts() {
global $wp_the_query;
$this->build_query_string();
$wp_the_query->query($this->query_vars);
}
...
WP_Query - The Query class
class WP_Query {
/**
* Sets up the WordPress query by parsing query string.
* @return array List of posts.
*/
public function query( $query ) {
$this->init();
$this->query = $this->query_vars = wp_parse_args( $query );
return $this->get_posts();
}
/**
* Retrieve the posts based on query variables.
* @return array List of posts.
*/
public function get_posts() {
...
do_action_ref_array( 'pre_get_posts', array( &$this ) );
...
WP_Query - The Query classQuery vars
/**
* Retrieve variable in the WP_Query class.
*
* @see WP_Query::get()
* @uses $wp_query
*
* @return mixed
*/
function get_query_var( $var, $default = '' ) {
global $wp_query;
return $wp_query->get( $var, $default );
}
Чёрный пояс!
Это всё?
Это начало :)
Highload & Perfomance,
Architecture, Supportability, Usability,
UNIX/Linux CLI, Stability, Unit
Testing, Continius integration,
… Communication skills,
Time management
Вопросы?
Спасибо!