La nueva versión de CoockieConsent de Orest Bida, en este caso la V3, que ofrece mayores funcionalidades y mayor capacidad de personalización.
Vamos a realizar una página que nos muestre un filtro avanzado de las entradas recurriendo a la librería Filterizr para los efectos visuales y para el filtrado.
Filterizr es una biblioteca de JavaScript que ordena, baraja y aplica filtros impresionantes sobre galerías utilizando transiciones CSS3.
Usaremos para ello solo Oxygen, sin recurrir a ningún otro plugin.
Filterizr es una librería JavaScript con las siguientes características:
- Rendimiento fluido: optimizado para una experiencia fluida en dispositivos móviles
- Soporte de plataforma: Chrome, Firefox, Safari, Opera Android y navegadores iOS Edge, IE (v.10+)
- Licencia MIT de código abierto (es decir, gratis para todos los usos)
- Disponible en GitHub para la descarga de todo el código para un proyecto completo.
🛠 Vamos al tajo 🛠
Paso 1 - Elementos que vamos a necesitar.
Por supuesto que en gran parte dependerá de tus preferencias y/o necesidades del diseño, pero aquí vamos a mostrar los requerimientos mínimos; juego ya dependerá de ti todo lo demás.
Así que ahí abajo se muestra la lista.
- Un componente Code-Bolck, donde vamos a meter código PHP, CSS y JavaScript.
- Un componente Repeater.
- Descargar los archivos desde GitHub.
- A mayores, ganas de hacerlo y aprender un poco.
Paso 2 - El Repeater
Montar un componente Repeater con las configuraciones necesarias.
Teniendo en cuenta lo siguiente:
-- Al Repeater hay que darle la clase: filtr-container
-- Al primer DIV después del Repeater darle la clase: filtr-item.
Al primer DIV tambien hay que darle dos atributos:
Primer atributo:
name --> data-category
value --> [ oxygen data='post_terms' taxonomy='category' ]
Segundo atributo:
name --> data-sort
value --> value
Si en el Repeater no se incluyen todas las categorías, ver imagen, toma nota de las categorías que se han seleccionado para el filtrado o bien después se puede tomar nota en la sección de Categorías del menú de Entradas en el Panel de Administración.
Estos datos nos harán falta para el código php
Paso 3 - Descargar desde GitHub
Vamos al GitHub de Filterizr y descargamos el Zip, aunque solo necesitamos del archivo jquery.filterizr.min.js que se encuentra en la carpeta dist; este archivo hay que subirlo a Medios como un archivo de imagen cualquiera, y tomaremos nota de la url del mismo para pegarla en el código PHP.
Paso 4 - Código PHP
Copiar y pegar el código de abajo en la sección PHP del componente Code-Block, en el que tenemos en consideración los siguientes puntos.
- En la primera línea se pega la url correspondiente al archivo js que hemos subido a medios, se puede pegar la ruta absoluta tal y como se ha copiado o bien solo la relativo como muestra en el código, es decir, sustituir "/wp-content/uploads/2023/03/jquery.filterizr.min_.js" por lo que hayas copiado.
- La variable $lista es un array que contiene los nombres de las categorías que quieres filtrar y que deben coincidir con las seleccionadas en las opciones del Repeater y se deben escribir exactamente igual, respetando mayúsculas y minúsculas; si no has seleccionado ninguna o lo que es lo mismo, vas a mostrar todos los posts borra completamente esa línea o pon al inicio de la línea dos slash (barras inclinadas hacia adelante).
- Descargar los archivos desde GitHub.
- A mayores, ganas de hacerlo y aprender un poco.
<script type="text/javascript"
src="/wp-content/uploads/2023/05/jquery.filterizr.min_.js"></script>
<ul class="ul-filtro">
<li data-filter="all" class="li-filtro"> Todos </li>
<?php
/** Poner dos // delante de $lista
* o borrar toda la línea
* si se van a incluir todos los posts
*/
$lista = array('CSS', 'Guías', 'java script'); //Array a modificar
//! *** No cambiar nada desde aqui *** /
$incluir_todos = (isset($lista))? false: true;
$args = array(
'orderby' => 'name',
'order' => 'ASC'
);
$categories = get_categories($args);
foreach ($categories as $category) {
$nombre_cat = ucwords($category->name);
if($incluir_todos){
echo'<li data-filter="'.$category->slug.'" class="li-filtro">'. $nombre_cat .'</li>';
}else{
if(in_array($category->name, $lista)){
echo'<li data-filter="'.$category->slug.'" class="li-filtro">'. $nombre_cat .'</li>';
}
}
}
?>
</ul>
Paso 5- Código CSS
En el apartado de CSS del Code-Block damos el formato que queremos para la lista, en nuestra caso para que se muestren en línea.
.ul-filtro{
display:flex;
gap: 10px;
}
.listFilter-activado{
background-color: rgba(28,122,5,0.65);
color: #000;
}
Paso 6 - Código JavaScript
En el apartado de JavaScript del Code-Block pegamos el siguiente código.
Las opciones están comentadas en el mismo código, así mismo en la documentación oficial de Filterirz hay más info sobre más opciones.
let divFilters = document.querySelectorAll('.filtr-item:not(.filteredOut)');
const altoDivFilter = divFilters[0].clientHeight
const contenedorFiltro = document.querySelector('.filtr-container')
const footer = document.querySelector('footer')
const contenedorFilterPrincipal = document.querySelector('.ct-inner-content')
const botonesFiltro = document.querySelectorAll('.li-filtro')
ajustaAlto = ()=>{
divFilters = document.querySelectorAll('.filtr-item:not(.filteredOut)');
contenedorFilterPrincipal.style.height = contenedorFiltro.clientHeight +(altoDivFilter*2)+"px"
contenedorFilterPrincipal.style.minHeight = "70vh"
}
window.addEventListener('DOMContentLoaded',()=>{
ajustaAlto()
})
const options = {
animationDuration:0.4,// Duración de la animación en segundos.
gutterPixels:20,//Separación entre divs en pixels.
callbacks: {
onFilteringEnd: function() {
footer.style.display='block'
},
onFilteringStart:function() {
footer.style.display='none'
}
},
}
const filterizr = new Filterizr('.filtr-container', options);
document.addEventListener('click', (e)=>{
if(e.target.classList.contains('li-filtro')){
for(boton of botonesFiltro){
boton.classList.remove('listFilter-activado')
}
ajustaAlto();
e.target.classList.add('listFilter-activado')
}
})
/*** Opcional para los títulos de los post del Repeater
*Esto es lo que maneja el efecto del título al pasar el mouse por encima.
*Eliminar si no se utiliza
*/
divFilters.forEach((divfilter)=>{
divfilter.addEventListener('mouseover', ()=>divfilter.firstElementChild.classList.remove('titulo-desplazado'))
divfilter.addEventListener('mouseout', ()=>divfilter.firstElementChild.classList.add('titulo-desplazado'))
})
Paso 7 - Personalizado
Para el efecto del título, en nuestro ejemplo, utilizamos la clase titulo-desplazado, esta clase se la damos al título y la manejamos con JavaScript, por lo que si quieres aprovechar el script, puedes crear una clase, ya bien sea con código escrito CSS o por medio de la ventana gráfica de Oxygen.
Puedes copiar directamente todo el Code-Block con estes botones.
Como siempre esperamos tus comentarios y por supuesto si tienes alguna duda o necesitas ayuda puedes contactar por nuestro grupo de Telegram o dejando un comentario.
Nos vemos en la próxima. 👌
.ul-filtro{
display:flex;
gap: 10px;
}
.listFilter-activado{
background-color: rgba(28,122,5,0.65);
color: #000;
}
eyJzb3VyY2UiOiJodHRwOi8vb3h5cHJ1ZWJhcy1jb20uc3RhY2tzdGFnaW5nLmNvbSIsImNvbXBvbmVudCI6W3siaWQiOjczLCJuYW1lIjoiY3RfY29kZV9ibG9jayIsIm9wdGlvbnMiOnsiY3RfaWQiOjczLCJjdF9wYXJlbnQiOjMsInNlbGVjdG9yIjoiY29kZV9ibG9jay03My0zMDY5Iiwib3JpZ2luYWwiOnsiY29kZS1waHAiOiI8c2NyaXB0IHR5cGU9XCJ0ZXh0L2phdmFzY3JpcHRcIiBzcmM9XCIvd3AtY29udGVudC91cGxvYWRzLzIwMjMvMDUvanF1ZXJ5LmZpbHRlcml6ci5taW5fLmpzXCI+PC9zY3JpcHQ+XG4gIDx1bCBjbGFzcz1cInVsLWZpbHRyb1wiPlxuICAgPGxpIGRhdGEtZmlsdGVyPVwiYWxsXCIgY2xhc3M9XCJsaS1maWx0cm9cIiA+IFRvZG9zIDwvbGk+XG5cdDw/cGhwIFxuXHQgJGxpc3RhID0gYXJyYXkoJ0NTUycsICdHdcOtYXMnLCAnamF2YSBzY3JpcHQnKTtcblxuXHRcdCRpbmNsdWlyX3RvZG9zID0gKGlzc2V0KCRsaXN0YSkpPyBmYWxzZTogdHJ1ZTtcblxuXHQkYXJncyA9IGFycmF5KFxuXHRcdCdvcmRlcmJ5JyA9PiAnbmFtZScsXG5cdFx0J29yZGVyJyA9PiAnQVNDJ1xuXHQpO1xuXHQkY2F0ZWdvcmllcyA9IGdldF9jYXRlZ29yaWVzKCRhcmdzKTtcblxuXHRmb3JlYWNoICgkY2F0ZWdvcmllcyBhcyAkY2F0ZWdvcnkpIHtcblx0XHQkbm9tYnJlX2NhdCA9ICB1Y3dvcmRzKCRjYXRlZ29yeS0+bmFtZSk7XG5cdFx0aWYoJGluY2x1aXJfdG9kb3Mpe1xuXHRcdFx0ZWNobyc8bGkgZGF0YS1maWx0ZXI9XCInLiRjYXRlZ29yeS0+c2x1Zy4nXCIgY2xhc3M9XCJsaS1maWx0cm9cIj4nLiAkbm9tYnJlX2NhdCAuJzwvbGk+Jztcblx0XHR9ZWxzZXtcblx0XHRcdGlmKGluX2FycmF5KCRjYXRlZ29yeS0+bmFtZSwgJGxpc3RhKSl7XG5cdFx0XHRcdGVjaG8nPGxpIGRhdGEtZmlsdGVyPVwiJy4kY2F0ZWdvcnktPnNsdWcuJ1wiIGNsYXNzPVwibGktZmlsdHJvXCI+Jy4gJG5vbWJyZV9jYXQgLic8L2xpPic7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdD8+XG48L3VsPlxuIiwiY29kZS1qcyI6ImxldCBkaXZGaWx0ZXJzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmZpbHRyLWl0ZW06bm90KC5maWx0ZXJlZE91dCknKTtcbmNvbnN0IGFsdG9EaXZGaWx0ZXIgPSBkaXZGaWx0ZXJzWzBdLmNsaWVudEhlaWdodFxuY29uc3QgY29udGVuZWRvckZpbHRybyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5maWx0ci1jb250YWluZXInKVxuY29uc3QgZm9vdGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignZm9vdGVyJylcbmNvbnN0IGNvbnRlbmVkb3JGaWx0ZXJQcmluY2lwYWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY3QtaW5uZXItY29udGVudCcpXG5jb25zdCBib3RvbmVzRmlsdHJvID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmxpLWZpbHRybycpXG5hanVzdGFBbHRvID0gKCk9Pntcblx0ZGl2RmlsdGVycyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5maWx0ci1pdGVtOm5vdCguZmlsdGVyZWRPdXQpJyk7XG5cdGNvbnRlbmVkb3JGaWx0ZXJQcmluY2lwYWwuc3R5bGUuaGVpZ2h0ID0gY29udGVuZWRvckZpbHRyby5jbGllbnRIZWlnaHQgKyhhbHRvRGl2RmlsdGVyKjIpK1wicHhcIlxuXHRjb250ZW5lZG9yRmlsdGVyUHJpbmNpcGFsLnN0eWxlLm1pbkhlaWdodCA9IFwiNzB2aFwiXG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdET01Db250ZW50TG9hZGVkJywoKT0+e1xuXHRhanVzdGFBbHRvKClcbn0pXG5cbmNvbnN0IG9wdGlvbnMgPSB7XG4gICAgYW5pbWF0aW9uRHVyYXRpb246MC40LC8vIER1cmFjacOzbiBkZSBsYSBhbmltYWNpw7NuIGVuIHNlZ3VuZG9zLlxuICAgIGd1dHRlclBpeGVsczoyMCwvL1NlcGFyYWNpw7NuIGVudHJlIGRpdnMgZW4gcGl4ZWxzLlxuICBjYWxsYmFja3M6IHtcbiAgICAgIG9uRmlsdGVyaW5nRW5kOiBmdW5jdGlvbigpIHtcbiAgICAgIGZvb3Rlci5zdHlsZS5kaXNwbGF5PSdibG9jaydcbiAgICBcdH0sXG5cdCAgb25GaWx0ZXJpbmdTdGFydDpmdW5jdGlvbigpIHtcbiAgICAgIGZvb3Rlci5zdHlsZS5kaXNwbGF5PSdub25lJ1xuICAgIH1cbiAgfSxcbn0gXG5cbmNvbnN0IGZpbHRlcml6ciA9IG5ldyBGaWx0ZXJpenIoJy5maWx0ci1jb250YWluZXInLCBvcHRpb25zKTtcblxuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZSk9Pntcblx0aWYoZS50YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKCdsaS1maWx0cm8nKSl7XG5cdFx0Zm9yKGJvdG9uIG9mIGJvdG9uZXNGaWx0cm8pe1xuXHRcdFx0Ym90b24uY2xhc3NMaXN0LnJlbW92ZSgnbGlzdEZpbHRlci1hY3RpdmFkbycpXG5cdFx0fVxuXHRcdGFqdXN0YUFsdG8oKTtcblx0XHRlLnRhcmdldC5jbGFzc0xpc3QuYWRkKCdsaXN0RmlsdGVyLWFjdGl2YWRvJylcblx0fVxufSlcblxuLyoqKiBPcGNpb25hbCBwYXJhIGxvcyB0w610dWxvcyBkZSBsb3MgcG9zdCBkZWwgUmVwZWF0ZXJcbipFc3RvIGVzIGxvIHF1ZSBtYW5lamEgZWwgZWZlY3RvIGRlbCB0w610dWxvIGFsIHBhc2FyIGVsIG1vdXNlIHBvciBlbmNpbWEuXG4gKkVsaW1pbmFyIHNpIG5vIHNlIHV0aWxpemFcbiAqL1xuZGl2RmlsdGVycy5mb3JFYWNoKChkaXZmaWx0ZXIpPT57XG4gICAgZGl2ZmlsdGVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsICgpPT5kaXZmaWx0ZXIuZmlyc3RFbGVtZW50Q2hpbGQuY2xhc3NMaXN0LnJlbW92ZSgndGl0dWxvLWRlc3BsYXphZG8nKSlcbiAgICBkaXZmaWx0ZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdXQnLCAoKT0+ZGl2ZmlsdGVyLmZpcnN0RWxlbWVudENoaWxkLmNsYXNzTGlzdC5hZGQoJ3RpdHVsby1kZXNwbGF6YWRvJykpXG59KSIsInBhZGRpbmctYm90dG9tIjoiMjIiLCJjb2RlLWNzcyI6Ii51bC1maWx0cm97XG5cdGRpc3BsYXk6ZmxleDtcblx0Z2FwOiAxMHB4O1xufVxuLmxpc3RGaWx0ZXItYWN0aXZhZG97XG5cdGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjgsMTIyLDUsMC42NSk7XG5cdGNvbG9yOiAjMDAwO1xufVxuIiwidW53cmFwIjoiZmFsc2UifSwibmljZW5hbWUiOiJDb2RlIEJsb2NrICgjNzMpIiwiYWN0aXZlc2VsZWN0b3IiOmZhbHNlfSwiZGVwdGgiOjN9XSwiY2xhc3NlcyI6e30sImNvbG9ycyI6e319
{"component":{"id":73,"name":"ct_code_block","options":{"ct_id":73,"ct_parent":3,"selector":"code_block-73-3069","original":{"code-php":"<script type=\"text/javascript\" src=\"/wp-content/uploads/2023/05/jquery.filterizr.min_.js\"></script>\n <ul class=\"ul-filtro\">\n <li data-filter=\"all\" class=\"li-filtro\" > Todos </li>\n\t<?php \n\t $lista = array('CSS', 'Guías', 'java script');\n\n\t\t$incluir_todos = (isset($lista))? false: true;\n\n\t$args = array(\n\t\t'orderby' => 'name',\n\t\t'order' => 'ASC'\n\t);\n\t$categories = get_categories($args);\n\n\tforeach ($categories as $category) {\n\t\t$nombre_cat = ucwords($category->name);\n\t\tif($incluir_todos){\n\t\t\techo'<li data-filter=\"'.$category->slug.'\" class=\"li-filtro\">'. $nombre_cat .'</li>';\n\t\t}else{\n\t\t\tif(in_array($category->name, $lista)){\n\t\t\t\techo'<li data-filter=\"'.$category->slug.'\" class=\"li-filtro\">'. $nombre_cat .'</li>';\n\t\t\t}\n\t\t}\n\t}\n\t?>\n</ul>\n","code-js":"let divFilters = document.querySelectorAll('.filtr-item:not(.filteredOut)');\nconst altoDivFilter = divFilters[0].clientHeight\nconst contenedorFiltro = document.querySelector('.filtr-container')\nconst footer = document.querySelector('footer')\nconst contenedorFilterPrincipal = document.querySelector('.ct-inner-content')\nconst botonesFiltro = document.querySelectorAll('.li-filtro')\najustaAlto = ()=>{\n\tdivFilters = document.querySelectorAll('.filtr-item:not(.filteredOut)');\n\tcontenedorFilterPrincipal.style.height = contenedorFiltro.clientHeight +(altoDivFilter*2)+\"px\"\n\tcontenedorFilterPrincipal.style.minHeight = \"70vh\"\n}\n\nwindow.addEventListener('DOMContentLoaded',()=>{\n\tajustaAlto()\n})\n\nconst options = {\n animationDuration:0.4,// Duración de la animación en segundos.\n gutterPixels:20,//Separación entre divs en pixels.\n callbacks: {\n onFilteringEnd: function() {\n footer.style.display='block'\n \t},\n\t onFilteringStart:function() {\n footer.style.display='none'\n }\n },\n} \n\nconst filterizr = new Filterizr('.filtr-container', options);\n\ndocument.addEventListener('click', (e)=>{\n\tif(e.target.classList.contains('li-filtro')){\n\t\tfor(boton of botonesFiltro){\n\t\t\tboton.classList.remove('listFilter-activado')\n\t\t}\n\t\tajustaAlto();\n\t\te.target.classList.add('listFilter-activado')\n\t}\n})\n\n/*** Opcional para los títulos de los post del Repeater\n*Esto es lo que maneja el efecto del título al pasar el mouse por encima.\n *Eliminar si no se utiliza\n */\ndivFilters.forEach((divfilter)=>{\n divfilter.addEventListener('mouseover', ()=>divfilter.firstElementChild.classList.remove('titulo-desplazado'))\n divfilter.addEventListener('mouseout', ()=>divfilter.firstElementChild.classList.add('titulo-desplazado'))\n})","padding-bottom":"22","code-css":".ul-filtro{\n\tdisplay:flex;\n\tgap: 10px;\n}\n.listFilter-activado{\n\tbackground-color: rgba(28,122,5,0.65);\n\tcolor: #000;\n}\n","unwrap":"false"},"nicename":"Code Block (#73)","activeselector":false},"depth":3},"classes":{}}