Crear Plugin de WordPress desde Cero

58
Crear un WordPress Plugin desde Cero Eduardo Turiño Programador Web en Bilbao @etmsoft linkedin.com/in/eduardoturino

Transcript of Crear Plugin de WordPress desde Cero

Page 1: Crear Plugin de WordPress desde Cero

Crear un WordPress Plugin desde Cero

Eduardo TuriñoProgramador Web

en Bilbao

@etmsoft

linkedin.com/in/eduardoturino

Page 2: Crear Plugin de WordPress desde Cero

¿Qué veremos? @etmsoft - #WPBilbao

- Conceptos básicos

- Buenas prácticas en el desarrollo de plugins

- Archivos y formato necesarios- Bloque de definición del plugin.

Atributos.- readme.txt- screenshots.png

- Plugin “Share-now” versión no OOP

- Plugin “Share-now” versión OOP

- Subir plugin al repositorio de wordpress.org

Requisitos

- Conocimientos medios en- PHP- OOP- HTML- CSS- Javascript / jQuery / Ajax

- Ganas de aportar

- De vez en cuando un Tweet con el hashtag #WPBilbao

Page 3: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Hooks

Actions Filters

Page 4: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoHooks - Acciones

<?php// Añade código adicional al comportamiento habitual de WordPressadd_action('action_name', 'callback_function ');

add_action( 'save_post', 'notificar_guardado', 10, 2 );function notificar_guardado( $post_id, $post ) {

// Notificar por email que se ha guardado el postwp_mail('[email protected] ', 'Se ha guardado el post' . $post_id);

}

add_action( 'wp_head', 'hacer_web_responsive' );function hacer_web_responsive() {

echo '<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />';

}?>

Page 5: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoHooks - Filtros

<?php// Cambia el valor de los datos antes de mostrarlos o guardarlos en BDadd_filter('filter_name', 'callback_function ');

add_filter( 'body_class', 'add_slug_body_class' );function add_slug_body_class( $classes ) {

global $post;if ((is_single() || is_page()) && isset( $post ) ) {

$classes[] = $post->post_type . '-' . $post->post_name;}return $classes;

}?>

// Genera: <body class="page page-contacto">

Page 6: Crear Plugin de WordPress desde Cero

<?php /* Plugin Name: CTA Compartir Plugin URI: http://wpbilbao.es Description: Añade un texto de llamada a la acción para compartir o comentar una entrada. Version: 0.1 Author: Eduardo Turiño Author URI: http://etmsoft.com */

add_filter( 'the_content', 'cta_compartir' );

function cta_compartir( $content ) {

$cta_compartir = '<p>Si te ha gustado este artículo comentanos que te ha parecido o compártelo en las redes sociales</p>';

$content = apply_filters('the_content', $content) . $cta_compartir;return $content;

} ?>

@etmsoft - #WPBilbaoHooks - Ejemplo de plugin con filtro

Page 7: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Conceptos básicos

Page 8: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoConceptos básicos - Mínimo requerido

wp-content/plugins/ [nombre-plugin]/nombre-plugin.php

<?php/*Plugin Name: Plugin de Ejemplo*/

?>

Page 9: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoConceptos básicos - Cabecera completa<?php

/*Plugin Name: Mi PluginPlugin URI: http://etmsoft.com/plugins/mi-plugin (Puede estar en WordPress.org o tu sitio)Description: Aquí va la descripción breve del plugin (no más de 140 caracteres)Version: 1.5Author: Eduardo Turiño (pueden haber varios autores)Author URI: http://etmsoft.comLicense: GPL2License URI: https://www.gnu.org/licenses/gpl-2.0.htmlDomain Path: /languagesText Domain: mi-plugin

// Recomendado incluir descripción de la licencia:

{Plugin Name} is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or any later version.

{Plugin Name} is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with {Plugin Name}. If not, see {License URI}.

*/

