Re: WonderCMS 3.5.0 released
Posted: Tue Mar 25, 2025 9:14 pm
Is yours a fresh install or an upgrade?
Have you done anything other than login into your site?
Have you done anything other than login into your site?
small flat file CMS - simple website builder
https://www.wondercms.com/community/
A further thought...NorfolkGreg wrote: Tue Mar 25, 2025 9:14 pm Is yours a fresh install or an upgrade?
Have you done anything other than login into your site?
NorfolkGreg wrote: Sat Mar 22, 2025 11:03 am I've just looked again at the standard navigation code generated for https://gregchapman.uk The list item I am concerned about is this:It's just Line 2 that I'm looking to change to:Code: Select all
<li class="nav-item subpage-nav"> <a class="nav-link" href="https://gregchapman.uk/games/">Games</a> <ul class="subPageDropdown"> <li class="nav-item "> <a class="nav-link" href="https://gregchapman.uk/games/board/">Board</a> </li> <li class="nav-item "> <a class="nav-link" href="https://gregchapman.uk/games/table/">Table</a> </li> </ul> </li>
I can then use a CSS first-child selector to style the second (now <button>) line to appear like other menu items and open the child drop-down list <ul class="subPageDropdown"> on hover (on a desktop) or tap (on a phone).Code: Select all
<button class="nav-link">Games</button>
I see your suggested code includes a reference to "top level" but I would want any list item of class "subpage-nav" to replace a link with button code, so sub-pages could cascade almost indefinitely.
Does that make sense?
Code: Select all
<a class="nav-link" href="https://gregchapman.uk/games/">Games</a>
Code: Select all
<?php
// Define the helper function outside of the listener to avoid redeclaration
function hasVisibleSubpages($item) {
foreach ($item->subpages as $subpage) {
if ($subpage->visibility === 'show') {
return true;
}
}
return false;
}
global $Wcms;
$Wcms->addListener('renderPageNavMenuItem', function ($args) use ($Wcms) {
// Ensure we have the required arguments
list($output, $item, $parentSlug, $visibleSubpage) = array_pad($args, 4, null);
// Check if this item has visible subpages
$hasVisibleSubpages = hasVisibleSubpages($item);
// If the item has subpages, create a button for the parent item (still a link)
$navTag = $hasVisibleSubpages
? '<a class="nav-link" href="' . $Wcms->url($parentSlug) . '"><button class="nav-link-button">' . $item->name . '</button></a>'
: '<a class="nav-link" href="' . $Wcms->url($parentSlug) . '">' . $item->name . '</a>';
// Create the main list item
$output = '<li class="nav-item ' . ($Wcms->currentPage === $item->slug ? 'active ' : '') . ($hasVisibleSubpages ? 'subpage-nav' : '') . '">'
. $navTag;
// Render subpages only if there are visible ones
if ($hasVisibleSubpages) {
$output .= '<ul class="subPageDropdown">';
foreach ($item->subpages as $subpage) {
if ($subpage->visibility === 'hide') {
continue;
}
// If the subpage has its own visible subpages, treat it as a button
$subpageHasVisibleSubpages = hasVisibleSubpages($subpage);
// If the subpage has visible subpages, make it a button
$subpageSlug = $parentSlug . '/' . $subpage->slug;
$subpageTag = $subpageHasVisibleSubpages
? '<a class="nav-link" href="' . $Wcms->url($subpageSlug) . '"><button class="nav-link-button">' . $subpage->name . '</button></a>'
: '<a class="nav-link" href="' . $Wcms->url($subpageSlug) . '">' . $subpage->name . '</a>';
$output .= '<li class="nav-item ' . ($subpageHasVisibleSubpages ? 'subpage-nav' : '') . '">'
. $subpageTag
. '</li>';
// If the subpage has its own visible subpages, render them
if ($subpageHasVisibleSubpages) {
$output .= '<ul class="subPageDropdown">';
foreach ($subpage->subpages as $subsubpage) {
if ($subsubpage->visibility === 'hide') {
continue;
}
$subsubpageSlug = $subpageSlug . '/' . $subsubpage->slug;
$output .= '<li class="nav-item">'
. '<a class="nav-link" href="' . $Wcms->url($subsubpageSlug) . '">' . $subsubpage->name . '</a>'
. '</li>';
}
$output .= '</ul>';
}
}
$output .= '</ul>';
}
$output .= '</li>';
return [$output];
});
?>
<!DOCTYPE html>
<html lang="<?= $Wcms->getSiteLanguage() ?>">
<head>
<!-- Encoding, browser compatibility, viewport -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<!-- Search Engine Optimization (SEO) -->
<meta name="title" content="<?= $Wcms->get('config', 'siteTitle') ?> - <?= $Wcms->page('title') ?>" >
<meta name="description" content="<?= $Wcms->page('description') ?>">
<meta name="keywords" content="<?= $Wcms->page('keywords') ?>">
<meta property="og:url" content="<?= $this->url() ?>" >
<meta property="og:type" content="website" >
<meta property="og:site_name" content="<?= $Wcms->get('config', 'siteTitle') ?>" >
<link href="https://fonts.googleapis.com/css?family=Boogaloo|McLaren" rel="stylesheet">
<meta property="og:title" content="<?= $Wcms->page('title') ?>" >
<!-- Website and page title -->
<title>
<?= $Wcms->get('config', 'siteTitle') ?> - <?= $Wcms->page('title') ?>
</title>
<!-- Admin CSS -->
<?= $Wcms->css() ?>
<!-- Theme CSS -->
<link rel="stylesheet" rel="preload" as="style" href="<?= $Wcms->asset('css/style.css') ?>">
</head>
<body>
<div id="wrapper">
<!-- Admin settings panel and alerts -->
<?= $Wcms->settings() ?>
<?= $Wcms->alerts() ?>
<header>
<h1>
<em><?= $Wcms->get('config', 'siteTitle') ?></em><br>
<?= $Wcms->page('title') ?>
</h1>
<h2><?= $Wcms->page('description') ?></h2>
</header>
<section id="topMenu">
<div class="inner">
<!-- Hamburger icon -->
<input id="menuControl" type="checkbox">
<label for="menuControl"></label>
<nav>
<ul class="menu">
<!-- Menu -->
<?= $Wcms->menu() ?>
</ul>
</nav>
</div>
</section>
<section class="main">
<?= $Wcms->page('content') ?>
</section>
<footer>
<?= $Wcms->footer() ?>
</footer>
</div>
<!-- Admin JavaScript. More JS libraries can be added below -->
<?= $Wcms->js() ?>
<script>
function check() {
document.getElementById("menuControl").checked = true;
}
</script>
</body>
</html>
Code: Select all
/* Style buttons in the menu to match navigation items */
nav .nav-item button {
background-color: transparent;
border: none;
cursor: pointer;
font-weight: bold;
color: var(--menutext);
font-size: 1em;
padding: 0;
}
That's right and that's what's needed if you want a drop down menu to work on a touch screen device.wiz wrote: Sun Mar 30, 2025 4:33 pm Hi Greg, if you want for example:to be replaced with a button, wouldn't the Games then not be a link anymore?Code: Select all
<a class="nav-link" href="https://gregchapman.uk/games/">Games</a>
With the current solution I posted, this works as expected. On mobile dropdown is opened, if the user clicks it again, it opens the parent page.NorfolkGreg wrote: Sun Mar 30, 2025 10:20 pmThat's right and that's what's needed if you want a drop down menu to work on a touch screen device.wiz wrote: Sun Mar 30, 2025 4:33 pm Hi Greg, if you want for example:to be replaced with a button, wouldn't the Games then not be a link anymore?Code: Select all
<a class="nav-link" href="https://gregchapman.uk/games/">Games</a>
I'm prepared to be told I'm missing something but this is what I find (with my limited HTML and CSS coding knowledge.)
With the default code a tap on GAMES menu option opens the Games page. The dropdown never opens so there is no opportunity to pick one of the sub-pages. Tap and Hold over GAMES and and the dropdown does appear but it's hidden under the context menu which overlays it. You then need to tap somewhere off the context menu to clear it before being able to pick a sub-page.
You're right, changing GAMES to a button, will lose it as a link. Instead it becomes a heading that, with the appropriate CSS, will open the dropdown and allow you to select the sub-pages.
Yes, it is possible, with rather more complicated HTML and appropriate CSS, to create a menu that would allow you to tap on GAMES that would both open the dropdown and activate a link on the GAMES option. However, I thought that would add a lot more complication to the code needed in the function that would be more difficult to document and explain in the Wcms docs. (BTW: I like how you've moved it away from the GitHub interface that I think many potential users find too technical to use.)
I'll play with the code you suggest over the next few days and see how I get on, but I hope the above better indicates what I was thinking.