Crear dos páginas y dos entradas que tengan:
Encabezados
Párrafos
Imágenes
En el WP de alwaysdata
Crear dos páginas y dos entradas que tengan:
Encabezados
Párrafos
Imágenes
En el WP de alwaysdata
Una excelente explicación de como funcionan los números en coma flotante:
https://ciechanow.ski/exposing-floating-point/
Y un simulador para experimentar:
<?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: Juan Pablo
*/
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>";
}
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
}
<?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
}
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();
}
/**
* 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');
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");
<?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);