<?php /** * Plugin Name: Importador XML Avanzado * Description: Permite subir un archivo XML desde el panel de administración y genera entradas evitando duplicados. * Version: 1.1 * Author: Tu Nombre */ if ( ! defined( 'ABSPATH' ) ) exit; // seguridad // Menú en administración add_action('admin_menu', 'importador_xml_menu'); function importador_xml_menu() { add_menu_page( 'Importador XML', 'Importador XML', 'manage_options', 'importador-xml', 'importador_xml_page', 'dashicons-database-import' ); } // Página del plugin function importador_xml_page() { ?> <div class="wrap"> <h1>Importador de Entradas desde XML</h1> <h2>Subir XML</h2> <form method="post" enctype="multipart/form-data"> <?php wp_nonce_field('importador_xml_nonce','importador_xml_nonce_field'); ?> <input type="file" name="archivo_xml" accept=".xml" required> <input type="submit" name="subir_xml" class="button button-secondary" value="Subir XML"> </form> <h2>Importar entradas</h2> <form method="post"> <?php wp_nonce_field('importador_xml_nonce','importador_xml_nonce_field'); ?> <input type="submit" name="importar_xml" class="button button-primary" value="Importar desde XML"> </form> </div> <?php // Procesar subida if (isset($_POST['subir_xml']) && check_admin_referer('importador_xml_nonce','importador_xml_nonce_field')) { importador_xml_subir(); } // Procesar importación if (isset($_POST['importar_xml']) && check_admin_referer('importador_xml_nonce','importador_xml_nonce_field')) { importador_xml_procesar(); } } // Subir archivo XML a /uploads/importador-xml/ function importador_xml_subir() { if (!empty($_FILES['archivo_xml']['tmp_name'])) { $upload_dir = wp_upload_dir(); $destino_dir = $upload_dir['basedir'] . '/importador-xml/'; if (!file_exists($destino_dir)) { wp_mkdir_p($destino_dir); } $destino = $destino_dir . 'datos.xml'; if (move_uploaded_file($_FILES['archivo_xml']['tmp_name'], $destino)) { echo "<div class='updated'><p>Archivo subido correctamente: " . esc_html($destino) . "</p></div>"; } else { echo "<div class='error'><p>Error al subir el archivo.</p></div>"; } } } // Procesar archivo XML y crear posts function importador_xml_procesar() { $upload_dir = wp_upload_dir(); $ruta = $upload_dir['basedir'] . '/importador-xml/datos.xml'; if (!file_exists($ruta)) { echo "<div class='error'><p>No se encontró ningún archivo XML en: $ruta</p></div>"; return; } $xml = simplexml_load_file($ruta); if (!$xml) { echo "<div class='error'><p>Error al leer el archivo XML.</p></div>"; return; } $contador = 0; foreach ($xml->item as $item) { $titulo = sanitize_text_field((string) $item->title); $contenido = wp_kses_post((string) $item->body); // Comprobar si ya existe un post con este título $existe = get_page_by_title($titulo, OBJECT, 'post'); if (!$existe) { $nuevo_post = array( 'post_title' => $titulo, 'post_content' => $contenido, 'post_status' => 'publish', 'post_author' => get_current_user_id(), 'post_type' => 'post' ); wp_insert_post($nuevo_post); $contador++; } } echo "<div class='updated'><p>Se importaron $contador nuevas entradas desde el XML.</p></div>"; }
Ejemplo plugin consulta datos externos
Vamos a crear un plugin que consulte datos externos de una API y los muestre vía shortcode
1.- Crear el shortcode
<?php /* Plugin Name: Mostrar datos de una API externa Description: Consulta los datos de una API y los muestra donde yo ponga el shortcode Version: 1.0 Author: Jotapeich */ function mostrar_datos_func( $atts ) { return "Aquí se mostrarán los datos"; } add_shortcode( 'datos_api', 'mostrar_datos_func' );
2.- Obtener los datos de una api externa
<?php /* Plugin Name: Mostrar datos de una API externa Description: Consulta los datos de una API y los muestra donde yo ponga el shortcode Version: 1.0 Author: Jotapeich */ function consultar_api( $cantidad = 5 ) { $url = "https://jsonplaceholder.typicode.com/posts"; // API de ejemplo $response = wp_remote_get( $url ); if ( is_wp_error( $response ) ) { return "<p>Error al consultar la API.</p>"; } $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); if ( ! is_array( $data ) ) { return "<p>Respuesta inválida de la API.</p>"; } } function mostrar_datos_func( $atts ) { consultar_api(); return "Aquí se mostrarán los datos"; } add_shortcode( 'datos_api', 'mostrar_datos_func' );
3.- Formatear los datos que me llegan:
<?php /* Plugin Name: Mostrar datos de una API externa Description: Consulta los datos de una API y los muestra donde yo ponga el shortcode Version: 1.0 Author: Jotapeich */ function consultar_api( $cantidad = 5 ) { $url = "https://jsonplaceholder.typicode.com/posts"; // API de ejemplo $response = wp_remote_get( $url ); if ( is_wp_error( $response ) ) { return "<p>Error al consultar la API.</p>"; } $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); if ( ! is_array( $data ) ) { return "<p>Respuesta inválida de la API.</p>"; } $data = array_slice( $data, 0, intval($cantidad) ); $output = '<table style="border-collapse: collapse; width:100%; border:1px solid #ccc;">'; $output .= '<thead><tr style="background:#f4f4f4;"><th style="padding:8px;border:1px solid #ccc;">ID</th><th style="padding:8px;border:1px solid #ccc;">Título</th><th style="padding:8px;border:1px solid #ccc;">Body</th></tr></thead><tbody>'; foreach ( $data as $item ) { $output .= '<tr>'; $output .= '<td style="padding:8px;border:1px solid #ccc;">' . esc_html($item['id']) . '</td>'; $output .= '<td style="padding:8px;border:1px solid #ccc;">' . esc_html($item['title']) . '</td>'; $output .= '<td style="padding:8px;border:1px solid #ccc;">' . nl2br(esc_html($item['body'])) . '</td>'; $output .= '</tr>'; } $output .= '</tbody></table>'; return $output; } function mostrar_datos_func( $atts ) { return consultar_api(); } add_shortcode( 'datos_api', 'mostrar_datos_func' );
4.- Le voy a poner un parámetro al shortcode
function mostrar_datos_func( $atts ) { $atts = shortcode_atts( array( 'cantidad' => 5, ), $atts, 'mis_datos' ); return consultar_api($atts['cantidad']); }
5.- Vamos a añadir opciones
<?php /* Plugin Name: Mostrar datos de una API externa Description: Consulta los datos de una API y los muestra donde yo ponga el shortcode Version: 1.0 Author: Jotapeich */ function consultar_api( $cantidad = 5 ) { $url = "https://jsonplaceholder.typicode.com/posts"; // API de ejemplo $response = wp_remote_get( $url ); if ( is_wp_error( $response ) ) { return "<p>Error al consultar la API.</p>"; } $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); if ( ! is_array( $data ) ) { return "<p>Respuesta inválida de la API.</p>"; } $data = array_slice( $data, 0, intval($cantidad) ); $output = '<table style="border-collapse: collapse; width:100%; border:1px solid #ccc;">'; $output .= '<thead><tr style="background:#f4f4f4;"><th style="padding:8px;border:1px solid #ccc;">ID</th><th style="padding:8px;border:1px solid #ccc;">Título</th><th style="padding:8px;border:1px solid #ccc;">Body</th></tr></thead><tbody>'; foreach ( $data as $item ) { $output .= '<tr>'; $output .= '<td style="padding:8px;border:1px solid #ccc;">' . esc_html($item['id']) . '</td>'; $output .= '<td style="padding:8px;border:1px solid #ccc;">' . esc_html($item['title']) . '</td>'; $output .= '<td style="padding:8px;border:1px solid #ccc;">' . nl2br(esc_html($item['body'])) . '</td>'; $output .= '</tr>'; } $output .= '</tbody></table>'; return $output; } function mostrar_datos_func( $atts ) { $default_cantidad = get_option( 'asp_cantidad_default', 5 ); $atts = shortcode_atts( array( 'cantidad' => $default_cantidad, ), $atts, 'mis_datos' ); return consultar_api($atts['cantidad']); } add_shortcode( 'datos_api', 'mostrar_datos_func' ); // =========================== // 3. Menú en administración // =========================== function asp_add_admin_menu() { add_menu_page( 'Configuración API', // Título de la página 'Configuración API', // Texto en el menú 'manage_options', // Capacidad requerida 'asp-config', // Slug del menú 'asp_options_page_html', // Callback 'dashicons-admin-generic', // Icono 20 // Posición ); } add_action( 'admin_menu', 'asp_add_admin_menu' ); // =========================== // 4. Registrar ajustes // =========================== function asp_settings_init() { register_setting( 'asp_options_group', 'asp_cantidad_default', array( 'type' => 'integer', 'default' => 5, ) ); add_settings_section( 'asp_section', 'Configuración del shortcode', '__return_false', 'asp_options_group' ); add_settings_field( 'asp_cantidad_default', 'Cantidad por defecto', 'asp_field_cantidad_render', 'asp_options_group', 'asp_section' ); } add_action( 'admin_init', 'asp_settings_init' ); // Campo de formulario function asp_field_cantidad_render() { $valor = get_option( 'asp_cantidad_default', 5 ); echo '<input type="number" name="asp_cantidad_default" value="' . esc_attr( $valor ) . '" min="1" max="50">'; } // =========================== // 5. Página HTML en admin // =========================== function asp_options_page_html() { if ( ! current_user_can( 'manage_options' ) ) { return; } ?> <div class="wrap"> <h1>Configuración de los datos de la api externa</h1> <form action="options.php" method="post"> <?php settings_fields( 'asp_options_group' ); do_settings_sections( 'asp_options_group' ); submit_button(); ?> </form> </div> <?php }
Ejemplo opciones en WordPress
<?php /** * Plugin Name: Contar palabras * Description: Cuenta las palabras que tiene una entrada del blog y lo pone al final * Version: 1.1 * Author: Jotapé */ // Esta función se encarga de contar las palabras y añadirlas function contar_palabras($content){ $ppm=get_option( 'palabras_minuto_default', 200 ); // usamos str_word_count para contar las palabras: se puede mejorar para no contar html o imágenes o etc... $num_palabras=str_word_count($content); // Calculo el tiempo de lectura $tiempo=round($num_palabras/$ppm,1); // Creo el texto a añadir. Como son comillas dobles puedo poner la variable dentro $texto="Número de palabras: <b>$num_palabras</b>. Tiempo estimado de lectura: <b>$tiempo minutos</b>"; // Devuelvo el contenido con el texto anterior. return "<p>$texto</p>$content"; } // Añado el filtro para modificar el contenido add_filter("the_content","contar_palabras"); function ppm_add_admin_menu() { add_menu_page( 'Palabras por minuto', // Título de la página 'Config PPM', // Texto en el menú 'manage_options', // Capacidad requerida 'ppm-config', // Slug del menú 'ppm_options_page_html', // Callback 'dashicons-admin-generic', // Icono 20 // Posición ); } add_action( 'admin_menu', 'ppm_add_admin_menu' ); function ppm_settings_init() { register_setting( 'options_contar_palabras', 'palabras_minuto_default', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 200, ) ); add_settings_section( 'contar_palabras_section', 'Configuración de las palabras por minuto', function() { echo '<p>Configura el valor de las palabras por minuto para estimar el tiempo de lectura.</p>'; }, 'options_contar_palabras' ); add_settings_field( 'palabras_minuto_default', 'Palabras por minuto por defecto', 'asp_field_palabras_render', 'options_contar_palabras', 'contar_palabras_section' ); } add_action( 'admin_init', 'ppm_settings_init' ); function asp_field_palabras_render() { $valor = get_option( 'palabras_minuto_default', 200 ); echo '<input type="number" name="palabras_minuto_default" value="' . esc_attr( $valor ) . '" min="50" max="500">'; } function ppm_options_page_html() { if ( ! current_user_can( 'manage_options' ) ) { return; } ?> <div class="wrap"> <h1>Configuración de las palabras por minuto por defecto</h1> <form action="options.php" method="post"> <?php settings_fields( 'options_contar_palabras' ); do_settings_sections( 'options_contar_palabras' ); submit_button(); ?> </form> </div> <?php }
Ejercicios shortcode
1.- Crear un shortcode llamado ‘cuestionario’ que nos muestre un texto de encabezado que ponga ‘Cuestionario de wwordpress’
2.- Sobre ese shortcode añadir un array de 10 preguntas sobre wordpress. Ejemplo:
$preguntas=[«¿Qué es wp?»,»Desde donde se descarga WP»,»Como se llama el contenido de wp que tiene etiquetas?»]
3.- En el shortcode elegir una pregunta al azar y crear un formulario con la pregunta, un campo para responder y un botón de enviar
4.- Recoger la respuesta y ver si es correcta comparándola con un array de respuestas, ejemplo:
$respuestas=[«CMS»,»wordpress.org»,»Entrada»]
Si la respuesta es correcta indicarlo y si no lo es, también
5.- Nivel Pro: Añadir cuatro respuestas que una sea la correcta y que el usuario la elija.
<?php /* Plugin Name: Cuestionario WP Description: Un pequeño cuestionario para poner a prueba nuestros conocimientos Version: 1.0 Author: Tu Nombre */ add_shortcode("cuestionario","crear_cuestionario"); function crear_cuestionario(){ ob_start(); $respuestas=["CMS","wordpress.org","Entrada"]; if ( isset($_POST['fb_submit']) ) { $respuesta=sanitize_text_field($_POST['respuesta']); $numero=sanitize_text_field($_POST['pregunta']); if ($respuesta==$respuestas[$numero]){ echo "Respuesta correcta ¡Muy bien!"; }else{ echo "Incorrecto, eres un looser"; } } $preguntas=["¿Qué es wp?","Desde donde se descarga WP","Como se llama el contenido de wp que tiene etiquetas?"]; $numero=rand(0,count($preguntas)-1); $pregunta=$preguntas[$numero]; // Formulario HTML ?> <h2><?=$pregunta?></h2> <form method="post"> <input type="hidden" name="pregunta" value="<?=$numero?>"/> <p> <label for="fb_titulo">Respuesta:</label><br> <input type="text" name="respuesta" id="respuesta" required style="width:100%;"> </p> <p> <input type="submit" name="fb_submit" value="enviar respuesta"> </p> </form> <?php return ob_get_clean(); }
Versión PRO
<?php /* Plugin Name: Cuestionario WP Description: Un pequeño cuestionario para poner a prueba nuestros conocimientos Version: 1.0 Author: Tu Nombre */ add_shortcode("cuestionario","crear_cuestionario"); function crear_cuestionario(){ ob_start(); $cuestionario=[ ["pregunta"=>"¿Qué es wordpress?", "respuestas"=>["CMS","Web","La palabra de la prensa","No tengo ni idea"]], ["pregunta"=>"¿Desde donde se descarga WP?", "respuestas"=>["wordpress.org","Un sitio pirata","Mis descargas.com","Tengo miedo de descargar cosas"]], ["pregunta"=>"¿Cómo se llama el contenido que tiene etiquetas?", "respuestas"=>["Entradas","Etiquetometro","Páginas","Me llamo Ralph"]], ]; if ( isset($_POST['fb_submit']) ) { $correcta=sanitize_text_field($_POST['correcta']); $respuesta=sanitize_text_field($_POST['respuesta']); if ($respuesta==$correcta){ echo "Respuesta correcta ¡Muy bien!"; }else{ echo "Incorrecto, eres un looser"; } } $elegida=$cuestionario[array_rand($cuestionario)]; $correcta=$elegida['respuestas'][0]; shuffle($elegida['respuestas']); // Formulario HTML ?> <h2><?=$elegida['pregunta']?></h2> <form method="post"> <input type="hidden" name="correcta" value="<?=$correcta?>"/> <p> <label for="fb_titulo">Respuesta:</label><br> <?php foreach($elegida['respuestas'] as $respuesta){ ?> <label><input type="radio" name='respuesta' value='<?=$respuesta?>'> <?=$respuesta?></label> <?php s } ?> </p> <p> <input type="submit" name="fb_submit" value="enviar respuesta"> </p> </form> <?php return ob_get_clean(); }
Ejemplo shortcode
/** * Shortcode: [form_borrador] */ function fb_formulario_shortcode() { ob_start(); // Procesar el formulario si se envió if ( isset($_POST['fb_submit']) ) { $titulo = sanitize_text_field($_POST['fb_titulo']); $contenido = sanitize_textarea_field($_POST['fb_contenido']); // Crear el borrador $nuevo_post = array( 'post_title' => $titulo, 'post_content' => $contenido, 'post_status' => 'draft', 'post_type' => 'post' ); $post_id = wp_insert_post($nuevo_post); if ($post_id) { echo "<p style='color:green;'><strong>✅ Borrador creado correctamente.</strong></p>"; } else { echo "<p style='color:red;'><strong>❌ Hubo un error al crear el borrador.</strong></p>"; } } // Formulario HTML ?> <form method="post"> <p> <label for="fb_titulo">Título:</label><br> <input type="text" name="fb_titulo" id="fb_titulo" required style="width:100%;"> </p> <p> <label for="fb_contenido">Contenido:</label><br> <textarea name="fb_contenido" id="fb_contenido" rows="6" required style="width:100%;"></textarea> </p> <p> <input type="submit" name="fb_submit" value="Crear borrador"> </p> </form> <?php return ob_get_clean(); } add_shortcode('form_borrador', 'fb_formulario_shortcode');
Ejercicio plugins
Crear un plugin que al final de cada entrada nos diga el número de palabras que tiene.
Es decir, tendremos que modificar el contenido (the_content) añadiendo al final el número de palabras
Pasos a realizar:
1.- Crear los archivos de plugin
2.- Conseguir que al final de cada entrada ponga ‘hola’ y comprobar que funciona
3.- Hacer un código que cuente las palabras de un texto en php y añadir ese número al final.
<?php /** * Plugin Name: Contar palabras * Description: Cuenta las palabras que tiene una entrada del blog y lo pone al final * Version: 1.1 * Author: Jotapé */ // Esta función se encarga de contar las palabras y añadirlas function contar_palabras($content){ // usamos str_word_count para contar las palabras: se puede mejorar para no contar html o imágenes o etc... $num_palabras=str_word_count($content); // Calculo el tiempo de lectura $tiempo=round($num_palabras/200,1); // Creo el texto a añadir. Como son comillas dobles puedo poner la variable dentro $texto="Número de palabras: <b>$num_palabras</b>. Tiempo estimado de lectura: <b>$tiempo minutos</b>"; // Devuelvo el contenido con el texto anterior. return "<p>$texto</p>$content"; } // Añado el filtro para modificar el contenido add_filter("the_content","contar_palabras");
Ejemplo plugin registro entradas
<?php /** * Plugin Name: Registro entradas * Plugin URI: https://trifulcas.com * Description: Un plugin que registra en un archivo cuando se publica una entrada * Version: 1.0 * Author: Jotapé * Author URI: https://trifulcas.com * License: GPL2 */ function registrar($id,$post){ // Poner el código para escribir en el archivo $texto=$post->post_title." | ".$post->post_author.PHP_EOL; $archivo = plugin_dir_path( __FILE__ ) . 'registro.txt'; file_put_contents( $archivo, $texto, FILE_APPEND | LOCK_EX ); } add_action('publish_post','registrar',10,2);
Ejemplo plugin wp
<?php /** * Plugin Name: Mi Plugin Personalizado * Plugin URI: https://tusitio.com * Description: Un plugin simple para demostrar cómo crear uno. * Version: 1.0 * Author: Tu Nombre * Author URI: https://tusitio.com * License: GPL2 */ function mensaje_final_personalizado($content) { $aforismos = [ "La vida es aquello que te sucede mientras estás ocupado haciendo otros planes. – John Lennon", "El conocimiento es poder. – Francis Bacon", "Pienso, luego existo. – René Descartes", "La imaginación es más importante que el conocimiento. – Albert Einstein", "El hombre está condenado a ser libre. – Jean-Paul Sartre", "Solo sé que no sé nada. – Sócrates", "No hay camino para la paz, la paz es el camino. – Mahatma Gandhi", "El secreto de la felicidad no es hacer siempre lo que se quiere, sino querer siempre lo que se hace. – León Tolstói", "La esperanza es el sueño del hombre despierto. – Aristóteles", "El que tiene un porqué para vivir puede soportar casi cualquier cómo. – Friedrich Nietzsche" ]; $aforismo=$aforismos[mt_rand(0,9)]; if (is_single()) { $content .= '<p style="color: green;">'.$aforismo.'</p>'; } return $content; } add_filter('the_content', 'mensaje_final_personalizado');