// NoFestival – Create a custom metabox function nofestival_add_event_date_metabox() { add_meta_box( ‘nofestival_event_date_metabox’, ‘Event Date’, ‘nofestival_display_event_date_metabox’, ‘post’, // You can specify other post types if needed ‘normal’, ‘high’ ); } // NoFestival – Display the custom field in the metabox function nofestival_display_event_date_metabox($post) { $event_date = get_post_meta($post->ID, ‘_event_date’, true); echo ‘<label for=”event_date”>Event Date:</label>’; echo ‘<input type=”date” id=”event_date” name=”event_date” value=”‘ . esc_attr($event_date) . ‘” />’; } // NoFestival – Save the custom field data when the post is saved function nofestival_save_event_date($post_id) { if (defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE) return; if (!current_user_can(‘edit_post’, $post_id)) return; $event_date = sanitize_text_field($_POST[‘event_date’]); update_post_meta($post_id, ‘_event_date’, $event_date); } add_action(‘add_meta_boxes’, ‘nofestival_add_event_date_metabox’); add_action(‘save_post’, ‘nofestival_save_event_date’);

add custom.js

document.addEventListener("DOMContentLoaded", function () {
const menuToggle = document.querySelector(".menu-toggle");
const mainNavigation = document.querySelector(".main-navigation");

const menuIcon = document.querySelector(".menu-toggle i");

menuToggle.addEventListener("click", function () {
mainNavigation.classList.toggle("mobile-menu-open");

if (mainNavigation.classList.contains("mobile-menu-open")) {
menuIcon.classList.add("rotate-icon");
} else {
menuIcon.classList.remove("rotate-icon");
}
});
const menuItems = document.querySelectorAll(".menu-item");

menuItems.forEach(function (item) {
item.addEventListener("click", function (event) {
mainNavigation.classList.remove("mobile-menu-open");
menuIcon.classList.remove("rotate-icon");
});
});
});

Add to functions.php

class [your-theme-name]_Walker_Nav_Menu extends Walker_Nav_Menu {
  function start_el( &$output, $item, $depth = 0, $args = null, $id = 0 ) {
    // Add "has-submenu" class to top-level items with submenus
    if ( in_array( 'menu-item-has-children', $item->classes ) && $depth === 0 ) {
      $item->classes[] = 'has-submenu';
    }
    // Continue with the default start_el() method
    parent::start_el( $output, $item, $depth, $args );
  }
}
function [your-theme-name]_enqueue_scripts() {
    wp_enqueue_script('[your-theme-name]-custom', get_template_directory_uri() . '/js/custom.js', array('jquery'), '1.0', true);
}

add_action('wp_enqueue_scripts', '[your-theme-name]_enqueue_scripts');

Add to Header.php

<nav id="site-navigation" class="main-navigation">
  <?php
  wp_nav_menu(
    array(
      'theme_location' => 'primary',
      'menu_id'        => 'primary-menu',
      'walker'         => new [your-theme-name]_Walker_Nav_Menu(),
    )
  );
  ?>
</nav><!-- #site-navigation -->

Add to style.css


/* Navigation */
.main-navigation {
  width: 300px;
}

.main-navigation ul,
.sub-menu {
  list-style: none;
  padding: 0;
  margin: 0;
}

.main-navigation a {
  display: block;
  text-decoration: none;
  padding: 10px;
  color: #FFF;
  transition: background-color 0.3s, color 0.3s;
}

.main-navigation a:hover {
  background-color: #FF4F00;
  color: #fff;
}

.main-navigation.mobile-menu-open .sub-menu {
  display: block;
  max-height: 400px; /* Adjust max-height as needed */
  overflow: visible;
}

.main-navigation ul.sub-menu a {
  color: #fff;
}

.main-navigation ul.sub-menu a:hover {
  background-color: #FF4F00;
}

.main-navigation.mobile-menu-open ul.sub-menu {
  max-height: 400px; /* Adjust max-height as needed */
  overflow: visible;
}

.menu-toggle {
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  transition: transform 0.3s ease;
}

.menu-toggle.rotate {
  transform: rotate(360deg);
}

.menu-toggle p {
  margin: 0;
  padding-left: 0.2em;
}

.menu-toggle i {
   transition: transform 1s ease;
}

/* Rotate the icon when the "rotate-icon" class is applied */
.menu-toggle i.rotate-icon {
  transform: rotate(180deg);
}

.main-navigation ul,
.main-navigation ul.sub-menu {
  display: none;
}

.main-navigation.mobile-menu-open ul,
.main-navigation.mobile-menu-open ul.sub-menu {
  display: block;
  max-height: 400px; /* Adjust max-height as needed */
  overflow: visible;
  transition: max-height 1s ease-out;
}


