Comprender las bases y el punto de partida

1

Bienvenida y recomendaciones

2

¿Cómo es un entorno de desarrollo profesional en WordPress?

3

Presentación del proyecto y repaso del curso de fundamentos

Crear Post Types y Archivos

4

¿Cómo se crea y se personaliza una categoría en WordPress?

5

Creemos la UI de un archivo en la web

6

¿Por qué es importante la navegabilidad de la web y cómo se mejora?

7

¿Qué es un Post Type y cómo se pueden personalizar los diferentes tipos?

8

¿Cómo creamos la UI de un Post Type personalizado?

9

Construyamos un loop personalizado

10

¿Qué es una taxonomía y cómo se registra una nueva?

11

¿Qué es un page template y cómo se utiliza?

Utilizar AJAX

12

¿Cómo funcionan los emails en WordPress?

13

¿Cómo utilizar AJAX dentro de WordPress?

14

Empecemos a construir un filtro dinámico para la web

15

Completemos la función AJAX para darle vida a nuestro filtro

La REST-API de WordPress

16

¿Cómo se utiliza la REST-API de WordPress?

17

¿Qué son y cómo funcionan los endpoints?

18

Hagamos el primer llamado a la API

Utilizar Bloques

19

¿Qué es un bloque de Gutenberg?

20

Creando un bloque nativo con React

21

Optimicemos el bloque con componentes de WordPress

22

Creemos el primer bloque dinámico

23

Mejorando la experiencia del usuario en Gutenberg con SSR (Server Side Render)

24

Creando bloques con ACF Pro

25

Crea un bloque igual al de ACF pero de forma nativa

Deployment

26

¿Cómo se lleva un sitio a producción?

27

¿Cómo podemos optimizar la indexación y el SEO de nuestro sitio?

28

¿Cómo defiendo a mi sitio de ataques externos y lo hago más seguro?

Finalizar el Curso

29

Conclusiones

Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Completemos la función AJAX para darle vida a nuestro filtro

15/29
Recursos

Aportes 31

Preguntas 8

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Revisen el repositorio esta desactualizado, y al parecer tengo el mismo error que todos.

Saludos a todos,
Seguí los pasos de la clase y me da un “Fatal error: Cannot use empty list in …\Platzigifts\wp-content\themes\platzigifts\functions.php on line 121
Ha habido un error crítico en tu web.”

El código es:

function pgFiltroProductos() {
	$args = array(
		'post_type' => 'producto',
		'posts_per_page' => -1,
		'order' => 'ASC',
		'orderby' => 'title'
	);

	if ($_POST['categoria']) {
		$args['tax_query'] = array(
			array(
				'taxonomy' => 'categoria-productos',
				'field' => 'slug',
				'terms' => $_POST['categoria']
			)
		);
	}
	
	$productos = new WP_Query($args);

	if ($productos->have_posts()){
		$return = array();
		while($productos->have_posts()) {
			$productos->the_post();
			return[] = array(
				'imagen' => get_the_post_thunbnail(get_the_id(), 'large'),
				'link' => get_the_permalink(),
				'titulo' => get_the_title() // Aquí es la línea 121
			);
		}
		wp_send_json($return);
	};
}

add_action("wp_ajax_nopriv_pgFiltroProductos", "pgFiltroProductos");
add_action("wp_ajax_pgFiltroProductos", "pgFiltroProductos");
?>

No encuentro la pestaña “Archivos y Enlaces” para verificar el código, si lo tienen tal como está en la clase me lo alcanzan para comparar, gracias.

Completemos la función AJAX para darle vida a nuestro filtro


Para poder hacer cosas con AJAX en Wordpress usaremos algunas funciones y cosas en particular.

Para trabajar con AJAX, en el archivo de functions.php y en la misma función donde registramos nuestro CSS y JS, colocamos la siguiente función:

<?php

function template_styles() {
		// ...
		wp_localize_script( 'custom', 'pg', array(
        'ajaxurl' => admin_url( 'admin-ajax.php' )
    ) );
}

Creamos una función donde esté el código de PHP que recibe la función AJAX así:

<?php