Page 10: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoConceptos básicos - readme.txt=== Share Now ===Contributors: (Debe ser una lista de Id de usuarios de wordpress.org)Donate link: http://etmsoft.com/Tags: share, social buttonsRequires at least: 3.0.1Tested up to: 4.4Stable tag: 4.3License: GPLv2 or laterLicense URI: http://www.gnu.org/licenses/gpl-2.0.html

Aquí una breve descripción del plugin. Esto no debería ser más de 150 caracteres. Sin etiquetado.

== Descripción ==

Esta es la descripción larga. No hay límite, y se puede utilizar etiquetado (también en las secciones siguientes). Por compatibilidad con versiones anteriores, si esta sección no se indica, toda la descripción corta será mostrada y el etiquetado será válido.

== Instalación ==

Esta sección describe cómo instalar el plugin y los pasos para hacerlo funcionar.

1. Paso 11. Paso 2

Page 11: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoConceptos básicos - Licencia GPLv2

You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.

Eres libre de modificar, reutilizar todo o parte del código de un plugin o tema para tus propios proyectos, incluso si a ese proyecto le sacas rendimiento económico.

If the program dynamically links plug-ins, and they make function calls to each other and share data structures, we believe they form a single program, which must be treated as an extension of both the main program and the plug-ins. This means the plug-ins must be released under the GPL....

Sólo por el hecho de que un plugin o tema utilice funciones de WordPress, ya se adhiere a la licencia GPL, porque será tratado como una extensión del software base, que es el WordPress, que está bajo dicha licencia.

Por tanto, aunque sea un Plugin / Tema comprado:- Puedes eliminar enlaces de referencias al autor.- No se pueden combinar licencias Creative Commons + GPL- Puedes instalarlo varias veces

Page 12: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoConceptos básicos - Activación / Desactivación

<?php/*Plugin Name: Mi Plugin...*/

register_activation_hook( __FILE__, 'miplugin_activacion' ); function miplugin_activacion() {

// Acciones a realizar durante la activación// ...

}

register_deactivation_hook( __FILE__, 'miplugin_desactivacion' );function miplugin_desactivacion() {

// Borrar los permalinksflush_rewrite_rules();

}

?>

Page 13: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoConceptos básicos - Desinstalación. 2 Opciones<?php

/*Plugin Name: Mi Plugin*/register_uninstall_hook( __FILE__, 'miplugin_desinstalar' );

?>

uninstall.php

<?php// Si uninstall.php no es llamado // desde WordPress, salirif ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) {

exit();}

delete_option( 'miplugin_opciones' );

// Para opciones en un WordPress Multisitedelete_site_option( 'miplugin_opciones' );

// Eliminar tabla de la base de datosglobal $wpdb;$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}miplugin" );

?>

Page 14: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoConceptos básicos - Desactivación vs Desinstalación

Escenario Hook de Desactivación ‘Hook’ de Desinstalación

Eliminar opciones del plugin

No Sí

Limpiar caché de objetos generados por el plugin

Sí No

Page 15: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Mejores prácticas

Page 16: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoMejores Prácticas - Prefijos, Condicionales y Carpetas

<?phpif ( !function_exists('miplugin_init' ) ) {

function miplugin_init() { register_setting( ' miplugin_setting_example', 'foo' ); register_setting( ' miplugin_setting_demo', 'bar' ); }

}

if ( is_admin() ) {// Estamos en modo admin (en el backend)require_once( dirname(__file__).'/admin/myplugin_admin.php' );

}?>

/mi-plugin mi-plugin.php /images uninstall.php

/assets /includes /admin /settings /js /css

Page 17: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoMejores Prácticas - Arquitectura

Enfoques

1. Un único archivo de plugin, con funciones. Hello Dolly 2. Un único archivo con una clase y métodos. ej. Update from Bottom3. Un archivo principal de plugin y varios archivos con clases, cada una realizando su función.

Implementación de patrones OOP y organización de código

