// Add Event fields to Posts
add_action('add_meta_boxes', function () {
add_meta_box('post_event_details', 'Event details', function ($post) {
wp_nonce_field('native_event_meta','native_event_meta_nonce');
$ts = get_post_meta($post->ID,'event_timestamp', true);
$ext = get_post_meta($post->ID,'event_external_url', true);
$val = '';
if ($ts) {
$dt = new DateTime('@'.$ts);
$dt->setTimezone(wp_timezone());
$val = $dt->format('Y-m-d\TH:i');
}
echo '<p><label for="event_datetime">Event date & time</label><br>';
echo '<input type="datetime-local" id="event_datetime" name="event_datetime" value="'.esc_attr($val).'"></p>';
echo '<p><label for="event_external_url">More info URL (optional)</label><br>';
echo '<input type="url" id="event_external_url" name="event_external_url" class="widefat" value="'.esc_attr($ext).'"></p>';
echo '<p style="font-size:12px;color:#666">Set the Event date. Posts with a date in the future will appear in the Upcoming list.</p>';
}, 'post', 'side');
});
// Save Event fields
add_action('save_post', function ($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!isset($_POST['native_event_meta_nonce']) || !wp_verify_nonce($_POST['native_event_meta_nonce'], 'native_event_meta')) return;
if (!current_user_can('edit_post', $post_id)) return;
if (isset(_POST['event_datetime']) && _POST['event_datetime'] !== '') {
$tz = wp_timezone();
try {
$dt = new DateTime(sanitize_text_field($_POST['event_datetime']), $tz);
$utc = clone $dt; $utc->setTimezone(new DateTimeZone('UTC'));
update_post_meta($post_id, 'event_timestamp', $utc->getTimestamp());
} catch (Exception $e) {}
} else {
delete_post_meta($post_id, 'event_timestamp');
}
if (isset($_POST['event_external_url'])) {
$url = esc_url_raw($_POST['event_external_url']);
if ($url) update_post_meta($post_id,'event_external_url',$url);
else delete_post_meta($post_id,'event_external_url');
}
});
// Shortcode: [upcoming_events count="5" category="events" show_image="1"]
function native_upcoming_events_shortcode($atts) {
$a = shortcode_atts(array(
'count' => 5,
'category' => 'events',
'show_image' => '1'
), $atts, 'upcoming_events');
$args = array(
'post_type' => 'post',
'posts_per_page' => intval($a['count']),
'category_name' => sanitize_text_field($a['category']),
'meta_key' => 'event_timestamp',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(array(
'key' => 'event_timestamp',
'value' => time(),
'compare' => '>=',
'type' => 'NUMERIC'
)),
'no_found_rows' => true,
'cache_results' => false,
'update_post_meta_cache' => true,
'update_post_term_cache' => false,
);
$q = new WP_Query($args);
if (!$q->have_posts()) return '<div class="events-list empty">No upcoming events.</div>';
ob_start();
echo '<div class="events-list">';
while (q->have_posts()) { q->the_post();
$ts = (int) get_post_meta(get_the_ID(),'event_timestamp', true);
if (!$ts) continue;
$dt = new DateTime('@'.$ts); $dt->setTimezone(wp_timezone());
$date_str = $dt->format(get_option('date_format').' '.get_option('time_format'));
$ext = get_post_meta(get_the_ID(),'event_external_url', true);
$permalink = get_permalink();
$link = $permalink; // or use $ext if you prefer external
echo '<article class="event-item">';
if ($a['show_image'] && has_post_thumbnail()) {
echo '<a class="event-thumb" href="'.esc_url($link).'">'.get_the_post_thumbnail(get_the_ID(),'medium_large', array('loading'=>'lazy')).'</a>';
}
echo '<div class="event-body">';
echo '<h3 class="event-title"><a href="'.esc_url($link).'">'.esc_html(get_the_title()).'</a></h3>';
echo '<div class="event-meta">'.esc_html($date_str).'</div>';
echo '<div class="event-excerpt">'.wp_kses_post(get_the_excerpt()).'</div>';
if ($ext) echo '<p class="event-more"><a href="'.esc_url($ext).'" target="_blank" rel="noopener">More info</a></p>';
echo '</div></article>';
}
echo '</div>';
wp_reset_postdata();
return ob_get_clean();
}
add_shortcode('upcoming_events', 'native_upcoming_events_shortcode');
Optional CSS (nice layout)
.events-list{display:grid;gap:16px}
.event-item{display:flex;gap:16px;align-items:flex-start;padding:14px;border:1px solid #eee;border-radius:12px;background:#fff;box-shadow:0 4px 16px rgba(0,0,0,.06)}
.event-thumb img{display:block;width:160px;max-width:160px;height:auto;border-radius:8px}
.event-title{margin:0 0 6px}
.event-meta{font-size:.9rem;color:#666;margin-bottom:8px}
@media (max-width:700px){.event-item{flex-direction:column}.event-thumb img{width:100%;max-width:100%}}
/* filtered copy of the same background, above the real background, below content */
#header-bg::after,
.wp-block-group.header-blur::after {
content: "";
position: absolute;
inset: 0;
pointer-events: none;
z-index: 0;


/* copy background from the group element */
background-image: inherit;
background-position: inherit;
background-size: inherit;
background-repeat: inherit;
background-attachment: inherit;

/* apply effects */
filter: brightness(0.6) blur(6px) !important;
-webkit-filter: brightness(0.6) blur(6px) !important;

/* avoid blur “halo” cropping */
transform: scale(1.06);
transform-origin: center;
}

/* ensure the header contents stay above the filtered layer */
#header-bg > *,
.wp-block-group.header-blur > * {
position: relative;
z-index: 1;
}

/* Optional: extra dark overlay for contrast (adjust alpha) /
#header-bg::before,
.wp-block-group.header-blur::before {
content: "";
position: absolute;
inset: 0;
background: rgba(0,0,0,0.18);
pointer-events: none;
z-index: 1; / between background (z:0) and content (z:1 on children) */
}
/* Scope to your menu: add class "nav-fancy" to the Navigation block or menu wrapper /
.nav-fancy .wp-block-navigation__container,
.nav-fancy > ul {
display: flex;
align-items: center;
gap: 0; / we’ll create spacing with the divider rule */
}

