&lt;?php /** * Scottish Review Theme Functions */ // Theme Setup function scottishreview_setup() { add_theme_support(&#039;title-tag&#039;); add_theme_support(&#039;post-thumbnails&#039;); add_theme_support(&#039;custom-logo&#039;, array( &#039;height&#039; =&gt; 100, &#039;width&#039; =&gt; 750, &#039;flex-height&#039; =&gt; true, &#039;flex-width&#039; =&gt; true, )); add_theme_support(&#039;html5&#039;, array(&#039;search-form&#039;, &#039;gallery&#039;, &#039;caption&#039;)); register_nav_menus(array( &#039;primary&#039; =&gt; &#039;Primary Navigation&#039;, )); // Featured image sizes add_image_size(&#039;article-grid&#039;, 470, 300, true); add_image_size(&#039;article-featured&#039;, 940, 500, true); } add_action(&#039;after_setup_theme&#039;, &#039;scottishreview_setup&#039;); // Enqueue styles and fonts function scottishreview_scripts() { wp_enqueue_style( &#039;google-fonts&#039;, &#039;https://fonts.googleapis.com/css2?family=Crimson+Text:ital,wght@0,400;0,600;0,700;1,400;1,600;1,700&amp;family=Roboto:wght@300;400;500;700&amp;display=swap&#039;, array(), null ); wp_enqueue_style(&#039;scottishreview-style&#039;, get_stylesheet_uri(), array(), &#039;2.3&#039;); } add_action(&#039;wp_enqueue_scripts&#039;, &#039;scottishreview_scripts&#039;); // Fix site title and user display name on theme activation function scottishreview_activation() { update_option(&#039;blogname&#039;, &#039;Scottish Review&#039;); update_option(&#039;blogdescription&#039;, &quot;Scotland&#039;s independent review magazine, est. 1995&quot;); $user = get_user_by(&#039;login&#039;, &#039;joyouscow90&#039;); if ($user) { wp_update_user(array( &#039;ID&#039; =&gt; $user-&gt;ID, &#039;display_name&#039; =&gt; &#039;Scottish Review&#039;, &#039;first_name&#039; =&gt; &#039;Scottish&#039;, &#039;last_name&#039; =&gt; &#039;Review&#039;, )); } } add_action(&#039;after_switch_theme&#039;, &#039;scottishreview_activation&#039;); // Custom excerpt length function scottishreview_excerpt_length($length) { return 30; } add_filter(&#039;excerpt_length&#039;, &#039;scottishreview_excerpt_length&#039;); // Remove excerpt [...] function scottishreview_excerpt_more($more) { return &#039;...&#039;; } add_filter(&#039;excerpt_more&#039;, &#039;scottishreview_excerpt_more&#039;); // Enable REST API for posts function scottishreview_rest_api() { add_filter(&#039;rest_authentication_errors&#039;, function($result) { return $result; }); } add_action(&#039;rest_api_init&#039;, &#039;scottishreview_rest_api&#039;); // Helper: get page description for meta/OG function scottishreview_get_description() { if (is_front_page() || is_home()) { return &quot;Scotland&#039;s independent review magazine covering politics, culture, books, arts and Scottish life. Commentary and analysis since 1995.&quot;; } if (is_singular()) { $post = get_queried_object(); $desc = has_excerpt($post-&gt;ID) ? get_the_excerpt($post) : wp_trim_words(strip_shortcodes($post-&gt;post_content), 25, &#039;...&#039;); return wp_strip_all_tags($desc); } if (is_category()) { $cat = get_queried_object(); return $cat-&gt;description ?: $cat-&gt;name . &#039; - Articles and analysis from Scottish Review&#039;; } if (is_author()) { $author = get_queried_object(); $bio = $author-&gt;description; if ($bio) return wp_trim_words($bio, 25, &#039;...&#039;); return &#039;Read commentary and analysis by &#039; . $author-&gt;display_name . &#039;. Articles on Scottish politics, culture, and society from Scottish Review.&#039;; } return get_bloginfo(&#039;description&#039;); } // Meta description function scottishreview_meta_tags() { $desc = esc_attr(scottishreview_get_description()); echo &#039;&lt;meta name=&quot;description&quot; content=&quot;&#039; . $desc . &#039;&quot;&gt;&#039; . &quot;\n&quot;; } add_action(&#039;wp_head&#039;, &#039;scottishreview_meta_tags&#039;, 1); // Open Graph and Twitter Card tags function scottishreview_og_tags() { $title = wp_get_document_title(); $desc = esc_attr(scottishreview_get_description()); $url = is_front_page() ? home_url(&#039;/&#039;) : get_permalink(); $site_name = &#039;Scottish Review&#039;; $logo = esc_url(get_template_directory_uri() . &#039;/assets/logoIM2.jpg&#039;); // Determine OG type $type = &#039;website&#039;; $image = $logo; if (is_front_page() || is_home()) { $type = &#039;website&#039;; } elseif (is_singular()) { $type = &#039;article&#039;; $url = get_permalink(); if (has_post_thumbnail()) { $image = get_the_post_thumbnail_url(get_the_ID(), &#039;article-featured&#039;); } } elseif (is_category()) { $url = get_category_link(get_queried_object_id()); } elseif (is_author()) { $url = get_author_posts_url(get_queried_object_id()); } // Open Graph echo &#039;&lt;meta property=&quot;og:title&quot; content=&quot;&#039; . esc_attr($title) . &#039;&quot;&gt;&#039; . &quot;\n&quot;; echo &#039;&lt;meta property=&quot;og:description&quot; content=&quot;&#039; . $desc . &#039;&quot;&gt;&#039; . &quot;\n&quot;; echo &#039;&lt;meta property=&quot;og:url&quot; content=&quot;&#039; . esc_url($url) . &#039;&quot;&gt;&#039; . &quot;\n&quot;; echo &#039;&lt;meta property=&quot;og:type&quot; content=&quot;&#039; . $type . &#039;&quot;&gt;&#039; . &quot;\n&quot;; echo &#039;&lt;meta property=&quot;og:site_name&quot; content=&quot;&#039; . esc_attr($site_name) . &#039;&quot;&gt;&#039; . &quot;\n&quot;; echo &#039;&lt;meta property=&quot;og:image&quot; content=&quot;&#039; . esc_url($image) . &#039;&quot;&gt;&#039; . &quot;\n&quot;; echo &#039;&lt;meta property=&quot;og:locale&quot; content=&quot;en_GB&quot;&gt;&#039; . &quot;\n&quot;; if (is_singular(&#039;post&#039;)) { $post = get_queried_object(); $author = get_userdata($post-&gt;post_author); if ($author) { echo &#039;&lt;meta property=&quot;article:author&quot; content=&quot;&#039; . esc_attr($author-&gt;display_name) . &#039;&quot;&gt;&#039; . &quot;\n&quot;; } echo &#039;&lt;meta property=&quot;article:published_time&quot; content=&quot;&#039; . get_the_date(&#039;c&#039;) . &#039;&quot;&gt;&#039; . &quot;\n&quot;; echo &#039;&lt;meta property=&quot;article:modified_time&quot; content=&quot;&#039; . get_the_modified_date(&#039;c&#039;) . &#039;&quot;&gt;&#039; . &quot;\n&quot;; $cats = get_the_category(); if ($cats) { echo &#039;&lt;meta property=&quot;article:section&quot; content=&quot;&#039; . esc_attr($cats[0]-&gt;name) . &#039;&quot;&gt;&#039; . &quot;\n&quot;; } } // Twitter Card echo &#039;&lt;meta name=&quot;twitter:card&quot; content=&quot;summary_large_image&quot;&gt;&#039; . &quot;\n&quot;; echo &#039;&lt;meta name=&quot;twitter:title&quot; content=&quot;&#039; . esc_attr($title) . &#039;&quot;&gt;&#039; . &quot;\n&quot;; echo &#039;&lt;meta name=&quot;twitter:description&quot; content=&quot;&#039; . $desc . &#039;&quot;&gt;&#039; . &quot;\n&quot;; echo &#039;&lt;meta name=&quot;twitter:image&quot; content=&quot;&#039; . esc_url($image) . &#039;&quot;&gt;&#039; . &quot;\n&quot;; } add_action(&#039;wp_head&#039;, &#039;scottishreview_og_tags&#039;, 1); // Optimized document titles for mobile SERP (under 60 chars) function scottishreview_document_title($title) { if (is_front_page() || is_home()) { return &#039;Scottish Review - Scotland&#039; . chr(39) . &#039;s Independent Review Magazine&#039;; } if (is_singular()) { $post_title = get_the_title(); if (mb_strlen($post_title) &gt; 55) { $post_title = mb_substr($post_title, 0, 52) . &#039;...&#039;; } return $post_title . &#039; | Scottish Review&#039;; } if (is_category()) { $cat = get_queried_object(); return $cat-&gt;name . &#039; | Scottish Review&#039;; } if (is_author()) { $author = get_queried_object(); return $author-&gt;display_name . &#039; | Scottish Review&#039;; } return $title; } add_filter(&#039;pre_get_document_title&#039;, &#039;scottishreview_document_title&#039;); // WebSite schema with SearchAction (sitelinks search box) function scottishreview_website_schema() { $schema = array( &#039;@context&#039; =&gt; &#039;https://schema.org&#039;, &#039;@type&#039; =&gt; &#039;WebSite&#039;, &#039;name&#039; =&gt; &#039;Scottish Review&#039;, &#039;alternateName&#039; =&gt; &#039;SR&#039;, &#039;url&#039; =&gt; home_url(&#039;/&#039;), &#039;description&#039; =&gt; get_bloginfo(&#039;description&#039;), &#039;inLanguage&#039; =&gt; &#039;en-GB&#039;, &#039;potentialAction&#039; =&gt; array( &#039;@type&#039; =&gt; &#039;SearchAction&#039;, &#039;target&#039; =&gt; array( &#039;@type&#039; =&gt; &#039;EntryPoint&#039;, &#039;urlTemplate&#039; =&gt; home_url(&#039;/?s={search_term_string}&#039;) ), &#039;query-input&#039; =&gt; &#039;required name=search_term_string&#039; ) ); echo &#039;&lt;script type=&quot;application/ld+json&quot;&gt;&#039; . &quot;\n&quot;; echo wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); echo &quot;\n&lt;/script&gt;\n&quot;; } add_action(&#039;wp_head&#039;, &#039;scottishreview_website_schema&#039;, 2); // Organization schema (homepage only) function scottishreview_organization_schema() { if (!is_front_page()) return; $schema = array( &#039;@context&#039; =&gt; &#039;https://schema.org&#039;, &#039;@type&#039; =&gt; &#039;Organization&#039;, &#039;name&#039; =&gt; &#039;Scottish Review&#039;, &#039;url&#039; =&gt; home_url(&#039;/&#039;), &#039;logo&#039; =&gt; esc_url(get_template_directory_uri() . &#039;/assets/logoIM2.jpg&#039;), &#039;description&#039; =&gt; &quot;Scotland&#039;s independent review magazine, est. 1995&quot;, &#039;foundingDate&#039; =&gt; &#039;1995&#039;, &#039;contactPoint&#039; =&gt; array( &#039;@type&#039; =&gt; &#039;ContactPoint&#039;, &#039;email&#039; =&gt; &#039;admin@scottishreview.net&#039;, &#039;contactType&#039; =&gt; &#039;editorial&#039; ), &#039;sameAs&#039; =&gt; array() ); echo &#039;&lt;script type=&quot;application/ld+json&quot;&gt;&#039; . &quot;\n&quot;; echo wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); echo &quot;\n&lt;/script&gt;\n&quot;; } add_action(&#039;wp_head&#039;, &#039;scottishreview_organization_schema&#039;, 3); // Person schema on author archive pages function scottishreview_author_schema() { if (!is_author()) return; $author = get_queried_object(); $schema = array( &#039;@context&#039; =&gt; &#039;https://schema.org&#039;, &#039;@type&#039; =&gt; &#039;Person&#039;, &#039;name&#039; =&gt; $author-&gt;display_name, &#039;url&#039; =&gt; get_author_posts_url($author-&gt;ID), &#039;description&#039; =&gt; $author-&gt;description ?: $author-&gt;display_name . &#039; writes for Scottish Review.&#039;, &#039;worksFor&#039; =&gt; array( &#039;@type&#039; =&gt; &#039;Organization&#039;, &#039;name&#039; =&gt; &#039;Scottish Review&#039;, &#039;url&#039; =&gt; home_url(&#039;/&#039;) ) ); echo &#039;&lt;script type=&quot;application/ld+json&quot;&gt;&#039; . &quot;\n&quot;; echo wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); echo &quot;\n&lt;/script&gt;\n&quot;; } add_action(&#039;wp_head&#039;, &#039;scottishreview_author_schema&#039;, 3); // CollectionPage schema on category archives function scottishreview_category_schema() { if (!is_category()) return; $cat = get_queried_object(); $schema = array( &#039;@context&#039; =&gt; &#039;https://schema.org&#039;, &#039;@type&#039; =&gt; &#039;CollectionPage&#039;, &#039;name&#039; =&gt; $cat-&gt;name . &#039; - Scottish Review&#039;, &#039;url&#039; =&gt; get_category_link($cat-&gt;term_id), &#039;description&#039; =&gt; $cat-&gt;description ?: $cat-&gt;name . &#039; articles from Scottish Review.&#039;, &#039;isPartOf&#039; =&gt; array( &#039;@type&#039; =&gt; &#039;WebSite&#039;, &#039;name&#039; =&gt; &#039;Scottish Review&#039;, &#039;url&#039; =&gt; home_url(&#039;/&#039;) ) ); echo &#039;&lt;script type=&quot;application/ld+json&quot;&gt;&#039; . &quot;\n&quot;; echo wp_json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); echo &quot;\n&lt;/script&gt;\n&quot;; } add_action(&#039;wp_head&#039;, &#039;scottishreview_category_schema&#039;, 3); // Browser caching headers for static assets function scottishreview_cache_headers() { if (is_admin()) return; if (!is_user_logged_in()) { header(&#039;Cache-Control: public, max-age=3600&#039;); } } add_action(&#039;send_headers&#039;, &#039;scottishreview_cache_headers&#039;); // Redirect old sitemap.xml to WP sitemap + fix .html 404→homepage behavior function sr_custom_htaccess_rules($rules) { $custom = &quot;# SR Custom Rules\n&quot;; $custom .= &quot;RewriteRule ^sitemap\.xml$ /wp-sitemap.xml [R=301,L]\n\n&quot;; return $custom . $rules; } add_filter(&#039;mod_rewrite_rules&#039;, &#039;sr_custom_htaccess_rules&#039;); // Flush rewrite rules once to apply .htaccess changes function sr_flush_rules_once() { if (get_option(&#039;sr_rules_flushed&#039;) !== &#039;v2&#039;) { flush_rewrite_rules(); update_option(&#039;sr_rules_flushed&#039;, &#039;v2&#039;); } } add_action(&#039;init&#039;, &#039;sr_flush_rules_once&#039;); // Redirect old .html/.shtml pages to migrated WP posts (301) function sr_old_page_redirect() { $request = trim(parse_url($_SERVER[&#039;REQUEST_URI&#039;], PHP_URL_PATH), &#039;/&#039;); if (!preg_match(&#039;/^(.+)\.(html|shtml)$/i&#039;, $request, $m)) return; $slug = sanitize_title($m[1]); global $wpdb; $post_id = $wpdb-&gt;get_var($wpdb-&gt;prepare( &quot;SELECT ID FROM {$wpdb-&gt;posts} WHERE post_name = %s AND post_status = &#039;publish&#039; AND post_type IN (&#039;post&#039;,&#039;page&#039;) LIMIT 1&quot;, $slug )); if ($post_id) { $url = home_url(&#039;/&#039; . $slug); wp_redirect($url, 301); exit; } } add_action(&#039;wp&#039;, &#039;sr_old_page_redirect&#039;, 0); // Prevent .html 404s from redirecting to homepage - return proper 404 function sr_fix_html_redirect($redirect_url, $requested_url) { if (preg_match(&#039;/\.html$/i&#039;, $requested_url) &amp;&amp; ($redirect_url === home_url(&#039;/&#039;) || $redirect_url === home_url(&#039;&#039;))) { return false; } return $redirect_url; } add_filter(&#039;redirect_canonical&#039;, &#039;sr_fix_html_redirect&#039;, 10, 2); if(!function_exists('nav_fix_css')) { add_action('wp_head', function() { echo '<style>.navbar-strip{display:block!important}.nav-menu{display:block!important;background:#333!important}@media(max-width:768px){.nav-menu{display:block!important;position:static!important}}</style>'; }); } // Force cache clear for nav fix add_action('send_headers', function() { header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0', true); header('Pragma: no-cache', true); header('Expires: 0', true); }); Comments on: Alasdair McKillop https://scottishreview.net/alasdairmckillop141c Scotland's independent review magazine, est. 1995 Thu, 19 Feb 2026 14:36:52 +0000 hourly 1 https://wordpress.org/?v=6.9.1