/* CSS for submenus on larger screens */
@media screen and (min-width: 48.6em) {

	.main-navigation a {
  display: block;
  text-decoration: none;
  padding: 10px;
  color: #FFF; /* Text color */
}
	
/* Add hover behavior for all links */
.main-navigation a:hover {
  background-color: FF4F00; /* Hover background color */
  color: #fff;
}

/* Display submenus on hover */
.main-navigation li:hover > ul.sub-menu {
  display: block;
}

/* Style submenu links */
.main-navigation ul.sub-menu a {
  color: #fff;
}

/* Hover behavior for links inside submenus */
.main-navigation ul.sub-menu a:hover {
  background-color: #FF4F00; /* Hover background color */
}
}

a bit of text here….


// NoFestival - Create a custom metabox
function nofestival_add_event_details_metabox() {
    add_meta_box(
        'nofestival_event_details_metabox',
        'Event Details', // Updated title to include details
        'nofestival_display_event_details_metabox',
        'post', // You can specify other post types if needed
        'normal',
        'high'
    );
}
// Set the default timezone to Europe/Paris
date_default_timezone_set('Europe/Paris');

// NoFestival - Display the custom fields in the metabox
function nofestival_display_event_details_metabox($post) {
    $event_date = get_post_meta($post->ID, '_event_date', true);
    $event_start_time = get_post_meta($post->ID, '_event_start_time', true); // Added start time field
    $event_end_time = get_post_meta($post->ID, '_event_end_time', true); // Added end time field
    $event_location = get_post_meta($post->ID, '_event_location', true);
	$event_end_date = get_post_meta($post->ID, '_event_end_date', true); // Added end date field

    echo '<label for="event_date">Event Date:</label>';
    echo '<input type="date" id="event_date" name="event_date" value="' . esc_attr($event_date) . '" />';
    
    echo '<br><br>'; // Add some spacing between the fields

    echo '<label for="event_start_time">Start Time:</label>';
    echo '<input type="time" id="event_start_time" name="event_start_time" value="' . esc_attr($event_start_time) . '" />';

    echo '<br><br>'; // Add some spacing between the fields
	
	echo '<label for="event_end_date">Event End Date:</label>';
    echo '<input type="date" id="event_end_date" name="event_end_date" value="' . esc_attr($event_end_date) . '" />';
	
	echo '<br><br>'; // Add some spacing between the fields

    echo '<label for="event_end_time">End Time:</label>';
    echo '<input type="time" id="event_end_time" name="event_end_time" value="' . esc_attr($event_end_time) . '" />';

    echo '<br><br>'; // Add some spacing between the fields

    echo '<label for="event_location">Event Location:</label>';
    echo '<input type="text" id="event_location" name="event_location" value="' . esc_attr($event_location) . '" />';
}




// NoFestival - Save the custom field data when the post is saved
function nofestival_save_event_details($post_id) {
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
    if (!current_user_can('edit_post', $post_id)) return;

    $event_date = sanitize_text_field($_POST['event_date']);
    $event_start_time = sanitize_text_field($_POST['event_start_time']); // Added start time field
	$event_end_date = sanitize_text_field($_POST['event_end_date']); // Added end date field
    $event_end_time = sanitize_text_field($_POST['event_end_time']); // Added end time field
    $event_location = sanitize_text_field($_POST['event_location']);

    update_post_meta($post_id, '_event_date', $event_date);
    update_post_meta($post_id, '_event_start_time', $event_start_time); // Added start time field
	update_post_meta($post_id, '_event_end_date', $event_end_date); // Added end date field
    update_post_meta($post_id, '_event_end_time', $event_end_time); // Added end time field
    update_post_meta($post_id, '_event_location', $event_location);
}

add_action('add_meta_boxes', 'nofestival_add_event_details_metabox');
add_action('save_post', 'nofestival_save_event_details');

// Set the default timezone to Europe/Paris
date_default_timezone_set('Europe/Paris');