/* Top-level item dividers (works for both block and classic menus) */
.nav-fancy .wp-block-navigation__container > li + li,
.nav-fancy > ul > li + li {
border-inline-start: 1px solid var(--nav-divider, rgba(0,0,0,.18));
margin-inline-start: 14px;
padding-inline-start: 14px;
}

/* Links: padding, rounded corners, and animated underline on hover */
.nav-fancy a {
position: relative;
display: inline-flex;
align-items: center;
padding: 8px 10px;
border-radius: 8px;
color: var(--nav-link, #222);
text-decoration: none;
transition: color .2s ease, background-color .2s ease;
}

/* Subtle background + underline on hover/focus */
.nav-fancy a:hover,
.nav-fancy a:focus-visible {
background: rgba(0,0,0,.06);
color: #000;
}

.nav-fancy a::after {
content: "";
position: absolute;
left: 10px;
right: 10px;
bottom: 6px;
height: 2px;
background: currentColor;
transform: scaleX(0);
transform-origin: left;
transition: transform .25s ease;
opacity: .7;
}

.nav-fancy a:hover::after,
.nav-fancy a:focus-visible::after {
transform: scaleX(1);
}

/* Keep submenus clean (no extra divider on nested items) */
.nav-fancy .wp-block-navigation__submenu-container > li,
.nav-fancy ul ul > li {
border: 0;
margin: 0;
padding: 0;
}

/* Mobile/stacked menu: switch to horizontal dividers */
@media (max-width: 782px) {
.nav-fancy .wp-block-navigation__container,
.nav-fancy > ul {
flex-direction: column;
align-items: stretch;
}
.nav-fancy .wp-block-navigation__container > li + li,
.nav-fancy > ul > li + li {
border-inline-start: 0;
border-top: 1px solid var(--nav-divider, rgba(0,0,0,.14));
margin-inline-start: 0;
padding-inline-start: 0;
margin-top: 6px;
padding-top: 6px;
}
}
