Los pasos que a seguir son los siguientes:
- Crear menú en base de datos
- Listar menús desde base de datos con PHP
- Código PHP y javsacript para crear el menú desplegable
En github dejo el repo del proyecto https://github.com/depruebas/menu-desplegable-php
Y aquí están los scripts para crear la tabla y las consultas que crean los menús https://github.com/depruebas/menu-desplegable-php/tree/master/sql que acontinuación explico.
Crear menú en base de datos
Lo primero que hacemos es crear los registros del menú en la base se datos, primero los del nivel principal que serán los títulos del menú, en el ejemplo serán los títulos de los cursos
INSERT INTO `menus` (`parent_id`, `name`, `alias`, `enabled`, `orden`, `created_at`)
VALUES ('0', 'MySql en Linux', NULL, '1', '1', CURRENT_TIMESTAMP);
INSERT INTO `menus` (`parent_id`, `name`, `alias`, `enabled`, `orden`, `created_at`)
VALUES ('0', 'MySql en Windows', NULL, '1', '1', CURRENT_TIMESTAMP);
Para relacionar los menús utilizamos el campo parent_id que para los títulos de los cursos es 0 y para las lecciones que componen el curso será el id. Por ejemplo las lecciones que pertenecen al curso de MySql en Linux si el id del curso es 1 será el parent_id:
INSERT INTO `menus` (`parent_id`, `name`, `alias`, `enabled`, `orden`, `created_at`)
VALUES ('1', 'Información general', NULL, '1', '1', CURRENT_TIMESTAMP);
INSERT INTO `menus` (`parent_id`, `name`, `alias`, `enabled`, `orden`, `created_at`)
VALUES ('1', 'Guías de inicio rápido', NULL, '1', '5', CURRENT_TIMESTAMP);
INSERT INTO `menus` (`parent_id`, `name`, `alias`, `enabled`, `orden`, `created_at`)
VALUES ('1', 'Tutoriales', NULL, '1', '15', CURRENT_TIMESTAMP);
INSERT INTO `menus` (`parent_id`, `name`, `alias`, `enabled`, `orden`, `created_at`)
VALUES ('1', 'Recursos', NULL, '1', '10', CURRENT_TIMESTAMP);
Ahora hay que crear las lecciones que las pondremos en la otra tabla menus_contenido
-- Temas correspondientes al menú Información general
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('3', 'Novedades', 'Breve sobre las novedades', 'Texto sobre las novedades', '1', '1', CURRENT_TIMESTAMP, NOW());
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('3', 'Notas de la versión', 'BREVE sobre Notas de la versión',' TEXTO sobre Notas de la versión', '1', '5', CURRENT_TIMESTAMP, NOW());
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('3', 'Historial de versiones', 'Breve sobre Historial de versiones', 'Texto sobre Historial de versiones', '1', '10', CURRENT_TIMESTAMP, NOW());
-- Temas correspondientes al menú Guías de inicio rápido
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('4', 'Instalación en SUSE', 'BREVE sobre Instalación en SUSE', 'TEXTO sobre Instalación en SUSE', '1', '1', CURRENT_TIMESTAMP, NOW());
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('4', 'Instalación en Red Hat', 'BREVE sobre Instalación en Red Hat', 'TEXTO sobre Instalación en Red Hat', '1', '5', CURRENT_TIMESTAMP, NOW());
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('4', 'Instalación en Ubuntu', 'BREVE sobre Instalación en Ubuntu', 'TEXTO sobre Instalación en Ubuntu', '1', '10', CURRENT_TIMESTAMP, NOW());
-- Temas correspondientes al menú Tutoriales
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('5', 'Novedades de la documentación de MySql', 'BREVE sobre documentación', 'TEXTO sobre documentación', '1', '1', CURRENT_TIMESTAMP, NOW());
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('5', 'Migración desde Windows', 'BREVE sobre Migración desde Windows', 'TEXT sobre Migración desde Windows', '1', '1', CURRENT_TIMESTAMP, NOW());
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('5', 'Migración desde docker', 'BREVE Migración desde docker', 'TEXTO sobre Migración desde docker', '1', '5', CURRENT_TIMESTAMP, NOW());
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('5', 'Novedades en los recursos', 'BREVE sobre Novedades en los recursos', 'TEXTO sobre Novedades en los recursos', '1', '10', CURRENT_TIMESTAMP, NOW());
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('5', 'Novedades en los recursos', 'BREVE sobre Novedades en los recursos', 'TEXTO sobre Novedades en los recursos', '1', '15', CURRENT_TIMESTAMP, NOW());
-- Temas correspondientes al menú Recursos
INSERT INTO `menus_contenido` (`menu_id`, `title`, `brief`, `text`, `enabled`, `orden`, `created_at`, `updated_at`)
VALUES ('6', 'Guia de solución de problemas', 'BREVE sobre solución de problemas', 'TEXTO sobre solución de problemas', '1', '1', CURRENT_TIMESTAMP, NOW());
Listar menús desde base de datos con PHP
Ahora que tenemos la base de datos creada con las tablas y los menús insertados vamos a crear una página index.php para leer con una consulta SQL ese menú. La consulta es la siguiente:
select m.id as menu_id, m.name as menu_name,
mm.id as submenu_id, mm.name as submenu_name, mm.orden as submenu_orden,
mc.id as tema_id, mc.title as tema_title, mc.orden as tema_orden
from menus as m
inner join menus as mm On m.id = mm.parent_id
inner join menus_contenido as mc On mc.menu_id = mm.id
where m.id = 1
order by mm.orden asc, mc.orden asc;
Y el resultado de esta consulta es el siguiente:
En este listado tenemos:
- menu_name titulo del menú
- submenu_name los títulos de los submenus
- tema_name los títulos dentro de los submenus
Código PHP y javsacript para crear el menú desplegable
Una vez tenemos la consulta preparada la ejecutamos en el código PHP de la siguiente forma:
$db = mysqli_connect("172.21.0.2", "root", "root", "ejemplo_menus", 3306);
$rows = $db->query( "select m.id as menu_id, m.name as menu_name,
mm.id as submenu_id, mm.name as submenu_name, mm.orden as submenu_orden,
mc.id as tema_id, mc.title as tema_title, mc.orden as tema_orden
from menus as m
inner join menus as mm On m.id = mm.parent_id
inner join menus_contenido as mc On mc.menu_id = mm.id
where m.id = 1
order by mm.orden asc, mc.orden asc;")
->fetch_all(MYSQLI_ASSOC);
El resultado de la consulta devolverá n registros en un array con esta estructura:
Y este array lo recorreremos con el siguiente código PHP para crear el menú en htmlArray ( [0] => Array ( [menu_id] => 1 [menu_name] => MySql en Linux [submenu_id] => 3 [submenu_name] => Información general [submenu_orden] => 1 [tema_id] => 2 [tema_title] => Novedades [tema_orden] => 1 ) ... ... )
$submenu = '';
for( $i = 0; $i < count( $rows); $i++)
{
if ( $submenu != $rows[$i]['submenu_id'])
{
echo '<li class="list-unstyled">';
echo '<a id=Submenu_'.$rows[$i]['submenu_id'].' href="#" data-toggle="collapse" aria-expanded="false" class="">
<i class="fa-solid fa-circle fa-0xs"></i>'.$rows[$i]['submenu_name'].'</a>';
echo '<ul class="collapse " id="pageSubmenu_'.$rows[$i]['submenu_id'].'">';
}
echo '<li class="list-unstyled"><a href="/class/'.$rows[$i]['tema_id'].'"><i class="fa fa-chevron-right mr-2 fa-0xs"></i>'.$rows[$i]['tema_title'].'</a></li>';
$submenu = $rows[$i]['submenu_id'];
if ( $submenu != $rows[$i+1]['submenu_id'])
{
echo '</ul></li>';
}
}
Y este será el resultado hasta ahora:
Pero nos faltan un par de cosas, hasta ahora tenemos el menú pero no es desplegable, para poder desplegar el siguiente nivel y acceder a los temas hay que crear el código javascript/jquery y una consulta más que nos dará el numero de submenus tenemos que activar.
El código javascript es el siguiente:
window.onload = function() {
let menus = [<?php echo $menus[0]['ids']; ?>];
console.log(menus);
console.log(menus.length);
for (let i = 0; i < menus.length; i++)
{
console.log( menus[i]);
$("#Submenu_" + menus[i]).click(function(){
event.preventDefault();
if ( !$('#pageSubmenu_' + menus[i]).is(':visible'))
{
$("#pageSubmenu_" + menus[i]).show();
for (let j = 0; j < menus.length; j++)
{
if ( menus[i] != menus[j])
{
$("#pageSubmenu_" + menus[j]).hide();
}
}
}
else
{
$("#pageSubmenu_" + menus[i]).hide();
}
});
}
};
Y la consulta del numero de menus que almacenamos en la variable PHP, $menus y que se recoge en el código Javascritp es:
$menus = $db->query( "select GROUP_CONCAT(id SEPARATOR ', ') as ids from menus where parent_id = 1")
->fetch_all(MYSQLI_ASSOC);
Y hasta aquí el ejemplo de menú desplegable.
Todo el código esta en el repositorio https://github.com/depruebas/menu-desplegable-php
Al final son dos consultas SQL, un poco de código PHP y Javascript/jquery que se puede trasladar a cualquier framework, incluso en otros lenguajes.
Y esto es todo, feliz programming
Saludos
Alex.
También puede interesarte:
Configurar Laravel Sail para utilizar un MySql externo existente |
||