// NoFestival - Shortcode to display upcoming, happening, and past events
function nofestival_event_timeline_shortcode($atts) {
    // ...

    $args = array(
        'post_type'      => 'post',
        'meta_query'     => array(
            'relation' => 'AND',
            array(
                'key'     => '_event_date',
                'compare' => 'EXISTS', // Check if the meta key exists
            ),
            array(
                'key'     => '_event_end_date',
                'compare' => 'EXISTS', // Check if the end date meta key exists
            ),
        ),
        'orderby'        => 'meta_value',
        'order'          => 'DESC',
        'posts_per_page' => -1,
    );

    $query = new WP_Query($args);

    if ($query->have_posts()) :
        echo '<div class="event-timeline">';

        // Use current date and time based on Europe/Paris timezone
        $current_date = date('Y-m-d');
        $current_time = date('H:i');

        while ($query->have_posts()) : $query->the_post();

            $event_date = get_post_meta(get_the_ID(), '_event_date', true);
			$event_end_date = get_post_meta(get_the_ID(), '_event_end_date', true);

          // Check if event_date is empty or invalid
            if (empty($event_date) || strtotime($event_date) === false) {
                continue;
            }

            $event_start_time = get_post_meta(get_the_ID(), '_event_start_time', true);
            $event_end_time = get_post_meta(get_the_ID(), '_event_end_time', true);

            // Use _event_date as the end date if _event_end_date is empty
            $event_end_date = empty($event_end_date) ? $event_date : $event_end_date;

            // Calculate the full event start and end date/time
            $event_start_datetime = strtotime($event_date . ' ' . $event_start_time);
            $event_end_datetime = strtotime($event_end_date . ' ' . $event_end_time);

            // Check if the current time is within the event's start and end time
            if (
    $current_date >= $event_date && $current_date <= $event_end_date &&
    $current_time >= $event_start_time && $current_time <= $event_end_time
) {
    // Happening event
    $happening_events[] = get_event_markup($event_date, $event_start_time, $event_end_time);
} elseif ($current_date <= $event_end_date && $current_date >= $event_date) {
    // Event spans multiple days, consider it happening
    $happening_events[] = get_event_markup($event_date, $event_start_time, $event_end_time);
} elseif ($current_date <= $event_end_date && ($current_date < $event_date || ($current_date == $event_date && $current_time < $event_start_time))) {
    // Upcoming event
    $upcoming_events[] = get_event_markup($event_date, $event_start_time, $event_end_time);
} else {
    // Past event
    $past_events[] = get_event_markup($event_date, $event_start_time, $event_end_time);
}

        endwhile;

        // Display happening events
        if (!empty($happening_events)) {
            echo '<div class="happening-section">';
            echo '<h2>HAPPENING!!</h2>';
            echo implode('', $happening_events);
            echo '</div>';
        }

        // Display upcoming events
        if (!empty($upcoming_events)) {
			echo '<div class="upcoming-section">';
            echo '<h2 sytle="border-bottom: solid 1px darkmagenta;">UPCOMING EVENTS</h2>';
            echo implode('', $upcoming_events);
        }

        // Display past events
        if (!empty($past_events)) {
            echo '<div class="past-events">';
            echo '<h2>PAST EVENTS</h2>';
            echo implode('', $past_events);
            echo '</div>';
        }

        echo '</div>';
        wp_reset_postdata();
    else :
        echo 'No events found.';
    endif;

    return ob_get_clean();
}

add_shortcode('event_timeline', 'nofestival_event_timeline_shortcode');


function custom_limit_excerpt_length($excerpt, $length = 100) {
    if (mb_strlen($excerpt, 'UTF-8') > $length) {
        $excerpt = mb_substr($excerpt, 0, $length - 3, 'UTF-8') . '...';
    }
    return $excerpt;
}

// Function to get event markup
function get_event_markup($event_date) {
    $event_start_time = get_post_meta(get_the_ID(), '_event_start_time', true);
    $event_end_time = get_post_meta(get_the_ID(), '_event_end_time', true);
    $event_location = get_post_meta(get_the_ID(), '_event_location', true);
    $event_end_date = get_post_meta(get_the_ID(), '_event_end_date', true);

    $markup = '<div class="event-item">';

    $markup .= '<h2 class="event-title"><i class="fa-solid fa-hand-pointer fa-rotate-90" style="color: #FF4F00"></i>  <a href="' . esc_url(get_permalink()) . '">' . get_the_title() . '</a></h2>';

    // Format the start date
    $formatted_start_date = date('D j M', strtotime($event_date));

    // Format the end date if available
    $formatted_end_date = !empty($event_end_date) ? ' <i class="fa-solid fa-angles-right"></i> ' . date('D j M', strtotime($event_end_date)) : '';

    $markup .= '<p class="event-date">' . $formatted_start_date . ' : ' . $event_start_time . ' - ' . $event_end_time . $formatted_end_date . '</p>';
    $markup .= '<p class="event-location">' . $event_location . '</p>';
    
    // Include other event details as needed
    // ...

    $excerpt = get_the_excerpt();
    $limited_excerpt = custom_limit_excerpt_length($excerpt, 100);
    $markup .= '<p class="event-excerpt">' . $limited_excerpt . '</p>';

    $markup .= '</div>';

    return $markup;
}

Here’s an updated version of your code that removes any prefix:

php

<?php $archive_title = get_the_archive_title(); $prefixes_to_remove = array('Category: ', 'Tag: '); // Add more prefixes if needed // Remove prefixes $trimmed_title = str_replace($prefixes_to_remove, '', $archive_title); echo '<h1 class="page-title">' . $trimmed_title . '</h1>'; the_archive_description( '<div class="archive-description">', '</div>' ); ?>

In this version, you can easily add more prefixes to the $prefixes_to_remove array if needed. The str_replace function will then remove any of the specified prefixes from the archive title.

Replace your existing code with this modification in your archives.php file.