Ian Dunn de Automattic - Arquitectura MVC en Plugins

Page 18: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoMejores Prácticas - Arquitectura

Page 19: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoMejores Prácticas - Arquitectura: Plugin multiclass

plugin.php

Mi_Plugin_Activator

Mi_Plugin_Deactivator

Mi_Plugin

Mi_Plugin_Loader

add_action();add_filter();

Mi_Plugin_Public

Mi_Plugin_Admin

Mi_Plugin_i18n

uninstall.php

Page 20: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

En la mente del novato hay muchas posibilidades,

en la del experto hay pocas. - Shunryu Suzuki

Page 21: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Seguridad

Page 22: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoSeguridad - Roles y Capabilities de usuarios<?php

http://misitio.com/noticias?accion=eliminar&id_noticia=5

if ( isset($_REQUEST['accion']) && $_REQUEST['accion']=='eliminar' ) {add_action('init', 'miplugin_borrar_noticia');

}

function miplugin_borrar_noticia() {

if ( ! current_user_can( 'edit_others_posts' ) )return;

// Obtener el ID de la noticia.$id_noticia = (isset($_REQUEST['id_noticia'])?get_post((int)$_REQUEST['id_noticia']):false; // No es un post? Sintiéndolo mucho..if ( empty($id_noticia) )

return; // Borrar noticiawp_trash_post( $id_noticia );

}?>

Page 23: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoSeguridad - Validación de datos

Niveles de validación:

1. Javascripta. Campos requeridos dejados en blanco.b. Formatos de número (teléfonos, código postal, etc.)c. Campos de cantidad > 0

2. Funciones PHPa. isset() y empty(): la variable existe y no está en blanco.b. mb_strlen() o strlen() : longitud de caracteres.c. preg_match(), strpos() : buscar ocurrencias de una cadena dentro de otra.d. count(): elementos de un array()e. in_array() : chequea si un elemento existe en un array()

3. Funciones WordPressa. is_email() : chequea si un email es válido.b. term_exists() : chequea si una etiqueta, categoría o taxonomía existe.c. username_exists() : chequea si un usuario existe.d. wp_validate_auth_cookie() : valida la cookie de autenticación.e. Familia de funciones *_exists(), *_validate(), is_*()

Page 24: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoSeguridad - SanitizaciónFunciones de sanitización

● Chequea código UTF-8 no válido.● Convierte el ‘<’ en una entidad &lt;● Elimina etiquetado HTML● Eliminar cambios de línea, tabulaciones y espacios en blanco

extras● Eliminar octetos ( 0x6F7395 )

<input id="title" type="text" name="title" />

<?php$title = sanitize_text_field( $_POST['title'] );update_post_meta( $post->ID, 'title', $title );

?>

sanitize_email()sanitize_file_name()sanitize_html_class()sanitize_key()sanitize_meta()sanitize_mime_type()sanitize_option()sanitize_sql_orderby()sanitize_text_field()sanitize_title()sanitize_title_for_query()sanitize_title_with_dashes()sanitize_user()esc_url_raw()wp_filter_post_kses()wp_filter_nohtml_kses()

Page 25: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoSeguridad - Data output// Funciones esc_*();

<h4><?php echo esc_html( $title ); ?></h4>

<a href="#" onclick="<?php echo esc_js( $custom_js ); ?>">Click me</a>

<ul class="<?php esc_attr( $list_class ); ?>">

// Tip: No usar echo directamente, usar las funciones esc_

esc_html__() esc_html_e()esc_html_x() esc_attr__()esc_attr_e() esc_attr_x()

// Output con algunas etiquetas permitidas: wp_kses()

$html_permitido = array( echo wp_kses( $custom_content, $html_permitido );'a' => array(

'href' => array(),'title' => array()

),'br' => array(),'em' => array(),'strong' => array(),

);

Page 26: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoSeguridad - Nonces (Number + Once)HTML

