feat: one breadcrumb, same place and style on every inner page
- Plugin: vc_breadcrumb_trail()/vc_breadcrumb_html(); tours, region, city and tag pages show Home / (Region) / Page in the banner instead of the generic 'Tour & Travel' label; the tour page uses the same helper - Theme: blog list shows Home / Blog; blog post title, breadcrumb and meta move into the banner like the other pages - Shared style: title's colour (white in photo banners, black on About), softer links, current page bold and shortened if long - also on phones - Plugin 1.9.6, theme 1.0.16 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,13 +12,6 @@
|
||||
color: var(--c-ink);
|
||||
}
|
||||
|
||||
.vc-app.vc-app .tour__crumbs li[aria-current] {
|
||||
overflow: hidden;
|
||||
max-width: 28ch;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ---------- gallery: one large photo + two, the rest in the lightbox ---------- */
|
||||
.vc-app.vc-app .tgal {
|
||||
position: relative;
|
||||
@@ -162,12 +155,6 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* the tour name is the page title right below — keep the trail short */
|
||||
.vc-app.vc-app .tour__crumbs li[aria-current] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* Compact 2 × 2 facts instead of four stacked full-width cards. */
|
||||
.vc-app.vc-app .tour--top .facts {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
|
||||
@@ -266,6 +266,17 @@ class VC_Display {
|
||||
. '.vc-fullwidth .site-content,.vc-fullwidth .ast-container,'
|
||||
. '.vc-fullwidth .entry-content,.vc-fullwidth .site-main>article'
|
||||
. '{overflow:visible!important;}',
|
||||
// Breadcrumb — one style on every page (the theme's design pages use
|
||||
// the same rules): takes the colour of the title it sits above,
|
||||
// links softer, current page bold and shortened if long.
|
||||
'.vc-app.vc-app .crumbs{color:inherit;}',
|
||||
'.vc-app.vc-app .crumbs__list{color:inherit;font-size:.8125rem;font-weight:500;}',
|
||||
'.vc-app.vc-app .crumbs__list a{opacity:.75;}',
|
||||
'.vc-app.vc-app .crumbs__list a:hover{opacity:1;}',
|
||||
'.vc-app.vc-app .crumbs__list [aria-current]{max-width:min(40ch,60vw);overflow:hidden;font-weight:700;text-overflow:ellipsis;white-space:nowrap;}',
|
||||
'.vc-app.vc-app .hero__content>.crumbs{margin-block-end:calc(var(--sp-1) * -1);}',
|
||||
// In a banner the title is white, so the breadcrumb is too.
|
||||
'.vc-app.vc-app .hero .crumbs{color:var(--c-white);}',
|
||||
// FAQ question buttons must stay flat — Astra gives <button> a shadow.
|
||||
'.vc-app.vc-app .acc__q{box-shadow:none!important;}',
|
||||
// Astra colours every heading on the element itself (h1–h6 and
|
||||
|
||||
@@ -617,6 +617,64 @@ function vc_icon( $name, $extra_class = '' ) {
|
||||
return '<svg class="' . esc_attr( $class ) . '" aria-hidden="true"><use href="#' . esc_attr( $name ) . '"></use></svg>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Breadcrumb trail for the current Viator view: list of [label, url] links
|
||||
* (Home first); the current page itself is not included.
|
||||
* tours archive Home
|
||||
* region / city Home › Region (for a city)
|
||||
* tag / category Home › Tours
|
||||
* single tour Home › Region › City (its canonical city)
|
||||
* other pages Home
|
||||
*/
|
||||
function vc_breadcrumb_trail() {
|
||||
$trail = array( array( __( 'Home', 'viator-collector' ), home_url( '/' ) ) );
|
||||
|
||||
$city = null;
|
||||
if ( is_tax( 'viator_destination' ) ) {
|
||||
$term = get_queried_object();
|
||||
if ( $term instanceof WP_Term && $term->parent ) {
|
||||
$city = $term; // its parent (region) is added below
|
||||
}
|
||||
} elseif ( is_tax( array( 'viator_tag', 'viator_category' ) ) ) {
|
||||
$trail[] = array( __( 'Tours', 'viator-collector' ), get_post_type_archive_link( 'viator_tour' ) );
|
||||
} elseif ( is_singular( 'viator_tour' ) ) {
|
||||
$post_id = get_queried_object_id();
|
||||
$city_slug = class_exists( 'VC_Routing' ) ? VC_Routing::product_city( $post_id ) : '';
|
||||
$city = $city_slug ? get_term_by( 'slug', $city_slug, 'viator_destination' ) : null;
|
||||
if ( ! $city ) {
|
||||
$terms = get_the_terms( $post_id, 'viator_destination' );
|
||||
$city = ( $terms && ! is_wp_error( $terms ) ) ? $terms[0] : null;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $city instanceof WP_Term ) {
|
||||
if ( $city->parent ) {
|
||||
$region = get_term( $city->parent, 'viator_destination' );
|
||||
if ( $region instanceof WP_Term && ! is_wp_error( get_term_link( $region ) ) ) {
|
||||
$trail[] = array( $region->name, get_term_link( $region ) );
|
||||
}
|
||||
}
|
||||
// On a city archive the city is the current page, not a link.
|
||||
if ( is_singular( 'viator_tour' ) && ! is_wp_error( get_term_link( $city ) ) ) {
|
||||
$trail[] = array( $city->name, get_term_link( $city ) );
|
||||
}
|
||||
}
|
||||
|
||||
return apply_filters( 'vc_breadcrumb_trail', $trail );
|
||||
}
|
||||
|
||||
/**
|
||||
* Breadcrumb markup shared by every page (the theme's design pages print the
|
||||
* same structure): links, then the current page in bold.
|
||||
*/
|
||||
function vc_breadcrumb_html( array $trail, $current, $extra_class = '' ) {
|
||||
$out = '<nav class="crumbs' . ( $extra_class ? ' ' . esc_attr( $extra_class ) : '' ) . '" aria-label="' . esc_attr__( 'Breadcrumb', 'viator-collector' ) . '"><ol class="crumbs__list">';
|
||||
foreach ( $trail as $item ) {
|
||||
$out .= '<li><a href="' . esc_url( $item[1] ) . '">' . esc_html( $item[0] ) . '</a></li>';
|
||||
}
|
||||
return $out . '<li aria-current="page">' . esc_html( $current ) . '</li></ol></nav>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotating ring badge (the circular "BOOK NOW ·" anchor in the design).
|
||||
*
|
||||
|
||||
@@ -87,7 +87,12 @@ $vc_hero_img = vc_hero_image_source();
|
||||
</div>
|
||||
|
||||
<div class="container hero__content">
|
||||
<p class="pill hero__eyebrow"><?php echo esc_html__( 'Tour & Travel', 'viator-collector' ); ?></p>
|
||||
<?php
|
||||
// Short current-page label: "Tours" on the archive, the page's own
|
||||
// title on a page hosting [viator_listing], else the heading.
|
||||
$vc_crumb_current = ! empty( $vc_crumb_label ) ? $vc_crumb_label : ( is_page() ? get_the_title() : $vc_title );
|
||||
echo vc_breadcrumb_html( vc_breadcrumb_trail(), $vc_crumb_current ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
<h1 class="hero__title"><?php echo esc_html( $vc_title ); ?></h1>
|
||||
|
||||
<form class="filters" id="vc-filter-form" method="get" action="<?php echo esc_url( $vc_action ); ?>" novalidate>
|
||||
|
||||
@@ -38,37 +38,13 @@ while ( have_posts() ) :
|
||||
$lead = has_post_thumbnail( $post_id ) ? (string) get_the_post_thumbnail_url( $post_id, 'large' ) : $primary;
|
||||
$all = array_values( array_unique( array_filter( array_merge( array( $lead, $primary ), $gallery ) ) ) );
|
||||
|
||||
// Breadcrumb: Home › Region › City › Tour (the tour's canonical city).
|
||||
$crumbs = array( array( __( 'Home', 'viator-collector' ), home_url( '/' ) ) );
|
||||
$city_slug = class_exists( 'VC_Routing' ) ? VC_Routing::product_city( $post_id ) : '';
|
||||
$city = $city_slug ? get_term_by( 'slug', $city_slug, 'viator_destination' ) : null;
|
||||
if ( ! $city && $dest_terms && ! is_wp_error( $dest_terms ) ) {
|
||||
$city = $dest_terms[0];
|
||||
}
|
||||
if ( $city && $city->parent ) {
|
||||
$region = get_term( $city->parent, 'viator_destination' );
|
||||
if ( $region instanceof WP_Term && ! is_wp_error( get_term_link( $region ) ) ) {
|
||||
$crumbs[] = array( $region->name, get_term_link( $region ) );
|
||||
}
|
||||
}
|
||||
if ( $city && ! is_wp_error( get_term_link( $city ) ) ) {
|
||||
$crumbs[] = array( $city->name, get_term_link( $city ) );
|
||||
}
|
||||
|
||||
$book_href = $booking_url ? $booking_url : '#';
|
||||
$book_attrs = $booking_url ? ' target="_blank" rel="nofollow noopener"' : '';
|
||||
?>
|
||||
<div class="vc-app vc-single">
|
||||
<section class="section tour tour--top">
|
||||
<div class="container">
|
||||
<nav class="crumbs tour__crumbs" aria-label="<?php echo esc_attr__( 'Breadcrumb', 'viator-collector' ); ?>">
|
||||
<ol class="crumbs__list">
|
||||
<?php foreach ( $crumbs as $crumb ) : ?>
|
||||
<li><a href="<?php echo esc_url( $crumb[1] ); ?>"><?php echo esc_html( $crumb[0] ); ?></a></li>
|
||||
<?php endforeach; ?>
|
||||
<li aria-current="page"><?php the_title(); ?></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<?php echo vc_breadcrumb_html( vc_breadcrumb_trail(), get_the_title(), 'tour__crumbs' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</div>
|
||||
<div class="container tour__layout">
|
||||
<div class="tour__main">
|
||||
|
||||
@@ -4,13 +4,13 @@ defined('ABSPATH') || exit;
|
||||
/**
|
||||
* Plugin Name: Viator Collector
|
||||
* Description: Import Viator tours using the Viator Partner API and display them with native WordPress post types, templates, and shortcodes.
|
||||
* Version: 1.9.5
|
||||
* Version: 1.9.6
|
||||
* Author: Amir Bagheri
|
||||
* License: GPL-2.0-or-later
|
||||
* Text Domain: viator-collector
|
||||
*/
|
||||
|
||||
define('VC_VERSION', '1.9.5');
|
||||
define('VC_VERSION', '1.9.6');
|
||||
define('VC_PLUGIN_FILE', __FILE__);
|
||||
define('VC_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||
define('VC_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||
|
||||
Reference in New Issue
Block a user