- WordPress core y plugins - Tema Twenty Twenty-Four configurado - Plugin allow-unfiltered-html.php simplificado - .gitignore configurado para excluir wp-config.php y uploads 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
322 lines
8.4 KiB
PHP
Executable File
322 lines
8.4 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* The llms.txt module.
|
|
*
|
|
* @package RankMath
|
|
* @subpackage RankMath\LLMS
|
|
*/
|
|
|
|
namespace RankMath\LLMS;
|
|
|
|
use RankMath\Helper;
|
|
use RankMath\Traits\Hooker;
|
|
use RankMath\Helpers\Arr;
|
|
use RankMath\Sitemap\Sitemap;
|
|
use RankMath\Sitemap\Router;
|
|
use RankMath\Helpers\Url;
|
|
use WP_Query;
|
|
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
/**
|
|
* LLMS_Txt class.
|
|
*/
|
|
class LLMS_Txt {
|
|
use Hooker;
|
|
|
|
/**
|
|
* Class constructor.
|
|
*
|
|
* Registers hooks and filters for the llms.txt module.
|
|
*/
|
|
public function __construct() {
|
|
$this->action( 'init', 'add_rewrite_rule' );
|
|
$this->action( 'template_redirect', 'maybe_serve_llms_txt' );
|
|
$this->filter( 'rank_math/settings/general', 'add_settings' );
|
|
$this->action( 'wp_loaded', 'remove_canonical_redirect' );
|
|
}
|
|
|
|
/**
|
|
* Remove the canonical redirect for the llms.txt file.
|
|
*
|
|
* @hook wp_loaded
|
|
* @return void
|
|
*/
|
|
public function remove_canonical_redirect() {
|
|
if ( strpos( Url::get_current_url(), '/llms.txt' ) !== false ) {
|
|
remove_filter( 'template_redirect', 'redirect_canonical' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add the llms.txt settings tab to the General settings panel.
|
|
*
|
|
* @hook rank_math/settings/general
|
|
*
|
|
* @param array $tabs Option panel tabs.
|
|
* @return array Modified tabs array with llms.txt tab added.
|
|
*/
|
|
public function add_settings( $tabs ) {
|
|
Arr::insert(
|
|
$tabs,
|
|
[
|
|
'llms' => [
|
|
'icon' => 'rm-icon rm-icon-bot',
|
|
'title' => esc_html__( 'Edit llms.txt', 'rank-math' ),
|
|
'desc' => esc_html__( 'Configure your llms.txt file for custom crawling/indexing rules.', 'rank-math' ),
|
|
'file' => __DIR__ . '/options.php',
|
|
'classes' => 'rank-math-advanced-option',
|
|
'json' => [
|
|
'llmsUrl' => esc_url( home_url( '/llms.txt' ) ),
|
|
],
|
|
],
|
|
],
|
|
5
|
|
);
|
|
return $tabs;
|
|
}
|
|
|
|
/**
|
|
* Add the rewrite rule and query var for llms.txt.
|
|
*
|
|
* @hook init
|
|
* @return void
|
|
*/
|
|
public function add_rewrite_rule() {
|
|
add_rewrite_rule( '^llms\.txt$', 'index.php?llms_txt=1', 'top' );
|
|
add_rewrite_tag( '%llms_txt%', '1' );
|
|
}
|
|
|
|
/**
|
|
* Serve the llms.txt file if the endpoint is hit.
|
|
*
|
|
* @hook template_redirect
|
|
* @return void
|
|
*/
|
|
public function maybe_serve_llms_txt() {
|
|
if ( intval( get_query_var( 'llms_txt' ) ) !== 1 ) {
|
|
return;
|
|
}
|
|
|
|
if ( substr( Url::get_current_url(), -1 ) === '/' ) {
|
|
wp_safe_redirect( home_url( '/llms.txt' ) );
|
|
exit;
|
|
}
|
|
|
|
$this->output();
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Output the llms.txt file content in Markdown format.
|
|
*
|
|
* @action rank_math/llms_txt/before_output Fires before llms.txt output is sent.
|
|
* @action rank_math/llms_txt/after_output Fires after llms.txt output is sent.
|
|
* @filter rank_math/llms_txt/posts_query_args Filter WP_Query args for posts.
|
|
* @filter rank_math/llms_txt/posts Filter post IDs to include.
|
|
* @filter rank_math/llms_txt/terms Filter term IDs to include.
|
|
* @filter rank_math/llms_txt/extra_content Filter extra content output.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function output() {
|
|
if ( headers_sent() ) {
|
|
return;
|
|
}
|
|
|
|
header( 'Content-Type: text/plain; charset=utf-8' );
|
|
header( 'X-Robots-Tag: noindex, nofollow', true );
|
|
/**
|
|
* Fires before the llms.txt output is sent to the browser.
|
|
*
|
|
* @since 1.0.250
|
|
*/
|
|
$this->do_action( 'llms_txt/before_output' );
|
|
|
|
$limit = absint( Helper::get_settings( 'general.llms_limit', 100 ) );
|
|
$this->add_header_content();
|
|
$this->add_post_types_data( $limit );
|
|
$this->add_taxonomies_data( $limit );
|
|
$this->add_extra_content();
|
|
|
|
/**
|
|
* Fires after the llms.txt output is sent to the browser.
|
|
*
|
|
* @since 1.0.250
|
|
*/
|
|
$this->do_action( 'llms_txt/after_output' );
|
|
}
|
|
|
|
/**
|
|
* Adds header content to the llms.txt output.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function add_header_content() {
|
|
$site_title = Helper::get_settings( 'titles.knowledgegraph_name', get_bloginfo( 'name' ) );
|
|
$site_desc = Helper::get_settings( 'titles.organization_description', get_bloginfo( 'description' ) );
|
|
$site_title .= $site_desc ? ': ' . $site_desc : '';
|
|
|
|
$this->output_line( 'Generated by Rank Math SEO, this is an llms.txt file designed to help LLMs better understand and index this website.' );
|
|
$this->output_line( '' );
|
|
$this->output_line( '# ' . esc_html( $site_title ) );
|
|
|
|
if ( ! Helper::is_module_active( 'sitemap' ) ) {
|
|
return;
|
|
}
|
|
|
|
$this->output_line( '' );
|
|
$sitemap_url = Router::get_base_url( Sitemap::get_sitemap_index_slug() . '.xml' );
|
|
$this->output_line( '## Sitemaps' );
|
|
$this->output_line( '[XML Sitemap](' . esc_url( $sitemap_url ) . '): Includes all crawlable and indexable pages.' );
|
|
// Add an extra blank line after the header content.
|
|
$this->output_line( '' );
|
|
}
|
|
|
|
/**
|
|
* Adds post type data to the llms.txt output.
|
|
*
|
|
* @param int $limit The maximum number of posts to include per post type.
|
|
* @return void
|
|
*/
|
|
private function add_post_types_data( $limit ) {
|
|
$post_types = Helper::get_settings( 'general.llms_post_types', [] );
|
|
if ( empty( $post_types ) ) {
|
|
return;
|
|
}
|
|
|
|
foreach ( $post_types as $post_type ) {
|
|
$args = [
|
|
'post_type' => $post_type,
|
|
'post_status' => 'publish',
|
|
'posts_per_page' => $limit,
|
|
'no_found_rows' => true,
|
|
];
|
|
|
|
/**
|
|
* Filter the WP_Query arguments used to fetch posts for llms.txt.
|
|
*
|
|
* @since 1.0.250
|
|
* @param array $args The WP_Query arguments.
|
|
* @return array Modified WP_Query arguments.
|
|
*/
|
|
$args = $this->do_filter( 'llms_txt/posts_query_args', $args );
|
|
$query = new \WP_Query( $args );
|
|
|
|
/**
|
|
* Filter the list of post IDs to be included in llms.txt for a post type.
|
|
*
|
|
* @since 1.0.250
|
|
* @param array $posts List of posts.
|
|
* @param array $args The WP_Query arguments.
|
|
* @return array Modified list of post IDs.
|
|
*/
|
|
$posts = $this->do_filter( 'llms_txt/posts', $query->posts, $args );
|
|
if ( empty( $posts ) ) {
|
|
continue;
|
|
}
|
|
|
|
$label = get_post_type_object( $post_type )->labels->name;
|
|
$this->output_line( '## ' . esc_html( $label ) );
|
|
|
|
foreach ( $posts as $object ) {
|
|
if ( ! Helper::is_post_indexable( $object ) ) {
|
|
continue;
|
|
}
|
|
|
|
$title = get_the_title( $object );
|
|
$link = get_permalink( $object );
|
|
$desc = wp_strip_all_tags( Helper::replace_vars( '%excerpt%', $object ) );
|
|
|
|
$this->output_line(
|
|
$desc
|
|
? '- [' . esc_html( $title ) . '](' . esc_url( $link ) . '): ' . esc_html( $desc )
|
|
: '- [' . esc_html( $title ) . '](' . esc_url( $link ) . ')'
|
|
);
|
|
}
|
|
$this->output_line( '' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds taxonomy data to the llms.txt output.
|
|
*
|
|
* @param int $limit The maximum number of terms to include per taxonomy.
|
|
* @return void
|
|
*/
|
|
private function add_taxonomies_data( $limit ) {
|
|
$taxonomies = Helper::get_settings( 'general.llms_taxonomies', [] );
|
|
if ( empty( $taxonomies ) ) {
|
|
return;
|
|
}
|
|
|
|
foreach ( $taxonomies as $taxonomy ) {
|
|
$tax_obj = get_taxonomy( $taxonomy );
|
|
if ( ! $tax_obj ) {
|
|
continue;
|
|
}
|
|
|
|
$terms = get_terms(
|
|
[
|
|
'taxonomy' => $taxonomy,
|
|
'hide_empty' => true,
|
|
'number' => $limit,
|
|
]
|
|
);
|
|
|
|
/**
|
|
* Filter the list of terms to be included in llms.txt for a taxonomy.
|
|
*
|
|
* @since 1.0.250
|
|
* @param array $terms List of terms.
|
|
* @param string $taxonomy Taxonomy name.
|
|
* @return array Modified list of term IDs.
|
|
*/
|
|
$terms = $this->do_filter( 'llms_txt/terms', $terms, $taxonomy );
|
|
if ( empty( $terms ) ) {
|
|
continue;
|
|
}
|
|
|
|
$label = $tax_obj->labels->name;
|
|
$this->output_line( '## ' . esc_html( $label ) );
|
|
foreach ( $terms as $term ) {
|
|
if ( $term && Helper::is_term_indexable( $term ) ) {
|
|
$name = $term->name;
|
|
$link = get_term_link( $term );
|
|
$this->output_line( '- [' . esc_html( $name ) . '](' . esc_url( $link ) . ')' );
|
|
}
|
|
}
|
|
$this->output_line( '' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds extra content to the end of the llms.txt output.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function add_extra_content() {
|
|
/**
|
|
* Filter the extra content output at the end of llms.txt.
|
|
*
|
|
* @since 1.0.250
|
|
* @param string $extra The extra content string.
|
|
* @return string Modified extra content.
|
|
*/
|
|
$extra = $this->do_filter( 'llms_txt/extra_content', Helper::get_settings( 'general.llms_extra_content', '' ) );
|
|
if ( ! empty( $extra ) ) {
|
|
$this->output_line( esc_html( str_replace( "\n", "\n", $extra ) ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Outputs a line with a newline character (\n).
|
|
*
|
|
* @param string $content The content to output.
|
|
* @return void
|
|
*/
|
|
private function output_line( $content ) {
|
|
echo esc_html( $content ) . "\n";
|
|
}
|
|
}
|