En esta presentación se recorren algunos de los puntos más relevantes sobre las mejores prácticas en el desarrollo para WordPress, basándonos en “WordPress Best Practices” de 10up veremos algunos ejemplos y consejos que nos permitirán construir proyectos con mejor rendimiento, seguridad y mantenibilidad
1. Lucy Tomas • @_lucymtc • #WCAlicante2017
W O R D P R E S S
M E J O R E S P R Á C T I C A S
C O - O R G A N I Z A D O R A W O R D P R E S S V A L E N C I A
Y W O R D P R E S S D E N I A
A U T O R A P L U G I N S E N R E P O S I T O R I O W O R D P R E S S . O R G
L U C Y T O M A S , W E B E N G I N E E R @ 1 0 U P
W O R D P R E S S E N G I N E E R I N G B E S T P R A C T I C E S
2. Í N D I C E
Sobre 10up
Rendimiento
Seguridad
Librerías y frameworks
Patrones de diseño,
documentación y estilo
Algunas buenas prácticas en
JavaScript
3. Lucy Tomas • @_lucymtc • #WCAlicante2017
S O B R E 1 0 U P
USA Canada Europe India
4. Lucy Tomas • @_lucymtc • #WCAlicante2017
S O B R E 1 0 U P
https://10up.github.io/Engineering-Best-Practices
5. Lucy Tomas • @_lucymtc • #WCAlicante2017
S O B R E 1 0 U P
6. Lucy Tomas • @_lucymtc • #WCAlicante2017
R E N D I M I E N T O
7. Lucy Tomas • @_lucymtc • #WCAlicante2017
WP_Object_Cache y Transients API
R E N D I M I E N T O
8. R E N D I M I E N T O C A C H E Y T R A N S I E N T S
9. R E N D I M I E N T O C A C H E Y T R A N S I E N T S
10. Lucy Tomas • @_lucymtc • #WCAlicante2017
wp_cache_set() / wp_cache_get()
R E N D I M I E N T O C A C H E Y T R A N S I E N T S
11. Lucy Tomas • @_lucymtc • #WCAlicante2017
R E N D I M I E N T O C A C H E Y T R A N S I E N T S
12. Lucy Tomas • @_lucymtc • #WCAlicante2017
R E N D I M I E N T O
admin-ajax.php
C A C H E Y T R A N S I E N T S
13. Lucy Tomas • @_lucymtc • #WCAlicante2017
WP_Query vs. get_posts() vs. query_posts()
R E N D I M I E N T O
hook pre_get_posts
W P _ Q U E R Y
14. Lucy Tomas • @_lucymtc • #WCAlicante2017
Argumentos de WP_Query que optimizan la consulta
R E N D I M I E N T O
'no_found_rows' => true ( evita SQL_CALC_FOUND_ROWS )
'update_post_term_cache' => false
'update_post_meta_cache' => false
'fields' => 'ids'
Evitar
'posts_per_page' => -1
'post__not_in'
W P _ Q U E R Y
15. Lucy Tomas • @_lucymtc • #WCAlicante2017
R E N D I M I E N T O
wp_options autoload
16. Lucy Tomas • @_lucymtc • #WCAlicante2017
S E G U R I D A D
17. Lucy Tomas • @_lucymtc • #WCAlicante2017
V A L I D A R , S A N E A R , E S C A P A R
S E G U R I D A D
18. Lucy Tomas • @_lucymtc • #WCAlicante2017
S E G U R I D A D
V A L I D A R , S A N E A R
V A L I D A R , S A N E A R , E S C A P A R
19. Lucy Tomas • @_lucymtc • #WCAlicante2017
S E G U R I D A D
sanitize_* wp_kses_*
sanitize_text_field(), sanitize_key(), sanitize_email(), sanitize_title(), wp_kses,…….
V A L I D A R , S A N E A R , E S C A P A R
20. Lucy Tomas • @_lucymtc • #WCAlicante2017
V A L I D A R , E S C A P A R
S E G U R I D A D
- Atributos: esc_attr()
- Enlaces: esc_url()
- Traducciones: esc_html_e(), esc_html__() en lugar de _e() y __()
V A L I D A R , S A N E A R , E S C A P A R
21. Lucy Tomas • @_lucymtc • #WCAlicante2017
S E G U R I D A D
L A T E E S C A P I N G
E V I T A R
V A L I D A R , S A N E A R , E S C A P A R
22. Lucy Tomas • @_lucymtc • #WCAlicante2017
S E G U R I D A D
P R E V E N I R I N Y E C C I O N E S S Q L
C O N W P D B P R E P A R E
V A L I D A R , S A N E A R , E S C A P A R
23. Lucy Tomas • @_lucymtc • #WCAlicante2017
S E G U R I D A D
N O N C E S
check_admin_referer, wp_verify_nonce, wp_nonce_field, wp_create_nonce,…….
24. Lucy Tomas • @_lucymtc • #WCAlicante2017
S E G U R I D A D N O N C E S
25. Lucy Tomas • @_lucymtc • #WCAlicante2017
S E G U R I D A D N O N C E S
26. Lucy Tomas • @_lucymtc • #WCAlicante2017
L I B R E R Í A S
Y F R A M E W O R K S
27. E N W O R D P R E S S
9 9 % D E L O Q U E
S E
N E C E S I T A M O S
L I B R E R Í A S / F R A M E W O R K S
Y mucho más…
28. Lucy Tomas • @_lucymtc • #WCAlicante2017
P A T R O N E S D E D I S E Ñ O
D E S I G N P A T T E R N S
29. Lucy Tomas • @_lucymtc • #WCAlicante2017
E S T I L O Y
D O C U M E N T A C I Ó N
30. Lucy Tomas • @_lucymtc • #WCAlicante2017
J A V A S C R I P T
31. Lucy Tomas • @_lucymtc • #WCAlicante2017
J A V A S C R I P T
U S O D E J Q U E R Y M O D E R A D O
32. Lucy Tomas • @_lucymtc • #WCAlicante2017
J A V A S C R I P T J Q U E R Y
V S
33. Lucy Tomas • @_lucymtc • #WCAlicante2017
J A V A S C R I P T J Q U E R Y
V S
34. Lucy Tomas • @_lucymtc • #WCAlicante2017
E V I T A R H A C E R L A M I S M A
S E L E C C I Ó N M Á S D E U N A
V E Z
J A V A S C R I P T
35. Lucy Tomas • @_lucymtc • #WCAlicante2017
J A V A S C R I P T
V S
36. Lucy Tomas • @_lucymtc • #WCAlicante2017
J A V A S C R I P T
C L O S U R E S
E V I T A C O N T A M I N A R E L O B J E T O W I N D O W
L I M I T A N D O E L A L C A N C E D E V A R I A B L E S Y
F U N C I O N E S
37. Lucy Tomas • @_lucymtc • #WCAlicante2017
V S
J A V A S C R I P T C L O S U R E S
38. Lucy Tomas • @_lucymtc • #WCAlicante2017
J A V A S C R I P T C L O S U R E S
39. Lucy Tomas • @_lucymtc • #WCAlicante2017
G R A C I A S
Hinweis der Redaktion
Estas 2 funciones en el core de WP por si solas no hacen nada.
Al instalar un plugin para cache, será el plugin que defina lo que hacen estas funciones.
Si desarrollas un plugin y usas estas funciones estarás haciendo un favor al usuario que tiene configurado un sistema para el cache.
Ejemplo común. En este caso siembre habrá un usuario que se encuentre con este valor de cache vacío, es ese usuario que genera la query y guarda el cache. Para 1 usuario la query es lenta. Hay estrategias más complejas, se puede generar el cache de manera asincrónica en el background.
Nunca asumir que estos objetos estarán en memoria, pueden ser borrados en cualquier momento.
nunca usar transients como manera de almacenar datos que necesita la aplicación.
el tiempo de expiración garantiza un tiempo máximo de su existencia. Sabremos que después de ese tiempo nunca existirá.
En ningún momento se garantiza un tiempo mínimo. puedo poner fecha expiración dentro de 1 año y a los 5 minutos ese transient borrarse por alguna razón.
Ejemplo error común! un plugin premium que guarda las licencias de los usuarios con fecha de expiración en un transient.
transients son excelentes para almacenar datos de API’s de terceros, RSS feeds, etc. siempre será mas rápido hacer las peticiones a nuestra base de datos que a servicios externos.
WP no hace uso del cache en el admin
Rewrite rules API. registrar un endpoint con rewrite add_rewrite_rule()
add_action( 'template_redirect', 'do_api' );
do_api() { if(…){wp_send_json( $response );} }
- usar siempre por lo general WP_query, hace cosas detrás del escenario que otros métodos no hacen. get_posts: 'suppress_filters' => true
- query_posts tiene un uso distinto a get_posts o wp_query. No esta recomendado usar en themes o plugins. Reemplazará la query principal, incluso ejecutándola mas de una vez. usar pre_get_posts para modificar la query principal.
'no_found_rows' => true : Si no se usa paginación evita que WordPress
ejecute SQL_CALC_FOUND_ROWS en la query.
update_post_term_cache: Si no se va a hacer uso de los términos de los posts.
update_post_meta_cache: Si no se va a hacer uso del meta de los posts.
Siempre poner límite que no sea -1. Si nuestra web tiene 100,000 posts acabará rompiendo.
post__not_in : SQL ejecuta NOT IN, lento. Más rápido filtrar los ID’s dentro del loop en PHP.
Esto es algo que se puede olvidar fácilmente.
Por defecto estas funciones guardan la opción con autoload ‘yes’/true.
Esto significa que esa opción se carga de manera automática en cada carga de página.
Si la opción sólo se necesita en una página en concreto -> especificar autoload = false.
NO se puede modificar el valor autoload de una opción existente, hay que borrar la opción y guardarla de nuevo.
Validar: asegurarnos de que lo recibido es lo que esperamos
Sanear = limpiar
Validar datos para asegurarnos que lo que recibimos es lo que esperamos.
Sanear datos para limpiar y asegurar que cumplen con ciertos estándares y criterios.
- Hacer uso de wp_kses de forma moderada. Es una función cara en cuanto a rendimiento se refiere debido al gran número de expresiones regulares que tiene que recorrer.
En 10up seguimos la filosofía de Late Escaping.
Nos aseguramos que no puede pasar nada nunca entre el momento en que guardamos el valor en una variable y el momento en el que se imprime en pantalla.
Lo mismo para escribir en la base de datos, siembre sanear en el último momento.
$wpdb->prepare() = sprintf() llama a mysqli_real_escape_string en cada argumento.
sprintf devuelve un string formateado.
mysqli_real_escape_string escapa caracteres especiales en un string. Escapa ‘ y “ : previene Inyecciones SQL
Con lo que incluye WordPress tenemos el 99% de lo que necesitamos, desde manejo de base de datos, enviar emails, etc. Y esto tanto en PHP como en JavaScript.
Así que en 10up tratamos de no usar librerías y frameworks que WordPress no incluye, aunque sí que se usan algunas frameworks y librerías que son de código abierto como PHPUnit. Para JavaScript por ejemplo usamos jQuery, Underscore, Backbone.
Backbone es un framework para construir aplicaciones JavaScript más complejas y es muy usado en WordPress, especialmente en la librería de imágenes (o biblioteca de medios).
- Aseguran mantenibilidad de un proyecto.
- Estandarizar prácticas de desarrollo permiten a nuevos desarrolladores entrar en el proyecto de manera más sencilla.
Definiendo un nivel de dificultad bajo a la hora de saltar a un proyecto.
En 10up desarrolladores entran y salen de proyectos constantemente. Sería un fracaso si tu código solo lo entiendes tu o unos cuantos, llevaría demasiado tiempo para un nuevo desarrollador nuevo el ajustarse al proyecto.
En 10up revisamos cada línea de código antes de incluirla en un proyecto, tanto si es nuestro como plugins de terceros. En estas revisiones, a parte de seguridad, rendimiento y arquitectura del código, se tiene muy en cuenta la documentación y el estilo.
La regla de oro es que cualquier manager de proyecto debe poder entender lo que hace tu código.
Aunque trabajes sólo, tu futuro YO lo agradecerá.
jQuery nos ayuda a realizar procesos más complejos como pueden ser peticiones en ajax, animaciones. Pero en otras cosas más sencillas puede ser un excesivo.
En JS tenemos que cuidar al igual que en PHP los posibles conflictos con nombres de funciones y variables.
Closure. Actúan como una clase en PHP, nos permite disponer de funciones y variables privadas a las que se pueden acceder solo si las exponemos.