feat: city guide on city pages (tagline, facts, About, seasons)

Editable per city under Viator tours > Destinations. Shown above the
tours on page 1 of an unfiltered listing only; filtering and paging jump
to the results. Text recovered from the six old /tour-destination/ pages
is imported once into empty guides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 09:58:54 +03:30
parent 466ea0ac5f
commit 2ded000a27
12 changed files with 846 additions and 10 deletions

View File

@@ -9,6 +9,7 @@ define( 'ABSPATH', __DIR__ . '/' );
require_once dirname( __DIR__ ) . '/includes/class-vc-structure.php';
require_once dirname( __DIR__ ) . '/includes/class-vc-tags.php';
require_once dirname( __DIR__ ) . '/includes/class-vc-city-guide.php';
function vc_assert_same( $expected, $actual, $msg = '' ) {
if ( $expected !== $actual ) {

View File

@@ -0,0 +1,46 @@
<?php
/**
* VC_City_Guide unit tests: bundled guide data and season months.
*/
function vc_test_bundled_guides() {
return include dirname( __DIR__ ) . '/data/city-guides.php';
}
function test_bundled_guides_use_known_fields() {
$fields = VC_City_Guide::fields();
foreach ( vc_test_bundled_guides() as $slug => $guide ) {
vc_assert_same( array(), array_values( array_diff( array_keys( $guide ), array_keys( $fields ) ) ), "unknown fields for $slug" );
}
}
function test_bundled_guides_have_core_text() {
foreach ( vc_test_bundled_guides() as $slug => $guide ) {
foreach ( array( 'tagline', 'language', 'currency', 'timezone', 'about_title', 'about' ) as $key ) {
vc_assert_same( true, ! empty( $guide[ $key ] ), "$slug.$key empty" );
}
vc_assert_same( false, (bool) preg_match( '/elementor|\{|\}/', implode( ' ', $guide ) ), "$slug has page junk" );
}
}
function test_bundled_guides_cover_old_pages() {
vc_assert_same(
array( 'las-vegas', 'miami', 'montreal', 'new-orleans', 'new-york-city', 'vancouver' ),
( function ( $k ) { sort( $k ); return $k; } )( array_keys( vc_test_bundled_guides() ) )
);
}
function test_empty_guide_detection() {
$blank = array_fill_keys( array_keys( VC_City_Guide::fields() ), '' );
vc_assert_same( true, VC_City_Guide::is_empty( $blank ) );
vc_assert_same( true, VC_City_Guide::is_empty( array_merge( $blank, array( 'southern' => true, 'about_image' => 'https://x/y.jpg' ) ) ) );
vc_assert_same( false, VC_City_Guide::is_empty( array_merge( $blank, array( 'winter' => 'Skate.' ) ) ) );
}
function test_season_months_flip_south() {
$north = VC_City_Guide::season_months( false );
$south = VC_City_Guide::season_months( true );
vc_assert_same( 'March – May', $north['spring'] );
vc_assert_same( 'September – November', $south['spring'] );
vc_assert_same( 'June – August', $south['winter'] );
}