// Número de un sólo uso

<form method="post"><!-- some inputs here ... --><?php wp_nonce_field( 'accion_del_formulario', 'campo_verificacion' ); ?>

</form>

<?phpif ( ! isset( $_POST['campo_verificacion'] ) || ! wp_verify_nonce( $_POST['campo_verificacion'], 'accion_del_formulario' )

) {

print 'Lo sentimos, el formulario no ha sido verificado.';exit;

} else { // Procesar los datos de formulario}

?>

Page 27: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Nunca confíes en el usuario, ni siquiera

cuando el usuario eres tú.

Page 28: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Menús de administración

Page 29: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoMenús de administración<?php

add_action( 'admin_menu', 'mi_plugin_menu' );function mi_plugin_menu() {

// Añadir página add_menu_page (

'Título de página','Título en el menú','manage_options','menu-slug','mi_plugin_function_menu','dashicons-*',int_posicion_menu

);

// Añadir subpágina add_submenu_page(

'menu-slug', 'Título de página', 'Título en el submenú', 'manage_options', 'submenu-slug', 'mi_plugin_function_submenu' );

}?>

add_dashboard_page()add_posts_page()add_media_page()add_links_page()add_pages_page()add_comments_page()add_theme_page()add_plugins_page()add_users_page()add_management_page()add_options_page()

Page 30: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Shortcodes

Page 31: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoShortcodes

<?phpadd_shortcode( 'hello-dolly', ' hello_dolly_shortcode' );function hello_dolly_shortcode() {

return "Hello Dolly";}[hello-dolly]

