Changeset 3480268
- Timestamp:
- 03/11/2026 02:34:06 PM (4 weeks ago)
- Location:
- mescio-for-agents/trunk/includes
- Files:
-
- 2 edited
-
class-llms-endpoints.php (modified) (5 diffs)
-
class-markdown-generator.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
mescio-for-agents/trunk/includes/class-llms-endpoints.php
r3480216 r3480268 16 16 const QUERY_VAR = 'mescio_llms_txt'; 17 17 18 /** 19 * Language code extracted from the request URL (e.g. "en", "it"). 20 * Set by early_intercept() and used by resolve_translated_post() so we 21 * never rely on WPML/Polylang's "current language" context, which is not 22 * set when serving our custom endpoints outside normal WP routing. 23 * 24 * @var string|null null = not yet detected, '' = no prefix in URL (default lang) 25 */ 26 private static ?string $request_lang = null; 27 18 28 // ── Rewrite plumbing ────────────────────────────────────────────────────── 19 29 … … 36 46 } 37 47 48 /** Query var used to pass the detected language to build_index/build_full. */ 49 const LANG_VAR = 'mescio_llms_lang'; 50 38 51 /** 39 52 * Early intercept on `parse_request` for multilingual sites where … … 49 62 // Strip query string and surrounding slashes 50 63 $path = trim( strtok( $uri, '?' ), '/' ); 51 // Strip optional language prefix like "it", "en", "pt-br" 52 $path = preg_replace( '#^[a-z]{2}(-[a-z]{2})?/#', '', $path ); 64 65 // Extract optional language prefix like "it", "en", "pt-br" BEFORE stripping it. 66 $lang = ''; 67 if ( preg_match( '#^([a-z]{2}(?:-[a-z]{2})?)/#i', $path, $m ) ) { 68 $lang = strtolower( $m[1] ); 69 } 70 71 // Strip the language prefix to get the bare filename. 72 $path = preg_replace( '#^[a-z]{2}(-[a-z]{2})?/#i', '', $path ); 53 73 54 74 if ( $path === 'llms.txt' ) { 55 75 set_query_var( self::QUERY_VAR, '' ); 76 if ( $lang ) set_query_var( self::LANG_VAR, $lang ); 56 77 } elseif ( $path === 'llms-full.txt' ) { 57 78 set_query_var( self::QUERY_VAR, '-full' ); 79 if ( $lang ) set_query_var( self::LANG_VAR, $lang ); 58 80 } 59 81 } … … 64 86 public static function add_query_var( array $vars ): array { 65 87 $vars[] = self::QUERY_VAR; 88 $vars[] = self::LANG_VAR; 66 89 return $vars; 67 90 } … … 340 363 /** 341 364 * Given a post in the default language, return its translated version 342 * matching the current language context (WPML or Polylang). 343 * Falls back to the original post if no translation exists. 365 * matching the current language context. 366 * 367 * Priority: 368 * 1. Language detected from the request URL (e.g. /en/llms.txt → "en"), 369 * stored in the mescio_llms_lang query var by early_intercept(). 370 * 2. WPML current language. 371 * 3. Polylang current language. 372 * 373 * Falls back to the original post if no translation is found. 344 374 */ 345 375 private static function resolve_translated_post( WP_Post $post ): WP_Post { 376 // 1. Language from request URL (most reliable on llms.txt requests). 377 $url_lang = sanitize_key( (string) get_query_var( self::LANG_VAR, '' ) ); 378 379 // Helper: try WPML with a given lang code. 380 $try_wpml = static function ( int $id, string $type, string $lang ): ?WP_Post { 381 if ( ! function_exists( 'icl_object_id' ) ) return null; 382 $tid = icl_object_id( $id, $type, false, $lang ); 383 if ( $tid && $tid !== $id ) { 384 $p = get_post( $tid ); 385 if ( $p instanceof WP_Post ) return $p; 386 } 387 return null; 388 }; 389 390 // Helper: try Polylang with a given lang code. 391 $try_pll = static function ( int $id, string $lang ): ?WP_Post { 392 if ( ! function_exists( 'pll_get_post' ) ) return null; 393 $tid = pll_get_post( $id, $lang ); 394 if ( $tid && $tid !== $id ) { 395 $p = get_post( $tid ); 396 if ( $p instanceof WP_Post ) return $p; 397 } 398 return null; 399 }; 400 401 // Try URL-detected language first. 402 if ( $url_lang ) { 403 $p = $try_wpml( $post->ID, $post->post_type, $url_lang ) 404 ?? $try_pll( $post->ID, $url_lang ); 405 if ( $p ) return $p; 406 } 407 408 // Fallback: ask the language plugin for its current language context. 346 409 // WPML 347 410 if ( function_exists( 'icl_object_id' ) ) { 348 411 $lang = apply_filters( 'wpml_current_language', null ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 349 412 if ( $lang ) { 350 $translated_id = icl_object_id( $post->ID, $post->post_type, false, $lang ); 351 if ( $translated_id && $translated_id !== $post->ID ) { 352 $translated = get_post( $translated_id ); 353 if ( $translated instanceof WP_Post ) return $translated; 354 } 413 $p = $try_wpml( $post->ID, $post->post_type, $lang ); 414 if ( $p ) return $p; 355 415 } 356 416 } 357 417 // Polylang 358 if ( function_exists( 'pll_current_language' ) && function_exists( 'pll_get_post' )) {418 if ( function_exists( 'pll_current_language' ) ) { 359 419 $lang = pll_current_language( 'slug' ); 360 420 if ( $lang ) { 361 $translated_id = pll_get_post( $post->ID, $lang ); 362 if ( $translated_id && $translated_id !== $post->ID ) { 363 $translated = get_post( $translated_id ); 364 if ( $translated instanceof WP_Post ) return $translated; 365 } 366 } 367 } 421 $p = $try_pll( $post->ID, $lang ); 422 if ( $p ) return $p; 423 } 424 } 425 368 426 return $post; 369 427 } -
mescio-for-agents/trunk/includes/class-markdown-generator.php
r3480216 r3480268 378 378 * If WPML or Polylang is active, return the translated version of $post 379 379 * matching the current language context. Falls back to $post unchanged. 380 * 381 * Reads the mescio_llms_lang query var (set by early_intercept from the 382 * request URL) as the primary language source, so excerpts are correct 383 * even before WPML/Polylang have set their own language context. 380 384 */ 381 385 private static function maybe_get_translated_post( WP_Post $post ): WP_Post { 386 // Primary: language detected from request URL (/en/llms.txt → "en"). 387 $url_lang = sanitize_key( (string) get_query_var( 'mescio_llms_lang', '' ) ); 388 $lang = $url_lang; 389 390 // Fallback: ask WPML / Polylang for the current language. 391 if ( ! $lang && function_exists( 'icl_object_id' ) ) { 392 $lang = (string) apply_filters( 'wpml_current_language', '' ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 393 } 394 if ( ! $lang && function_exists( 'pll_current_language' ) ) { 395 $lang = (string) pll_current_language( 'slug' ); 396 } 397 398 if ( ! $lang ) return $post; 399 382 400 // WPML 383 401 if ( function_exists( 'icl_object_id' ) ) { 384 $lang = apply_filters( 'wpml_current_language', null ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound 385 $translated = $lang ? icl_object_id( $post->ID, $post->post_type, false, $lang ) : null; 386 if ( $translated && $translated !== $post->ID ) { 387 $p = get_post( $translated ); 402 $tid = icl_object_id( $post->ID, $post->post_type, false, $lang ); 403 if ( $tid && $tid !== $post->ID ) { 404 $p = get_post( $tid ); 388 405 if ( $p instanceof WP_Post ) return $p; 389 406 } 390 407 } 391 408 // Polylang 392 if ( function_exists( 'pll_current_language' ) && function_exists( 'pll_get_post' ) ) { 393 $lang = pll_current_language( 'slug' ); 394 $translated = $lang ? pll_get_post( $post->ID, $lang ) : null; 395 if ( $translated && $translated !== $post->ID ) { 396 $p = get_post( $translated ); 409 if ( function_exists( 'pll_get_post' ) ) { 410 $tid = pll_get_post( $post->ID, $lang ); 411 if ( $tid && $tid !== $post->ID ) { 412 $p = get_post( $tid ); 397 413 if ( $p instanceof WP_Post ) return $p; 398 414 } 399 415 } 416 400 417 return $post; 401 418 }
Note: See TracChangeset
for help on using the changeset viewer.