add_action("wp_ajax_nopriv_pgFiltroProductos", "pgFiltroProductos");
add_action("wp_ajax_pgFiltroProductos", "pgFiltroProductos");
function pgFiltroProductos() {
    $args = array(
        'post_type' => 'producto',
        'posts_per_page' => -1,
        'order'     => 'ASC',
        'orderby' => 'title',
    );

    if ($_POST['categoria']) {
        $args['tax_query'] = array(
            array(
                'taxonomy' => 'categorias-productos',
                'field' => 'slug',
                'terms' => $_POST['categoria']
            )
        );
    }

    $productos = new WP_Query($args);

    $return = array();
    if ($productos->have_posts( )) {
        while ($productos->have_posts()) {
            $productos->the_post();

            $return[] = array(
                'imagen' => get_the_post_thumbnail( get_the_id( ), 'large' ),
                'link'   => get_the_permalink( ),
                'titulo' => get_the_title( )
            );
        }
    }
    wp_send_json( $return );
}

Y código de JQuery es:

(function($) {
    console.log('Hola WordPress')
    $("select").change(function() {
        $.ajax({
            url: pg.ajaxurl,
            method: "POST",
            data: {
                "action": "pgFiltroProductos",
                "categoria": $(this).find(':selected').val()
            },
            beforeSend: function() {
                $("#resultados-productos").html("Cargando...")
            },
            success: function(data) {
                let html = ''
                data.forEach(item => {
                    html += `
                        <div class="col-4 my-3">
                            <figure>${item.imagen}</figure>
                            <h4 class="text-center my-2">
                                <a href="${item.link}">${item.titulo}</a>
                            </h4>
                        </div>
                    `
                })

                $("#resultados-productos").html(html)
            },
            error: function(error) {
                console.error(error)
            }
        })
    })
})(jQuery)

Todo perfectamente claro. Gracias

Hola, mi filtro me muestra todos los productos en todas las opciones donde puedo tener el error, adjunto el codigo:
/custom.js
console.log(‘Hola WordPress’);
(function($) {
$(’#categorias-productos’).change(function(){
$.ajax({
url:pg.ajaxurl,
method:“POST”,
data:{
“action”:“pgFiltroProductos”,
“categoria”😒(this).find(’:selected’).val()
},
beforeSend: function(){
$("#resultado-productos").html(“cargando…”)

        },
        success:function(data){
            let html="";
            data.forEach (item => {
                html+=`<div class="col-4 my-3">
                <figure>${item.image}</figure>
                <h4 class=text-center my-2>
                <a href="${item.link}">${item.titulo}</a></h4></div>`
            })
            $("#resultado-productos").html(html);
        },
        error: function (error){
            console.log(error)
        }
    })
})

})(jquery);

Por favor subir los archivos del curso para poder tener el código como referencia y corregir los errores que se nos presentan

Hola, tengo un error 400, he revisado el código muchas veces y no lo he logrado solucionar

Resultado de la clase

Estaba trabajando en un proyecto personal y esta clase está increible, ya tengo algo de experiencia construyendo temas de wordpress pero nunca había usado Ajax.

Sin duda una excelente clase

Me sucedió algo, toda la parte del filtrado ocurría sin problemas, pero a la hora de imprimir el HTML no se ejecutaba. Me di cuenta que era porque me faltaba el elemento contenedor donde se imprimen los resultados:

<div id="resultado-productos"></div>

De modo que el html del front-page.php queda de esta forma:

<div class="row">
            <div class="col-12">
                <select class="form-control" name="categorias-productos" id="categorias-productos">
                    <option value="">Todas las categorias</option>
                    <?php $terms = get_terms('categoria-productos', array('hide_empty' => true)); ?>
                    <?php foreach ($terms as $term) {
                        echo '<option value="'.$term->slug.'">'.$term->name.'</option>'; 
                    } ?>
                </select>
                <div id="resultado-productos"></div>
            </div>
        </div>

Esta un poco cutre, pero se puede mejorar 😃

Profe nos serviría mucho el repositorio con el código final, el que ha mandado solo tiene el código del curso anterior. Gracias