add_shortcode( 'link', ' link_shortcode' );function link_shortcode( $atts, $content = null ) {

$a = shortcode_atts( array(

'color' => 'blue', 'href' => '#', 'target' => '_self' ), $atts

);return '<a style="color:'.$a['color'].'" href="'.$a['href'].'"

target="'.$a['target'].'">'.$content.'</a>';}[link color="green" href="http://wpbilbao.es" target="_blank"]Este es un

texto verde con que abre en wpbilbao en una ventana nueva[/link]?>

Page 32: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Valores de configuración

Page 33: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoValores de configuración

<?php// Guarda en la tabla wp_options

$array_de_opciones = array('nombre' => 'Eduardo','apellidos' => 'Turiño','color_favorito' => 'azul'

);update_option( 'mi_plugin_options', $array_de_opciones );

$array_de_opciones = get_option( 'mi_plugin_options' );

$nombre = $array_de_opciones[ 'nombre' ];$apellidos = $array_de_opciones[ 'apellidos' ];$color_favorito = $array_de_opciones[ 'color_favorito' ];

?>

Page 34: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

JavaScript, AJAX & jQuery

Page 35: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoAjax - Backend

<?phpadd_action('admin_enqueue_scripts', 'mi_plugin_admin_scripts');function mi_plugin_admin_scripts( $hook ) {

wp_enqueue_script( ' mi_plugin_script', plugins_url('/js/mi-plugin-backend.js', __FILE__), array

('jquery') );

wp_localize_script( ' mi_plugin_script', 'AjaxObject', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );

}

add_action('wp_ajax_ mi_plugin_guardar', 'mi_plugin_guardar_formulario' );

function mi_plugin_guardar_formulario() {parse_str( $_POST['data'], $data );update_option( 'mi_plugin_options', $data );

}?>

Page 36: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoAjax - /js/mi-plugin-backend.js

(function ($) {

$(window).ready(function() {

$('.boton-enviar').on( 'click', function(event) {$.ajax({

type: 'POST', // Enviar datos por POSTurl: AjaxObject.ajaxurl, // admin-ajax.phpdata: {

'action':'mi_plugin_guardar_formulario', 'data':$('#formulario').serialize()

},success: function(data){ // Guardado correctamente.

// Mostrar mensaje “guardado” }});

});});

});

}(jQuery));

Page 37: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Metadatos

Page 38: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Custom Post Types

Page 39: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Taxonomías

Page 40: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Usuarios

Page 41: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Cron

Page 42: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

generatewp.com

Page 43: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Internacionalización

Page 44: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoInternacionalización<?php

/*Plugin Name: Mi Plugin...Domain Path: /languagesText Domain: mi-plugin

?>

/languagesmi-plugin.potmi-plugin.momi-plugin-es_ES.pomi-plugin-es_ES.mo

mi-plugin.pot

"Project-Id-Version: Mi Plugin\n""POT-Creation-Date: 2016-03-15 23:55+0100\n""Language-Team: ETMSOFT <[email protected]>\n""Language: English\n""Content-Type: text/plain; charset=UTF-8\n""X-Generator: Poedit 1.5.7\n""X-Poedit-KeywordsList: __;_e\n""X-Poedit-SearchPath-0: ..\n"

#: ../mi-plugin-backend.php:14 msgid "Settings"msgstr ""

mi-plugin-backend.php(línea 14): __('Settings', 'mi-plugin');

poedit.net

Page 45: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

Publicar en wordpress.org/plugins

Page 46: Crear Plugin de WordPress desde Cero

Publicar Plugins - Requisitos @etmsoft - #WPBilbao

1. Licencia: GPLv22. Usar Subversion3. readme.txt4. No “trialware” (plugins que dejan de funcionar pasado

un tiempo)5. No “serviceware” (plugins que hacen referencia a SaaS,

servicios en la nube)6. …wordpress.org/plugins/about/guidelines/

Page 47: Crear Plugin de WordPress desde Cero

Publicar Plugins - Pasos @etmsoft - #WPBilbao

1. Solicitud: wordpress.org/plugins/add/ 2. Una vez aceptado: plugins.svn.wordpress.org/mi-plugin/

a. Cliente subversion, ej. Tortoise.b. Hacer ‘checkout’ en una subcarpeta ej. _wordpressorg

/mi-plugin/_wordpressorg

/tags/assets/trunk

1.0 después del checkout1.52.0

/branches/admin

/js /css

/images/includes/settingsmi-plugin.php

uninstall.php

tortoisesvn.net

Page 48: Crear Plugin de WordPress desde Cero

Publicar plugin en el repositorio. @etmsoft - #WPBilbao

1.- Checkout

2.- Copiar plugin en trunk3.- Commit (upload)

Page 49: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoPublicar plugin en el repositorio. <?php

/*Plugin Name: Mi PluginPlugin URI: http://etmsoft.com/plugins/mi-plugin (Puede estar en WordPress.org o tu sitio)Description: Aquí va la descripción breve del plugin (no más de 140 caracteres)Version: 1.5Author: Eduardo Turiño (pueden haber varios autores)Author URI: http://etmsoft.comLicense: GPL2License URI: https://www.gnu.org/licenses/gpl-2.0.htmlDomain Path: /languagesText Domain: mi-plugin

?>

readme.txt

=== Share Now === == Changelog ==Contributors: (Lista de Id de usuarios de wordpress.org) = 1.0 =Donate link: http://etmsoft.com/ * Primera versión.Tags: share, social buttons * Otro cambio.Requires at least: 3.0.1 = 1.5 =Tested up to: 4.4 * Siguiente versiónStable tag: 1.5 * Otro cambioLicense: GPLv2 or laterLicense URI: http://www.gnu.org/licenses/gpl-2.0.html

Page 50: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoPublicar plugin en el repositorio.

Page 51: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbaoPublicar plugin en el repositorio.

Page 52: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

‘Share Now’ procedural / funcional

(no OOP)

Page 53: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

WordPress Plugin Boilerplate

wppb.io

Page 54: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

‘Share Now’ OOP

Page 55: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

code.org

Page 58: Crear Plugin de WordPress desde Cero

@etmsoft - #WPBilbao

...y ahora vas y lo tuiteas