el código en github está diferente a los pasos que seguimos en la clase, a mi me aparecía un error 500 y me di cuenta que en el repo, en el archivo custom tiene $(“select”).change(function(){

De esa manera jala pero no está apuntando directamente, también tuve un typo con la ‘s’ de difrencia entre el id y el array, corrigiendo eso jaló

Todo excelente @whoisnegrello !!! Muchas gracias!!!

Una consulta, mi filtro me muestra todos los productos en todas las opciones donde puedo tener el error, adjunto el codigo
//custom.js
(function($){
$(’#categorias-productos’).change(function(){
$.ajax({
url: pg.ajaxurl,
method:‘POST’,
data: {
“action”:‘pgFiltroProductos’,
“categoria”: $(this).find(’:selected’).val()
},
beforeSend: function() {
$(’#resultado-productos’).html(‘Cargando…’);
},
success: function(data) {
console.log(data);
let html = “”;
data.forEach(item =>{
html+= <div class="col-4 my-3"> <figure>${item.imagen}</figure> <h4 class="text-center my-2> <a href="${item.link}">${item.titulo}</a></h4></div>
})
$("#resultado-productos").html(html);
},
error: function(error) {
console.log(error);
}
});
});

})(jQuery);
//functions.php
function pgFiltroProductos(){

    $args = array(
        'post_type' => 'producto',
        'post_per_page' => -1,
        'order'         => 'ASC',
        'orderby'       => 'title'
    );
    if($_POST['categoria']){
        $args ['taxt_query'] = array(
                    array(
                        'taxonomy' => 'categoria-productos',
                        'field' => 'slug',
                        'terms' => $_POST['categoria']
                    )
        );
                
    }
   
    $productos = new WP_Query($args);

    if($productos->have_posts()){
        $return = array();
        while($productos->have_posts()){
            $productos->the_post();
            $return[] = array(
                'imagen' => get_the_post_thumbnail(get_the_id(), 'large'),
                'link' =>   get_the_permalink(),
                'titulo' => get_the_title()
            );
        }
        
        wp_send_json($return);
    }

}
add_action(“wp_ajax_nopriv_pgFiltroProductos”, “pgFiltroProductos”);
add_action(“wp_ajax_pgFiltroProductos”, “pgFiltroProductos”);
//dondeesta el filtro
<div class=“col-12 text-right”>
<select name=“form-control” id=“categorias-productos”>
<option value="">Todos los productos</option>
<?php $terms = get_terms(‘categoria-productos’, array(‘hide_empty’ => true)); ?>
<?php foreach($terms as $term){
echo ‘<option value="’.$term->slug.’">’.$term->name. ‘</option>’;
}?>
</select>
</div>

Podrían pasar el ejemplo usando fetch JS ?

Con un spinner de carga se ve cool

Estoy lo voy a usar para crear un carrusel de las ultimas entradas publicadas, a ver que sale XD, excelente curso!!!

Cordial saludo.

Tengo el mismo inconveniente que reportaron pero he revisado el código y no encuentro error alguno adicionalmente verifique que la carpeta wp-admin contenga los permisos 644 y efectivamente son correctos.

Les agradecería mucho su ayuda.

<?php 
/* FUNCTION.PHP */
function init_template() {
    add_theme_support('post-thumbnails');
    add_theme_support('title-tag');
    add_theme_support(
        'custom-logo',
        array(
            'height'      => 190,
            'width'       => 190,
            'flex-width'  => false,
            'flex-height' => false,
        )
    );
    register_nav_menus(
        array(
            'top_menu' => 'Menú Principal',
            'footer' => 'Footer Menu',
            'social' => 'Social Links Menu'
        )
    );
}
add_action('after_setup_theme', 'init_template');

// CARGAR ARCHIVOS EXTERNOS
function assets() {
    wp_register_style( 'bootstrap', 'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css', '', '4.4.1', 'all');
    wp_register_style( 'montserrat', 'https://fonts.googleapis.com/css2?family=Montserrat&display=swap', '', '1.0', 'all');
    wp_register_style( 'Oswald', 'https://fonts.googleapis.com/css2?family=Oswald:[email protected];600&display=swap', '', '1.0', 'all');
    wp_register_style( 'Lato', 'https://fonts.googleapis.com/css2?family=Lato&display=swap', '', '1.0', 'all');
    wp_register_style( 'styleCustom', get_template_directory_uri().'/assets/css/custom.css', '', '1.0', 'all');
    wp_enqueue_style( 'estilos', get_stylesheet_uri(), array('bootstrap', 'montserrat', 'Oswald', 'Lato', 'styleCustom'), '1.0', 'all');

    wp_register_script( 'popper', 'https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js', '', '1.16.0', true);

    wp_enqueue_script( 'bootstrapjs', 'https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js', array('jquery', 'popper'), '4.4.1', true);
    wp_enqueue_script('custom', get_template_directory_uri().'/assets/js/custom.js', '', '1.0', true);
    wp_localize_script('custom', 'pg', array(
        'ajaxurl' => admin_url('admin-ajax.php')
    ));
}
add_action('wp_enqueue_scripts', 'assets');

// WIDGET
function sidebar() {
    register_sidebar (
        array (
            'name'          => 'Pie de pagina',
            'id'            => 'footer',
            'description'   => 'Zona de widgets para pie de pagina',
            'before_title'  => '<p>',
            'after_title'   => '</p>',
            'before_widget' => '<div id="%1$s" class="%2$s">',
            'after_widget'  => '</div>',
        )
    );
}
add_action('widgets_init', 'sidebar');

// CUSTOM POST TYPE
function productos_type() {
    $labels = array(
        'name'          => 'Productos',// nombre dentro de la seccion
        'singular_name' => 'Producto',
        'menu_name'     => 'Productos'
    );
    $args = array(
        'label'              => 'Productos', // este es el nombre por defecto
        'description'        => 'Poductos de platzi',
        'labels'             => $labels,
        'supports'           => array('title', 'editor', 'thumbnail', 'revision'),
        'public'             => true,
        'show_in_menu'       => true,
        'menu_position'      => 5,
        'menu_icon'          => 'dashicons-cart',
        'cant_export'        => true,
        'publicly_queryable' => true,
        'rewrite'            => true,
        'show_in_rest'       => true
    );
    register_post_type('producto', $args);
}
add_action( 'init', 'productos_type');

// CUSTOM TAXONOMY
function pgRegisterTax() {
    $args = array(
        'hierarchical' => true,
        'labels' => array(
            'name' => 'Categorías de productos',
            'singular_name' => 'Categoría de productos'
        ),
        'show_in_nav_menu' => true,
        'show_admin_column' => true,
        'rewrite' => array('slug' => 'categoria-productos')
    );
    register_taxonomy('categoria-productos', array('producto'), $args);
}
add_action('init', 'pgRegisterTax');

function filtroProductos() {
    $arg = array(
        'post_type' => 'producto',
        'posts_per_page' => -1,
        'order' => 'DESC',
        'orderby' => 'date'
    );
    if($_POST['categoria']) {
        $arg['tax_query'] = array(
            array(
                'taxonomy' => 'categoria-productos',
                'field' => 'slug',
                'terms' => $_POST['categoria']
            )
        );
    };
    $productos = new WP_Query($arg);
    if($productos->have_posts()){
        $return = array();
        while($productos->have_posts()){
            $productos->the_posts();
            $return[] = array(
                'imagen' => get_the_post_thumbnail(get_the_ID(), 'thumbnail'),
                'link' => get_the_permalink(),
                'titulo' => get_the_title()
            );
        };
    };
    wp_send_json($return);
}
add_action( 'wp_ajax_nopriv_filtroProductos', 'filtroProductos');
add_action( 'wp_ajax_filtroProductos', 'filtroProductos');
/* CUSTOM.JS */
(function($){
    $('#categorias-productos').change(function(){
        $.ajax({
            url: pg.ajaxurl,
            method:'POST',
            data: {
                "action":'filtroProductos',
                "categoria": $(this).find(':selected').val()
            },
            beforeSend: function() {
                $('#resultado-productos').html('Cargando....');
            },
            success: function(data) {
                console.log(data);
            },
            error: function(error) {
                console.log(error);
            }
        });
    });
})(jQuery);

Hola, cuando hago el script de PHP todo va bien, pero parece que hay algo mal en el JS y no me filtra, dónde tengo el error que no lo detecto? =(

(function($){
        $("#categorias-productos").change(function(){
        $.ajax({
            url:pg.ajaxurl,
            method: "POST",
            data: {
                "action":"pgFiltroProductos",
                "categoria": $(this).find(':selected').val()
            },
            beforeSend: function() {
                $("#resultado-productos").html("Cargando...")
            },
            success: function(data) {
                let html = "";
                data.forEach(item => {
                    html += `<div class="col-4 my-3">
                        <figure>${item.imagen}</figure>
                        <h4 class=text-center my-2>
                        <a href="${item.link}">${item.titulo}</a></h4></div>` 
                })
                $("#resultado-productos").html(html);
            },
            error: function(error) {
                console.log(error)
            }
        })
    })
})(jQuery);

Hola a todos, cuando estoy en la parte donde probamos el array con el console.log(data) me sale este error en la consola…

¿Por favor me podrían ayudar? Saludos!

Sos un crack Lucio, Muchas gracias!

Una pregunta: ¿cómo creo el template para la pagina de resultados? sería bueno agregar un search bar para buscar un nombre en específico de un producto.

Gracias!

Woow, en seiro que el profe es un capo, ¿cómo lo ven aplicado a mi web?

Muy interesante el ejercicio.

Necesitamos hacer lo siguiente:

Hacer la llamada AJAX
Crear la función que manejará la acción.
Enganchar la función con un hook.
Gestionar la respuesta a la llamada.
Queremos que la llamada se produzca cuando el botón es pulsado, para ello llamamos a la función ajax() que facilita jQuery cuando se da el evento on click de nuestro botón. A dicha función le proporcionamos como parámetros la URL del servidor, el tipo de petición HTTP (en este ejemplo hemos usado POST), los datos a enviar, y los callback a ejecutar en caso de error (saca el mensaje de error por la consola) o éxito (muestra la respuesta recibida modificando el DOM). Entre los datos que se envían hay que incluir action, este es el nombre de la acción que va a realizar el servidor.

no me funciono, y todo el codigo luce bien. hace una peticion al admin-ajax.php queda en status pending y luego falla

Hola, el proyecto en github esta super diferente a como se presenta en las clases tanto en los nombre de las funciones como en las estructuras.

Si no les funciona la invocacion del archivo custom.js, cuando hagan el cambio tienen que cambiar la version en el archivo functions.php

wp_enqueue_script( ‘custom’, get_template_directory_uri()."/assets/js/custom.js", false,“1.2”, true );

como ven lo cambie a la version 1.2

Este código no me sirvió y no entiendo exactamente el motivo, tuve que sar corchetes para que funcione
El error que tenía era que me salían todos los elementor de productos y usando los paréntesis me salen solo los que pertenecen a la categoría

if ($_POST['categoria']) {
		$args['tax_query'] = array(
			array(
				'taxonomy' => 'categoria-productos',
				'field' => 'slug',
				'terms' => $_POST['categoria']
			)
		);
	}

Este es el código que me funcionó

if ($_POST["categoria"]) {
  $args['tax_query'] = [
    [
      'taxonomy' => 'categoria-productos',
      'field' => 'slug',
      'terms' => $_POST['categoria']
    ]
  ];
}

Si que estaba de manco. En mi caso tube un error ya que estoy utilizando Bootstrap 5, que no utiliza jquery asi que nunca lo agregue al proyecto, simplemente fue agregarlo en el archivo functions.php. y listo.

El repositorio está desactualizado y a pesar de que muchos lo han dicho no hicieron nada, ademas que según veo no hay respuesta del instructor desde hace casi un año.

Hay múltiples formas de usar AJAX con WordPress, pero sólo una es la realmente correcta. Lo mejor es que también es la más simple, estamos hablando de usar la manera nativa, así que no tienes que instalar ni configurar nada. Todas las peticiones AJAX se procesan mediante el fichero admin-ajax.php, el cual se encuentra en la carpeta wp-admin. Sin embargo no necesitarás modificar este fichero, basta con que sepas de su existencia y conozcas su ruta.

AJAX es el acrónimo de Asynchronous Javascript And XML, y su misión es servir de puente entre tu sitio web y el servidor, el corazón de esta tecnología asíncrona es el objeto XMLHttpRequest, que permite el intercambio de datos. Estos son los pasos básicos para realizar una llamada AJAX:

Especificar la información a enviar
Configurar la llamada
Emplear el objeto XMLHttpRequest para enviar los datos
Recibir y procesar la respuesta del servidor
Lo bueno es que este proceso puede ser simplificado empleando la librería jQuery.

Dejo el link de mi repositorio por si les es de utilidad 😃https://github.com/ElianRuiz99/Tema-Wordpress-Platzi

Hola , el video se queda congelado en minuto 13:49