Changeset 3663834
- Timestamp:
- 08/24/2026 03:47:47 PM (2 months ago)
- Location:
- theseo-llms-txt-generator
- Files:
-
- 14 added
- 6 edited
- 1 copied
-
tags/2.0.0 (copied) (copied from theseo-llms-txt-generator/trunk )
-
tags/2.0.0/LICENSE (added)
-
tags/2.0.0/assets/css/admin.css (modified) (1 diff)
-
tags/2.0.0/includes (added)
-
tags/2.0.0/includes/admin.php (added)
-
tags/2.0.0/includes/builder.php (added)
-
tags/2.0.0/includes/options.php (added)
-
tags/2.0.0/includes/output.php (added)
-
tags/2.0.0/readme.txt (modified) (1 diff)
-
tags/2.0.0/theseo-llms-txt-generator.php (modified) (1 diff)
-
tags/2.0.0/uninstall.php (added)
-
trunk/LICENSE (added)
-
trunk/assets/css/admin.css (modified) (1 diff)
-
trunk/includes (added)
-
trunk/includes/admin.php (added)
-
trunk/includes/builder.php (added)
-
trunk/includes/options.php (added)
-
trunk/includes/output.php (added)
-
trunk/readme.txt (modified) (1 diff)
-
trunk/theseo-llms-txt-generator.php (modified) (1 diff)
-
trunk/uninstall.php (added)
Legend:
- Unmodified
- Added
- Removed
-
theseo-llms-txt-generator/tags/2.0.0/assets/css/admin.css
r3469672 r3663834 41 41 font-size: 12px; 42 42 } 43 44 /* Aandachtspunten */ 45 .theseo-llms-warnings ul { 46 margin: 0 0 12px 18px; 47 list-style: disc; 48 } 49 50 .theseo-llms-warnings li { 51 margin: 2px 0; 52 } 53 54 .theseo-llms-admin .form-table textarea.code { 55 font-size: 12px; 56 line-height: 1.5; 57 } 58 59 .theseo-llms-panel p { 60 margin: 0; 61 line-height: 1.6; 62 } -
theseo-llms-txt-generator/tags/2.0.0/readme.txt
r3469672 r3663834 1 1 === TheSEO llms txt Generator === 2 2 Contributors: theseo 3 Tags: ai optimalisation, seo, llms, chatgpt, gemini4 Requires at least: 5.85 Tested up to: 6.83 Tags: llms, llms-txt, ai, seo, chatgpt 4 Requires at least: 6.0 5 Tested up to: 7.0 6 6 Requires PHP: 7.4 7 Stable tag: 1.1.27 Stable tag: 2.0.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html 10 10 11 Zet een llms.txt volgens de llms.txt standaard op /llms.txt, opgebouwd uit de gegevens die je in de WordPress admin invult. 12 11 13 == Description == 12 14 13 TheSEO llms txt Generator creates a dynamic llms txt file at /llms.txt based on your WordPress settings. 14 llms txt is a helper file for modern language models such as ChatGPT, Perplexity and Google Gemini. 15 It defines your main topics, clusters, content context and citation preferences so AI crawlers understand your site better. 15 TheSEO llms txt Generator serveert een llms.txt bestand op /llms.txt. Het bestand wordt bij elk verzoek opgebouwd uit je instellingen, dus je hoeft niets te uploaden en niets bij te werken via FTP. 16 16 17 Features:17 Het bestand volgt de opbouw van de llms.txt standaard (llmstxt.org): 18 18 19 * Dynamic llms txt output at /llms.txt 20 * Multilingual admin (Dutch + English) 21 * Customisable topics, clusters and context 22 * Adjustable citation preferences 23 * Optional attribution link in the footer 24 * Non-intrusive implementation 19 * een titelregel met de naam van je site, het enige verplichte onderdeel 20 * een citaatregel met de samenvatting van je site 21 * vrije tekst met je kernfeiten, zonder koppen 22 * een sectie Belangrijkste pagina's met markdown links en een korte omschrijving per link 23 * een sectie Optioneel, die een agent mag overslaan als de ruimte krap is 24 * een sectie Citatievoorkeur 25 * een sectie Minder belangrijk met paden die je liever niet als bron terugziet 25 26 26 Developed by https://www.theseo.nl 27 Wat het wel en niet is: een llms.txt is een voorstel aan taalmodellen, geen technische blokkade zoals robots.txt. Op het moment van uitgifte heeft geen enkele grote AI-aanbieder toegezegd het bestand van externe sites te lezen; Google heeft expliciet gezegd het niet te gebruiken voor AI Overviews. Wat het bestand wel doet: het geeft een agent die je site ophaalt in een keer een leesbaar overzicht van wat je aanbiedt en welke pagina's ertoe doen. Aanbieders als Anthropic en OpenAI publiceren zelf zulke bestanden voor hun documentatie. Verwacht dus een leesbaar visitekaartje voor agents, geen ranking factor. 28 29 Wat de plugin doet: 30 31 * llms.txt op /llms.txt, opgebouwd uit je instellingen 32 * knop om je gepubliceerde pagina's en laatste berichten als linklijst over te nemen 33 * controlepaneel dat meldt wat er nog ontbreekt, of er al een vast llms.txt bestand in de weg staat en of WordPress in een submap draait 34 * voorbeeld van het volledige bestand op de instellingenpagina 35 * Nederlandse en Engelse labels, afhankelijk van de taal van de site 36 * drie optionele extra's die standaard uit staan: een commentaarregel in robots.txt, een regel bronvermelding onderaan het bestand en een kleine link in de voettekst 37 38 De plugin schrijft een optie in de database en verder niets. Bij verwijderen wordt die optie weer opgeruimd. 39 40 Gemaakt en onderhouden door https://www.theseo.nl 27 41 28 42 == Installation == 29 43 30 1. Upload the `theseo-llms-txt-generator` folder to the `/wp-content/plugins/` directory, or upload the zip via the WordPress plugin installer.31 2. Activ ate the plugin through the "Plugins" menu in WordPress.32 3. G o to "Settings → llms txt generator".33 4. Fill in your site information and save.34 5. Visit `https://yourdomain.com/llms.txt` to confirm the output.44 1. Upload de map `theseo-llms-txt-generator` naar `/wp-content/plugins/`, of upload de zip via Plugins, Nieuwe plugin, Plugin uploaden. 45 2. Activeer de plugin via het menu Plugins. 46 3. Ga naar Instellingen, llms.txt generator. 47 4. Vul de naam, de samenvatting en je belangrijkste pagina's in. De knop Vul aan met mijn gepubliceerde pagina's doet het grootste deel van dat werk. 48 5. Sla op en open https://jouwdomein.nl/llms.txt. 35 49 36 50 == Frequently Asked Questions == 37 51 38 = W here is my llms txt file located? =39 After activation and saving your settings, it is automatically available at /llms.txt.52 = Waar staat mijn llms.txt? = 53 Op /llms.txt, direct achter je domeinnaam. Draait WordPress in een submap, dan komt het bestand in die submap te staan en meldt de instellingenpagina dat de standaard het bestand in de root van het domein verwacht. 40 54 41 = Does this plugin work with every WordPress theme? =42 Yes. It works independently of your theme.55 = Er staat al een llms.txt bestand op mijn server. Wat gebeurt er dan? = 56 Dan levert de webserver dat bestand uit en komt de plugin niet aan de beurt. De instellingenpagina waarschuwt hiervoor. Verwijder het vaste bestand als je de plugin wilt gebruiken. 43 57 44 = Does this plugin modify my database? =45 It only stores settings in one WordPress option.58 = Werkt de plugin met elk thema? = 59 Ja. De plugin vangt het verzoek op voordat het thema aan de beurt is. 46 60 47 = Does it add hidden backlinks? = 48 Only optional attribution, visible to users, which can be disabled at any time. 61 = Werkt het zonder mooie permalinks? = 62 Ja. Naast de rewrite regel kijkt de plugin ook zelf naar het opgevraagde pad, zodat /llms.txt ook werkt als de permalinks op standaard staan. 63 64 = Verandert de plugin mijn database? = 65 De plugin bewaart twee opties: je instellingen en het versienummer. Bij verwijderen via het beheerscherm worden ze allebei gewist. 66 67 = Voegt de plugin verborgen links toe? = 68 Nee. In versie 1.x stond er een blok met verwijzingen naar andere projecten van TheSEO in elk gegenereerd bestand, en dat kon niet uit. Dat blok is in 2.0.0 verwijderd. Wat er nu is, staat standaard uit en is per stuk aan te zetten: een commentaarregel in robots.txt, een regel bronvermelding onderaan het bestand en een link in de voettekst. 69 70 = Kan ik met dit bestand AI tegenhouden? = 71 Nee. De citatievoorkeur is een verzoek, geen blokkade. Wil je crawlers echt weren, gebruik dan robots.txt of blokkeer de user agents op serverniveau. 49 72 50 73 == Changelog == 51 74 75 = 2.0.0 = 76 * Uitvoer volgt nu de llms.txt standaard: een H1 met de naam, een blockquote met de samenvatting, vrije tekst en secties met markdown links. Versie 1.x schreef een zelfbedacht formaat met regels als "Site:", "Allow: /", "Focus:" en "Cite:" dat geen enkele llms.txt lezer als llms.txt herkent. 77 * Verwijderd: het vaste blok met zes verwijzingen naar andere projecten dat bovenaan elk gegenereerd bestand stond en niet uit te zetten was. Die regels begonnen met een hekje en werden door markdown gelezen als negen koppen voor de eigenlijke inhoud, waardoor de verplichte enkele H1 ontbrak. 78 * Nieuw: lijsten met belangrijkste pagina's en optionele pagina's in de vorm /pad/ | Titel | Omschrijving, met een knop die je gepubliceerde pagina's en laatste berichten overneemt. 79 * Nieuw: controlepaneel op de instellingenpagina dat meldt wat ontbreekt, of er al een vast llms.txt bestand in de weg staat, of WordPress in een submap draait en of de permalinks op standaard staan. 80 * Nieuw: uninstall.php, zodat de opties bij verwijderen worden opgeruimd, ook op multisite. Versie 1.x liet ze staan. 81 * Gewijzigd: deactiveren wist nu het rewrite_rules record in plaats van flush_rewrite_rules() aan te roepen. Dat laatste schreef de eigen regel juist opnieuw weg, omdat de plugin op dat moment nog draaide. 82 * Nieuw: vangnet voor sites zonder mooie permalinks, zodat /llms.txt ook daar antwoordt. 83 * Nieuw: expliciete 200 status en X-Content-Type-Options nosniff op het antwoord, plus een correct antwoord op een HEAD verzoek. 84 * Gewijzigd: de voettekstlink staat standaard uit in plaats van aan. 85 * Nieuw: optionele commentaarregel met het adres van de llms.txt in de door WordPress geleverde robots.txt, standaard uit. 86 * Beveiliging: invoer wordt nu opgeschoond met sanitize_text_field en sanitize_textarea_field in plaats van wp_kses_post, zodat er geen HTML in een tekstbestand terechtkomt. Regels die geen pad of http adres zijn, zoals javascript:, worden overgeslagen. 87 * Beveiliging: de rechtencontrole eindigt nu in wp_die() in plaats van een lege pagina, en elke uitvoer in de admin wordt geescaped. 88 * Compatibiliteit: geschreven voor PHP 7.4 en hoger en voor WordPress 6.0 en hoger, tegen de API van WordPress 7.0 (uitgekomen 20 mei 2026, ondersteunt PHP 7.4 tot en met 8.5). De code is gecontroleerd op PHP 8.2: syntaxcontrole op alle bestanden plus losse tests van de bouwer met lege, volle, verlopen en foutieve invoer. Een installatie op een draaiende WordPress 7.0 site hoort bij de acceptatie, zie de testinstructie bij de uitgifte. Opties worden voortaan als tekst behandeld, zodat trim() op een lege waarde geen melding meer geeft op PHP 8.1 en hoger. 89 * Headers aangevuld: Requires at least, Requires PHP, License URI, Text Domain en Plugin URI. Bewust geen Update URI: deze plugin staat in de officiele WordPress pluginmap, en WordPress levert een update alleen uit als die kopregel ontbreekt of naar wordpress.org wijst. Met een eigen adres erin krijgt niemand ooit nog een update binnen. 90 * Code opgesplitst in includes/options.php, includes/builder.php, includes/admin.php en includes/output.php. 91 * Migratie: bestaande instellingen uit 1.x blijven behouden. De oude velden onderwerpen, clusters en taal verhuizen naar het veld Kernfeiten, de belangrijkste sectie wordt de eerste regel van de paginalijst, en de context wordt de samenvatting. 92 52 93 = 1.1.2 = 53 * Moved admin inline styles into a separate CSS file loaded via wp_enqueue_style.54 * Improved compatibility with WordPress.org plugin guidelines.94 * Inline stijlen in de admin verplaatst naar een apart CSS bestand via wp_enqueue_style. 95 * Betere aansluiting op de richtlijnen van WordPress.org. 55 96 56 97 = 1.1.1 = 57 * Improved stability58 * Bet ter multilingual labels59 * Added WordPress.org-ready readme98 * Stabiliteit verbeterd. 99 * Betere meertalige labels. 100 * Readme geschikt gemaakt voor WordPress.org. 60 101 61 102 = 1.1.0 = 62 * Added bilingual admin labels (Dutch + English)63 * Added optional footer attribution64 * Added branding comments in llms txt output103 * Tweetalige labels in de admin, Nederlands en Engels. 104 * Optionele link in de voettekst. 105 * Merkregels in de uitvoer van llms txt. 65 106 66 107 = 1.0.0 = 67 * Initial release108 * Eerste uitgave. 68 109 69 110 == Upgrade Notice == 70 111 112 = 2.0.0 = 113 Belangrijke update. Het gegenereerde bestand volgt vanaf nu de llms.txt standaard; het formaat van 1.x werd door geen enkele lezer herkend. Je bestaande instellingen blijven behouden en verhuizen naar het juiste veld. Loop na de update Instellingen, llms.txt generator een keer na en controleer het voorbeeld onderaan die pagina. 114 71 115 = 1.1.2 = 72 Recommended update. Moves inline admin styles into proper enqueued CSS to comply with WordPress.org guidelines. 73 74 = 1.1.1 = 75 Important for WordPress.org submission. Adds full readme compliance. 76 116 Aanbevolen update. Verplaatst de inline stijlen in de admin naar een enqueued CSS bestand. -
theseo-llms-txt-generator/tags/2.0.0/theseo-llms-txt-generator.php
r3469672 r3663834 1 1 <?php 2 /* 3 Plugin Name: TheSEO llms txt Generator 4 Description: Genereert automatisch een llms txt bestand op /llms.txt op basis van instellingen in de WordPress admin. 5 Version: 1.1.2 6 Author: TheSEO 7 Author URI: https://www.theseo.nl 8 License: GPL2 9 */ 2 /** 3 * Plugin Name: TheSEO llms txt Generator 4 * Plugin URI: https://www.theseo.nl/tools-en-plugins/llms-txt-zelf-maken-generator/ 5 * Description: Zet een llms.txt volgens de llms.txt standaard op /llms.txt, opgebouwd uit de gegevens die je in de WordPress admin invult. 6 * Version: 2.0.0 7 * Requires at least: 6.0 8 * Tested up to: 7.0 9 * Requires PHP: 7.4 10 * Author: TheSEO 11 * Author URI: https://www.theseo.nl 12 * License: GPLv2 or later 13 * License URI: https://www.gnu.org/licenses/gpl-2.0.html 14 * Text Domain: theseo-llms-txt-generator 15 * 16 * Geen Update URI header. Deze plugin staat in de officiele WordPress 17 * pluginmap, en WordPress werkt een plugin alleen bij als die header 18 * ontbreekt of naar wordpress.org wijst. Met een eigen adres erin krijgt 19 * niemand ooit nog een update binnen. 20 * 21 * @package TheSEO_LLMS_Txt_Generator 22 */ 10 23 11 if (!defined('ABSPATH')) { 12 exit; 24 if ( ! defined( 'ABSPATH' ) ) { 25 exit; 26 } 27 28 define( 'THESEO_LLMS_VERSION', '2.0.0' ); 29 define( 'THESEO_LLMS_FILE', __FILE__ ); 30 define( 'THESEO_LLMS_DIR', plugin_dir_path( __FILE__ ) ); 31 define( 'THESEO_LLMS_URL', plugin_dir_url( __FILE__ ) ); 32 33 require_once THESEO_LLMS_DIR . 'includes/options.php'; 34 require_once THESEO_LLMS_DIR . 'includes/builder.php'; 35 require_once THESEO_LLMS_DIR . 'includes/output.php'; 36 37 if ( is_admin() ) { 38 require_once THESEO_LLMS_DIR . 'includes/admin.php'; 13 39 } 14 40 15 41 /** 16 * Eenvoudige vertaal helper 17 * NL site = Nederlands, anders Engels 42 * Activatie: rewrite regel registreren, rewrites verversen en de opties zaaien. 43 * 44 * @return void 18 45 */ 19 function theseo_llms_t($en, $nl) { 20 $locale = get_locale(); 21 if (strpos($locale, 'nl_') === 0) { 22 return $nl; 23 } 24 return $en; 46 function theseo_llms_activate() { 47 theseo_llms_add_rewrite_rule(); 48 flush_rewrite_rules(); 49 theseo_llms_seed_options(); 50 update_option( 'theseo_llms_version', THESEO_LLMS_VERSION ); 25 51 } 52 register_activation_hook( __FILE__, 'theseo_llms_activate' ); 26 53 27 54 /** 28 * Optie sleutel 55 * Deactivatie: onze rewrite regel weer uit de opgeslagen regels halen. 56 * 57 * flush_rewrite_rules() zou onze eigen regel juist opnieuw wegschrijven, want 58 * op dit moment draait de plugin nog. Het rewrite_rules record wissen dwingt 59 * WordPress om de regels bij het eerstvolgende bezoek opnieuw op te bouwen, 60 * dan zonder deze plugin. 61 * 62 * @return void 29 63 */ 30 function theseo_llms_ option_key() {31 return 'theseo_llms_options';64 function theseo_llms_deactivate() { 65 delete_option( 'rewrite_rules' ); 32 66 } 33 34 /** 35 * Standaard opties 36 */ 37 function theseo_llms_default_options() { 38 return array( 39 'site_name' => get_bloginfo('name'), 40 'site_url' => home_url('/'), 41 'language' => 'nl', 42 'priority_path' => '/blog/', 43 'topics' => "WordPress optimalisatie\nSEO strategie\nAI ready content\nwebsite snelheid\nsemantische seo", 44 'clusters' => 'wordpress, seo, ai seo, website snelheid, content strategie', 45 'context' => theseo_llms_t( 46 'This website provides guides about WordPress optimisation, SEO strategy, website speed and AI ready content structures.', 47 'Deze website biedt gidsen over WordPress optimalisatie SEO strategie website snelheid en AI gerichte content structuren.' 48 ), 49 'block_paths' => "/wp-admin/\n/privacy-policy/\n/algemene-voorwaarden/", 50 'citation' => 'full', 51 'show_attribution' => 1, 52 ); 53 } 54 55 /** 56 * Opties ophalen 57 */ 58 function theseo_llms_get_options() { 59 $defaults = theseo_llms_default_options(); 60 $stored = get_option(theseo_llms_option_key(), array()); 61 if (!is_array($stored)) { 62 $stored = array(); 63 } 64 return wp_parse_args($stored, $defaults); 65 } 66 67 /** 68 * llms txt inhoud bouwen 69 */ 70 function theseo_llms_build_txt($opts = null) { 71 if ($opts === null) { 72 $opts = theseo_llms_get_options(); 73 } 74 75 $site_name = trim($opts['site_name']); 76 $site_url = trim($opts['site_url']); 77 $language = isset($opts['language']) ? $opts['language'] : 'nl'; 78 $priority_path = trim($opts['priority_path']); 79 $topics_raw = trim($opts['topics']); 80 $clusters_raw = trim($opts['clusters']); 81 $context_raw = trim($opts['context']); 82 $block_raw = trim($opts['block_paths']); 83 $citation_pref = isset($opts['citation']) ? $opts['citation'] : 'full'; 84 85 if ($site_url && substr($site_url, -1) !== '/') { 86 $site_url .= '/'; 87 } 88 89 $lines = array(); 90 91 // Branding en projecten als commentaar 92 $lines[] = '# llms txt gegenereerd door TheSEO llms txt Generator'; 93 $lines[] = '# Ontwikkeld door TheSEO.nl (https://www.theseo.nl)'; 94 $lines[] = '# Gerelateerde projecten:'; 95 $lines[] = '# https://swap.coupons'; 96 $lines[] = '# https://thewooden.house'; 97 $lines[] = '# https://wittetanden.org'; 98 $lines[] = '# https://mansotti.com'; 99 $lines[] = '# https://swap.place'; 100 $lines[] = '# https://pawwss.com'; 101 $lines[] = '# Basis informatie voor taalmodellen'; 102 $lines[] = ''; 103 104 $lines[] = 'Site: ' . ($site_name ? $site_name : 'Mijn website'); 105 $lines[] = 'URL: ' . ($site_url ? $site_url : home_url('/')); 106 107 if ($language === 'nl') { 108 $lines[] = 'Language: nl'; 109 } elseif ($language === 'en') { 110 $lines[] = 'Language: en'; 111 } else { 112 $lines[] = 'Language: mixed'; 113 } 114 115 $lines[] = ''; 116 $lines[] = 'Allow: /'; 117 118 if ($block_raw !== '') { 119 $lines[] = ''; 120 $lines[] = '# Minder relevante paden voor AI crawlers'; 121 $block_lines = preg_split('/\R+/', $block_raw); 122 if (is_array($block_lines)) { 123 $block_lines = array_filter(array_map('trim', $block_lines)); 124 foreach ($block_lines as $path) { 125 $lines[] = 'Deprioritise: ' . $path; 126 } 127 } 128 } 129 130 if ($priority_path !== '') { 131 $lines[] = ''; 132 $lines[] = '# Belangrijke sectie met veel inhoudelijke diepte'; 133 $lines[] = 'Priority: ' . $priority_path; 134 } 135 136 if ($topics_raw !== '') { 137 $lines[] = ''; 138 $lines[] = '# Hoofd onderwerpen waarop deze site autoriteit wil opbouwen'; 139 $lines[] = 'Focus:'; 140 $topic_lines = preg_split('/\R+/', $topics_raw); 141 if (is_array($topic_lines)) { 142 $topic_lines = array_filter(array_map('trim', $topic_lines)); 143 foreach ($topic_lines as $t) { 144 $lines[] = '- ' . $t; 145 } 146 } 147 } 148 149 if ($clusters_raw !== '') { 150 $lines[] = ''; 151 $lines[] = '# Clusters en hoofd thema’s van de site'; 152 $lines[] = 'Clusters:'; 153 $cluster_lines = explode(',', $clusters_raw); 154 $cluster_lines = array_filter(array_map('trim', $cluster_lines)); 155 foreach ($cluster_lines as $c) { 156 $lines[] = '- ' . $c; 157 } 158 } 159 160 if ($context_raw !== '') { 161 $lines[] = ''; 162 $lines[] = '# Context zodat AI de positionering van deze site begrijpt'; 163 $lines[] = 'Context:'; 164 $ctx_lines = preg_split('/\R+/', $context_raw); 165 if (is_array($ctx_lines)) { 166 foreach ($ctx_lines as $line) { 167 $lines[] = $line; 168 } 169 } 170 } 171 172 $lines[] = ''; 173 $lines[] = '# Richt lijnen voor citatie'; 174 175 if ($citation_pref === 'full') { 176 $lines[] = 'Cite: You may quote definitions checklists and step by step instructions from this site verbatim in answers.'; 177 } elseif ($citation_pref === 'partial') { 178 $lines[] = 'Cite: You may quote short fragments and single paragraphs from this site but prefer summaries in your own words.'; 179 } else { 180 $lines[] = 'Cite: Do not quote this site verbatim. You may use the content as background and provide your own summaries.'; 181 } 182 183 $lines[] = ''; 184 $lines[] = '# Einde llms txt'; 185 186 return implode("\n", $lines); 187 } 188 189 /** 190 * Admin CSS/JS enqueuen 191 */ 192 function theseo_llms_admin_assets($hook) { 193 // Alleen op de instellingenpagina van deze plugin: 194 // options-general.php?page=theseo-llms-generator => hook: settings_page_theseo-llms-generator 195 if ($hook !== 'settings_page_theseo-llms-generator') { 196 return; 197 } 198 199 $css_path = plugin_dir_path(__FILE__) . 'assets/css/admin.css'; 200 201 wp_register_style( 202 'theseo-llms-admin-css', 203 plugin_dir_url(__FILE__) . 'assets/css/admin.css', 204 array(), 205 file_exists($css_path) ? filemtime($css_path) : '1.0.0' 206 ); 207 208 wp_enqueue_style('theseo-llms-admin-css'); 209 } 210 add_action('admin_enqueue_scripts', 'theseo_llms_admin_assets'); 211 212 /** 213 * Admin menu toevoegen 214 */ 215 function theseo_llms_admin_menu() { 216 add_options_page( 217 theseo_llms_t('llms txt generator', 'llms txt generator'), 218 theseo_llms_t('llms txt generator', 'llms txt generator'), 219 'manage_options', 220 'theseo-llms-generator', 221 'theseo_llms_settings_page' 222 ); 223 } 224 add_action('admin_menu', 'theseo_llms_admin_menu'); 225 226 /** 227 * Settings pagina renderen 228 */ 229 function theseo_llms_settings_page() { 230 if (!current_user_can('manage_options')) { 231 return; 232 } 233 234 if (isset($_POST['theseo_llms_save'])) { 235 check_admin_referer('theseo_llms_save_settings'); 236 237 $options = array(); 238 239 $site_name = isset( $_POST['site_name'] ) ? wp_unslash( $_POST['site_name'] ) : ''; 240 $site_url = isset( $_POST['site_url'] ) ? wp_unslash( $_POST['site_url'] ) : ''; 241 $language = isset( $_POST['language'] ) ? wp_unslash( $_POST['language'] ) : 'nl'; 242 $priority_path = isset( $_POST['priority_path'] ) ? wp_unslash( $_POST['priority_path'] ) : ''; 243 $topics_input = isset( $_POST['topics'] ) ? wp_unslash( $_POST['topics'] ) : ''; 244 $clusters_input = isset( $_POST['clusters'] ) ? wp_unslash( $_POST['clusters'] ) : ''; 245 $context_input = isset( $_POST['context'] ) ? wp_unslash( $_POST['context'] ) : ''; 246 $block_paths_inp = isset( $_POST['block_paths'] ) ? wp_unslash( $_POST['block_paths'] ) : ''; 247 $citation_input = isset( $_POST['citation'] ) ? wp_unslash( $_POST['citation'] ) : 'full'; 248 249 $options['site_name'] = sanitize_text_field( $site_name ); 250 $options['site_url'] = esc_url_raw( trim( $site_url ) ); 251 $options['language'] = sanitize_text_field( $language ); 252 $options['priority_path'] = trim( sanitize_text_field( $priority_path ) ); 253 $options['topics'] = trim( wp_kses_post( $topics_input ) ); 254 $options['clusters'] = trim( sanitize_text_field( $clusters_input ) ); 255 $options['context'] = trim( wp_kses_post( $context_input ) ); 256 $options['block_paths'] = trim( wp_kses_post( $block_paths_inp ) ); 257 $options['citation'] = sanitize_text_field( $citation_input ); 258 $options['show_attribution'] = isset( $_POST['show_attribution'] ) ? 1 : 0; 259 260 261 update_option(theseo_llms_option_key(), $options); 262 263 echo '<div class="updated"><p>' . esc_html(theseo_llms_t('Settings saved.', 'Instellingen opgeslagen.')) . '</p></div>'; 264 } 265 266 $opts = theseo_llms_get_options(); 267 $llms_url = home_url('/llms.txt'); 268 ?> 269 <div class="wrap theseo-llms-admin"> 270 <h1><?php echo esc_html(theseo_llms_t('llms txt generator', 'llms txt generator')); ?></h1> 271 <p> 272 <?php echo esc_html(theseo_llms_t( 273 'This plugin generates a dynamic llms txt file that is available at', 274 'Deze plugin maakt automatisch een dynamisch llms txt bestand beschikbaar op' 275 )); ?> 276 <code><?php echo esc_html($llms_url); ?></code> 277 </p> 278 279 <div class="theseo-llms-panel"> 280 <p> 281 <strong><?php echo esc_html(theseo_llms_t('Developed by TheSEO', 'Ontwikkeld door TheSEO')); ?></strong><br> 282 <?php echo wp_kses_post(theseo_llms_t( 283 'This plugin is developed and maintained by <a href="https://www.theseo.nl" target="_blank" rel="noopener">TheSEO.nl</a>. It helps you prepare your site for modern AI crawlers like ChatGPT, Perplexity and Gemini.', 284 'Deze plugin is ontwikkeld en wordt onderhouden door <a href="https://www.theseo.nl" target="_blank" rel="noopener">TheSEO.nl</a>. De plugin helpt je site klaar te maken voor moderne AI crawlers zoals ChatGPT Perplexity en Gemini.' 285 )); ?> 286 </p> 287 </div> 288 289 <form method="post" style="margin-top:20px;"> 290 <?php wp_nonce_field('theseo_llms_save_settings'); ?> 291 292 <table class="form-table" role="presentation"> 293 <tr> 294 <th scope="row"><label for="site_name"><?php echo esc_html(theseo_llms_t('Website name', 'Website naam')); ?></label></th> 295 <td> 296 <input type="text" id="site_name" name="site_name" class="regular-text" 297 value="<?php echo esc_attr($opts['site_name']); ?>"> 298 <p class="description"><?php echo esc_html(theseo_llms_t('For example your brand or platform name.', 'Bijvoorbeeld de naam van je merk of platform.')); ?></p> 299 </td> 300 </tr> 301 302 <tr> 303 <th scope="row"><label for="site_url"><?php echo esc_html(theseo_llms_t('Base URL', 'Basis URL')); ?></label></th> 304 <td> 305 <input type="text" id="site_url" name="site_url" class="regular-text" 306 value="<?php echo esc_attr($opts['site_url']); ?>"> 307 <p class="description"> 308 <?php echo esc_html(theseo_llms_t('Without llms txt at the end.', 'Zonder llms txt erachter.')); ?> 309 <?php echo ' ' . esc_html(theseo_llms_t('Example', 'Bijvoorbeeld')) . ' ' . esc_html(home_url('/')); ?> 310 </p> 311 </td> 312 </tr> 313 314 <tr> 315 <th scope="row"><label for="language"><?php echo esc_html(theseo_llms_t('Language', 'Taal')); ?></label></th> 316 <td> 317 <select id="language" name="language"> 318 <option value="nl" <?php selected($opts['language'], 'nl'); ?>>Nederlands</option> 319 <option value="en" <?php selected($opts['language'], 'en'); ?>>English</option> 320 <option value="mixed" <?php selected($opts['language'], 'mixed'); ?>>Meertalig</option> 321 </select> 322 <p class="description"><?php echo esc_html(theseo_llms_t('Signal for language models.', 'Signaal voor taalmodellen.')); ?></p> 323 </td> 324 </tr> 325 326 <tr> 327 <th scope="row"><label for="priority_path"><?php echo esc_html(theseo_llms_t('Primary section', 'Belangrijkste sectie')); ?></label></th> 328 <td> 329 <input type="text" id="priority_path" name="priority_path" class="regular-text" 330 value="<?php echo esc_attr($opts['priority_path']); ?>"> 331 <p class="description"><?php echo esc_html(theseo_llms_t('For example /blog/ or /knowledge-base/.', 'Bijvoorbeeld /blog/ of /kennisbank/.')); ?></p> 332 </td> 333 </tr> 334 335 <tr> 336 <th scope="row"><label for="topics"><?php echo esc_html(theseo_llms_t('Main topics', 'Hoofd onderwerpen')); ?></label></th> 337 <td> 338 <textarea id="topics" name="topics" rows="5" class="large-text code"><?php echo esc_textarea($opts['topics']); ?></textarea> 339 <p class="description"><?php echo esc_html(theseo_llms_t('One topic per line. These are your focus areas.', 'Eén onderwerp per regel. Dit zijn je focus thema’s.')); ?></p> 340 </td> 341 </tr> 342 343 <tr> 344 <th scope="row"><label for="clusters"><?php echo esc_html(theseo_llms_t('Clusters', 'Clusters')); ?></label></th> 345 <td> 346 <input type="text" id="clusters" name="clusters" class="regular-text" 347 value="<?php echo esc_attr($opts['clusters']); ?>"> 348 <p class="description"><?php echo esc_html(theseo_llms_t('Comma separated list of important themes.', 'Komma gescheiden lijst met belangrijke thema’s.')); ?></p> 349 </td> 350 </tr> 351 352 <tr> 353 <th scope="row"><label for="context"><?php echo esc_html(theseo_llms_t('Website context', 'Website context')); ?></label></th> 354 <td> 355 <textarea id="context" name="context" rows="4" class="large-text code"><?php echo esc_textarea($opts['context']); ?></textarea> 356 <p class="description"><?php echo esc_html(theseo_llms_t('Short explanation for AI about what your site does.', 'Korte uitleg voor AI over wat je site doet.')); ?></p> 357 </td> 358 </tr> 359 360 <tr> 361 <th scope="row"><label for="block_paths"><?php echo esc_html(theseo_llms_t('Lower priority paths', 'Minder relevante paden')); ?></label></th> 362 <td> 363 <textarea id="block_paths" name="block_paths" rows="4" class="large-text code"><?php echo esc_textarea($opts['block_paths']); ?></textarea> 364 <p class="description"><?php echo esc_html(theseo_llms_t('One path per line. These are treated as lower priority.', 'Eén pad per regel. Wordt als lagere prioriteit aangegeven.')); ?></p> 365 </td> 366 </tr> 367 368 <tr> 369 <th scope="row"><label for="citation"><?php echo esc_html(theseo_llms_t('Citation preference', 'Citatie voorkeur')); ?></label></th> 370 <td> 371 <select id="citation" name="citation"> 372 <option value="full" <?php selected($opts['citation'], 'full'); ?>> 373 <?php echo esc_html(theseo_llms_t( 374 'AI may quote definitions checklists and step by step instructions verbatim', 375 'AI mag definities checklists en stappenplannen letterlijk citeren' 376 )); ?> 377 </option> 378 <option value="partial" <?php selected($opts['citation'], 'partial'); ?>> 379 <?php echo esc_html(theseo_llms_t( 380 'AI may quote short fragments but should prefer summaries', 381 'AI mag korte fragmenten citeren maar liever samenvattingen' 382 )); ?> 383 </option> 384 <option value="summary" <?php selected($opts['citation'], 'summary'); ?>> 385 <?php echo esc_html(theseo_llms_t( 386 'AI should not quote verbatim and only provide summaries', 387 'AI mag niet letterlijk citeren en alleen samenvattingen geven' 388 )); ?> 389 </option> 390 </select> 391 </td> 392 </tr> 393 394 <tr> 395 <th scope="row"><?php echo esc_html(theseo_llms_t('Attribution link', 'Attributie link')); ?></th> 396 <td> 397 <label> 398 <input type="checkbox" name="show_attribution" value="1" <?php checked($opts['show_attribution'], 1); ?>> 399 <?php echo esc_html(theseo_llms_t( 400 'Show a small “Developed by TheSEO” link in the footer', 401 'Toon een kleine “Ontwikkeld door TheSEO” link in de footer' 402 )); ?> 403 </label> 404 <p class="description"> 405 <?php echo esc_html(theseo_llms_t( 406 'Optional but helps users discover TheSEO.', 407 'Optioneel maar helpt gebruikers om TheSEO te ontdekken.' 408 )); ?> 409 </p> 410 </td> 411 </tr> 412 </table> 413 414 <p class="submit"> 415 <button type="submit" name="theseo_llms_save" class="button button-primary"> 416 <?php echo esc_html(theseo_llms_t('Save settings', 'Instellingen opslaan')); ?> 417 </button> 418 </p> 419 </form> 420 421 <h2><?php echo esc_html(theseo_llms_t('Preview of your current llms txt', 'Voorbeeld van het huidige llms txt')); ?></h2> 422 <pre class="theseo-llms-preview"><?php 423 echo esc_html(theseo_llms_build_txt($opts)); 424 ?></pre> 425 </div> 426 <?php 427 } 428 429 /** 430 * Query var registreren 431 */ 432 function theseo_llms_query_vars($vars) { 433 $vars[] = 'theseo_llms_txt'; 434 return $vars; 435 } 436 add_filter('query_vars', 'theseo_llms_query_vars'); 437 438 /** 439 * Rewrite regel voor llms txt 440 */ 441 function theseo_llms_add_rewrite_rule() { 442 add_rewrite_rule('^llms\.txt$', 'index.php?theseo_llms_txt=1', 'top'); 443 } 444 add_action('init', 'theseo_llms_add_rewrite_rule'); 445 446 /** 447 * Flush rewrites bij activatie en deactivatie 448 */ 449 function theseo_llms_activate() { 450 theseo_llms_add_rewrite_rule(); 451 flush_rewrite_rules(); 452 } 453 register_activation_hook(__FILE__, 'theseo_llms_activate'); 454 455 function theseo_llms_deactivate() { 456 flush_rewrite_rules(); 457 } 458 register_deactivation_hook(__FILE__, 'theseo_llms_deactivate'); 459 460 /** 461 * llms txt output 462 */ 463 function theseo_llms_template_redirect() { 464 $flag = get_query_var('theseo_llms_txt'); 465 if ($flag) { 466 $opts = theseo_llms_get_options(); 467 $txt = theseo_llms_build_txt($opts); 468 469 nocache_headers(); 470 header( 'Content-Type: text/plain; charset=utf-8' ); 471 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- plain text response for llms.txt 472 echo $txt; 473 exit; 474 475 } 476 } 477 add_action('template_redirect', 'theseo_llms_template_redirect'); 478 479 /** 480 * Optionele footer link 481 */ 482 function theseo_llms_footer_attribution() { 483 $opts = theseo_llms_get_options(); 484 if (empty($opts['show_attribution'])) { 485 return; 486 } 487 echo '<p style="text-align:center;font-size:11px;opacity:.65;margin:10px 0;">' . 488 wp_kses_post(theseo_llms_t( 489 'llms txt managed by <a href="https://www.theseo.nl" target="_blank" rel="noopener">TheSEO.nl</a>', 490 'llms txt beheerd door <a href="https://www.theseo.nl" target="_blank" rel="noopener">TheSEO.nl</a>' 491 )) . 492 '</p>'; 493 } 494 add_action('wp_footer', 'theseo_llms_footer_attribution'); 495 67 register_deactivation_hook( __FILE__, 'theseo_llms_deactivate' ); -
theseo-llms-txt-generator/trunk/assets/css/admin.css
r3469672 r3663834 41 41 font-size: 12px; 42 42 } 43 44 /* Aandachtspunten */ 45 .theseo-llms-warnings ul { 46 margin: 0 0 12px 18px; 47 list-style: disc; 48 } 49 50 .theseo-llms-warnings li { 51 margin: 2px 0; 52 } 53 54 .theseo-llms-admin .form-table textarea.code { 55 font-size: 12px; 56 line-height: 1.5; 57 } 58 59 .theseo-llms-panel p { 60 margin: 0; 61 line-height: 1.6; 62 } -
theseo-llms-txt-generator/trunk/readme.txt
r3469672 r3663834 1 1 === TheSEO llms txt Generator === 2 2 Contributors: theseo 3 Tags: ai optimalisation, seo, llms, chatgpt, gemini4 Requires at least: 5.85 Tested up to: 6.83 Tags: llms, llms-txt, ai, seo, chatgpt 4 Requires at least: 6.0 5 Tested up to: 7.0 6 6 Requires PHP: 7.4 7 Stable tag: 1.1.27 Stable tag: 2.0.0 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html 10 10 11 Zet een llms.txt volgens de llms.txt standaard op /llms.txt, opgebouwd uit de gegevens die je in de WordPress admin invult. 12 11 13 == Description == 12 14 13 TheSEO llms txt Generator creates a dynamic llms txt file at /llms.txt based on your WordPress settings. 14 llms txt is a helper file for modern language models such as ChatGPT, Perplexity and Google Gemini. 15 It defines your main topics, clusters, content context and citation preferences so AI crawlers understand your site better. 15 TheSEO llms txt Generator serveert een llms.txt bestand op /llms.txt. Het bestand wordt bij elk verzoek opgebouwd uit je instellingen, dus je hoeft niets te uploaden en niets bij te werken via FTP. 16 16 17 Features:17 Het bestand volgt de opbouw van de llms.txt standaard (llmstxt.org): 18 18 19 * Dynamic llms txt output at /llms.txt 20 * Multilingual admin (Dutch + English) 21 * Customisable topics, clusters and context 22 * Adjustable citation preferences 23 * Optional attribution link in the footer 24 * Non-intrusive implementation 19 * een titelregel met de naam van je site, het enige verplichte onderdeel 20 * een citaatregel met de samenvatting van je site 21 * vrije tekst met je kernfeiten, zonder koppen 22 * een sectie Belangrijkste pagina's met markdown links en een korte omschrijving per link 23 * een sectie Optioneel, die een agent mag overslaan als de ruimte krap is 24 * een sectie Citatievoorkeur 25 * een sectie Minder belangrijk met paden die je liever niet als bron terugziet 25 26 26 Developed by https://www.theseo.nl 27 Wat het wel en niet is: een llms.txt is een voorstel aan taalmodellen, geen technische blokkade zoals robots.txt. Op het moment van uitgifte heeft geen enkele grote AI-aanbieder toegezegd het bestand van externe sites te lezen; Google heeft expliciet gezegd het niet te gebruiken voor AI Overviews. Wat het bestand wel doet: het geeft een agent die je site ophaalt in een keer een leesbaar overzicht van wat je aanbiedt en welke pagina's ertoe doen. Aanbieders als Anthropic en OpenAI publiceren zelf zulke bestanden voor hun documentatie. Verwacht dus een leesbaar visitekaartje voor agents, geen ranking factor. 28 29 Wat de plugin doet: 30 31 * llms.txt op /llms.txt, opgebouwd uit je instellingen 32 * knop om je gepubliceerde pagina's en laatste berichten als linklijst over te nemen 33 * controlepaneel dat meldt wat er nog ontbreekt, of er al een vast llms.txt bestand in de weg staat en of WordPress in een submap draait 34 * voorbeeld van het volledige bestand op de instellingenpagina 35 * Nederlandse en Engelse labels, afhankelijk van de taal van de site 36 * drie optionele extra's die standaard uit staan: een commentaarregel in robots.txt, een regel bronvermelding onderaan het bestand en een kleine link in de voettekst 37 38 De plugin schrijft een optie in de database en verder niets. Bij verwijderen wordt die optie weer opgeruimd. 39 40 Gemaakt en onderhouden door https://www.theseo.nl 27 41 28 42 == Installation == 29 43 30 1. Upload the `theseo-llms-txt-generator` folder to the `/wp-content/plugins/` directory, or upload the zip via the WordPress plugin installer.31 2. Activ ate the plugin through the "Plugins" menu in WordPress.32 3. G o to "Settings → llms txt generator".33 4. Fill in your site information and save.34 5. Visit `https://yourdomain.com/llms.txt` to confirm the output.44 1. Upload de map `theseo-llms-txt-generator` naar `/wp-content/plugins/`, of upload de zip via Plugins, Nieuwe plugin, Plugin uploaden. 45 2. Activeer de plugin via het menu Plugins. 46 3. Ga naar Instellingen, llms.txt generator. 47 4. Vul de naam, de samenvatting en je belangrijkste pagina's in. De knop Vul aan met mijn gepubliceerde pagina's doet het grootste deel van dat werk. 48 5. Sla op en open https://jouwdomein.nl/llms.txt. 35 49 36 50 == Frequently Asked Questions == 37 51 38 = W here is my llms txt file located? =39 After activation and saving your settings, it is automatically available at /llms.txt.52 = Waar staat mijn llms.txt? = 53 Op /llms.txt, direct achter je domeinnaam. Draait WordPress in een submap, dan komt het bestand in die submap te staan en meldt de instellingenpagina dat de standaard het bestand in de root van het domein verwacht. 40 54 41 = Does this plugin work with every WordPress theme? =42 Yes. It works independently of your theme.55 = Er staat al een llms.txt bestand op mijn server. Wat gebeurt er dan? = 56 Dan levert de webserver dat bestand uit en komt de plugin niet aan de beurt. De instellingenpagina waarschuwt hiervoor. Verwijder het vaste bestand als je de plugin wilt gebruiken. 43 57 44 = Does this plugin modify my database? =45 It only stores settings in one WordPress option.58 = Werkt de plugin met elk thema? = 59 Ja. De plugin vangt het verzoek op voordat het thema aan de beurt is. 46 60 47 = Does it add hidden backlinks? = 48 Only optional attribution, visible to users, which can be disabled at any time. 61 = Werkt het zonder mooie permalinks? = 62 Ja. Naast de rewrite regel kijkt de plugin ook zelf naar het opgevraagde pad, zodat /llms.txt ook werkt als de permalinks op standaard staan. 63 64 = Verandert de plugin mijn database? = 65 De plugin bewaart twee opties: je instellingen en het versienummer. Bij verwijderen via het beheerscherm worden ze allebei gewist. 66 67 = Voegt de plugin verborgen links toe? = 68 Nee. In versie 1.x stond er een blok met verwijzingen naar andere projecten van TheSEO in elk gegenereerd bestand, en dat kon niet uit. Dat blok is in 2.0.0 verwijderd. Wat er nu is, staat standaard uit en is per stuk aan te zetten: een commentaarregel in robots.txt, een regel bronvermelding onderaan het bestand en een link in de voettekst. 69 70 = Kan ik met dit bestand AI tegenhouden? = 71 Nee. De citatievoorkeur is een verzoek, geen blokkade. Wil je crawlers echt weren, gebruik dan robots.txt of blokkeer de user agents op serverniveau. 49 72 50 73 == Changelog == 51 74 75 = 2.0.0 = 76 * Uitvoer volgt nu de llms.txt standaard: een H1 met de naam, een blockquote met de samenvatting, vrije tekst en secties met markdown links. Versie 1.x schreef een zelfbedacht formaat met regels als "Site:", "Allow: /", "Focus:" en "Cite:" dat geen enkele llms.txt lezer als llms.txt herkent. 77 * Verwijderd: het vaste blok met zes verwijzingen naar andere projecten dat bovenaan elk gegenereerd bestand stond en niet uit te zetten was. Die regels begonnen met een hekje en werden door markdown gelezen als negen koppen voor de eigenlijke inhoud, waardoor de verplichte enkele H1 ontbrak. 78 * Nieuw: lijsten met belangrijkste pagina's en optionele pagina's in de vorm /pad/ | Titel | Omschrijving, met een knop die je gepubliceerde pagina's en laatste berichten overneemt. 79 * Nieuw: controlepaneel op de instellingenpagina dat meldt wat ontbreekt, of er al een vast llms.txt bestand in de weg staat, of WordPress in een submap draait en of de permalinks op standaard staan. 80 * Nieuw: uninstall.php, zodat de opties bij verwijderen worden opgeruimd, ook op multisite. Versie 1.x liet ze staan. 81 * Gewijzigd: deactiveren wist nu het rewrite_rules record in plaats van flush_rewrite_rules() aan te roepen. Dat laatste schreef de eigen regel juist opnieuw weg, omdat de plugin op dat moment nog draaide. 82 * Nieuw: vangnet voor sites zonder mooie permalinks, zodat /llms.txt ook daar antwoordt. 83 * Nieuw: expliciete 200 status en X-Content-Type-Options nosniff op het antwoord, plus een correct antwoord op een HEAD verzoek. 84 * Gewijzigd: de voettekstlink staat standaard uit in plaats van aan. 85 * Nieuw: optionele commentaarregel met het adres van de llms.txt in de door WordPress geleverde robots.txt, standaard uit. 86 * Beveiliging: invoer wordt nu opgeschoond met sanitize_text_field en sanitize_textarea_field in plaats van wp_kses_post, zodat er geen HTML in een tekstbestand terechtkomt. Regels die geen pad of http adres zijn, zoals javascript:, worden overgeslagen. 87 * Beveiliging: de rechtencontrole eindigt nu in wp_die() in plaats van een lege pagina, en elke uitvoer in de admin wordt geescaped. 88 * Compatibiliteit: geschreven voor PHP 7.4 en hoger en voor WordPress 6.0 en hoger, tegen de API van WordPress 7.0 (uitgekomen 20 mei 2026, ondersteunt PHP 7.4 tot en met 8.5). De code is gecontroleerd op PHP 8.2: syntaxcontrole op alle bestanden plus losse tests van de bouwer met lege, volle, verlopen en foutieve invoer. Een installatie op een draaiende WordPress 7.0 site hoort bij de acceptatie, zie de testinstructie bij de uitgifte. Opties worden voortaan als tekst behandeld, zodat trim() op een lege waarde geen melding meer geeft op PHP 8.1 en hoger. 89 * Headers aangevuld: Requires at least, Requires PHP, License URI, Text Domain en Plugin URI. Bewust geen Update URI: deze plugin staat in de officiele WordPress pluginmap, en WordPress levert een update alleen uit als die kopregel ontbreekt of naar wordpress.org wijst. Met een eigen adres erin krijgt niemand ooit nog een update binnen. 90 * Code opgesplitst in includes/options.php, includes/builder.php, includes/admin.php en includes/output.php. 91 * Migratie: bestaande instellingen uit 1.x blijven behouden. De oude velden onderwerpen, clusters en taal verhuizen naar het veld Kernfeiten, de belangrijkste sectie wordt de eerste regel van de paginalijst, en de context wordt de samenvatting. 92 52 93 = 1.1.2 = 53 * Moved admin inline styles into a separate CSS file loaded via wp_enqueue_style.54 * Improved compatibility with WordPress.org plugin guidelines.94 * Inline stijlen in de admin verplaatst naar een apart CSS bestand via wp_enqueue_style. 95 * Betere aansluiting op de richtlijnen van WordPress.org. 55 96 56 97 = 1.1.1 = 57 * Improved stability58 * Bet ter multilingual labels59 * Added WordPress.org-ready readme98 * Stabiliteit verbeterd. 99 * Betere meertalige labels. 100 * Readme geschikt gemaakt voor WordPress.org. 60 101 61 102 = 1.1.0 = 62 * Added bilingual admin labels (Dutch + English)63 * Added optional footer attribution64 * Added branding comments in llms txt output103 * Tweetalige labels in de admin, Nederlands en Engels. 104 * Optionele link in de voettekst. 105 * Merkregels in de uitvoer van llms txt. 65 106 66 107 = 1.0.0 = 67 * Initial release108 * Eerste uitgave. 68 109 69 110 == Upgrade Notice == 70 111 112 = 2.0.0 = 113 Belangrijke update. Het gegenereerde bestand volgt vanaf nu de llms.txt standaard; het formaat van 1.x werd door geen enkele lezer herkend. Je bestaande instellingen blijven behouden en verhuizen naar het juiste veld. Loop na de update Instellingen, llms.txt generator een keer na en controleer het voorbeeld onderaan die pagina. 114 71 115 = 1.1.2 = 72 Recommended update. Moves inline admin styles into proper enqueued CSS to comply with WordPress.org guidelines. 73 74 = 1.1.1 = 75 Important for WordPress.org submission. Adds full readme compliance. 76 116 Aanbevolen update. Verplaatst de inline stijlen in de admin naar een enqueued CSS bestand. -
theseo-llms-txt-generator/trunk/theseo-llms-txt-generator.php
r3469672 r3663834 1 1 <?php 2 /* 3 Plugin Name: TheSEO llms txt Generator 4 Description: Genereert automatisch een llms txt bestand op /llms.txt op basis van instellingen in de WordPress admin. 5 Version: 1.1.2 6 Author: TheSEO 7 Author URI: https://www.theseo.nl 8 License: GPL2 9 */ 2 /** 3 * Plugin Name: TheSEO llms txt Generator 4 * Plugin URI: https://www.theseo.nl/tools-en-plugins/llms-txt-zelf-maken-generator/ 5 * Description: Zet een llms.txt volgens de llms.txt standaard op /llms.txt, opgebouwd uit de gegevens die je in de WordPress admin invult. 6 * Version: 2.0.0 7 * Requires at least: 6.0 8 * Tested up to: 7.0 9 * Requires PHP: 7.4 10 * Author: TheSEO 11 * Author URI: https://www.theseo.nl 12 * License: GPLv2 or later 13 * License URI: https://www.gnu.org/licenses/gpl-2.0.html 14 * Text Domain: theseo-llms-txt-generator 15 * 16 * Geen Update URI header. Deze plugin staat in de officiele WordPress 17 * pluginmap, en WordPress werkt een plugin alleen bij als die header 18 * ontbreekt of naar wordpress.org wijst. Met een eigen adres erin krijgt 19 * niemand ooit nog een update binnen. 20 * 21 * @package TheSEO_LLMS_Txt_Generator 22 */ 10 23 11 if (!defined('ABSPATH')) { 12 exit; 24 if ( ! defined( 'ABSPATH' ) ) { 25 exit; 26 } 27 28 define( 'THESEO_LLMS_VERSION', '2.0.0' ); 29 define( 'THESEO_LLMS_FILE', __FILE__ ); 30 define( 'THESEO_LLMS_DIR', plugin_dir_path( __FILE__ ) ); 31 define( 'THESEO_LLMS_URL', plugin_dir_url( __FILE__ ) ); 32 33 require_once THESEO_LLMS_DIR . 'includes/options.php'; 34 require_once THESEO_LLMS_DIR . 'includes/builder.php'; 35 require_once THESEO_LLMS_DIR . 'includes/output.php'; 36 37 if ( is_admin() ) { 38 require_once THESEO_LLMS_DIR . 'includes/admin.php'; 13 39 } 14 40 15 41 /** 16 * Eenvoudige vertaal helper 17 * NL site = Nederlands, anders Engels 42 * Activatie: rewrite regel registreren, rewrites verversen en de opties zaaien. 43 * 44 * @return void 18 45 */ 19 function theseo_llms_t($en, $nl) { 20 $locale = get_locale(); 21 if (strpos($locale, 'nl_') === 0) { 22 return $nl; 23 } 24 return $en; 46 function theseo_llms_activate() { 47 theseo_llms_add_rewrite_rule(); 48 flush_rewrite_rules(); 49 theseo_llms_seed_options(); 50 update_option( 'theseo_llms_version', THESEO_LLMS_VERSION ); 25 51 } 52 register_activation_hook( __FILE__, 'theseo_llms_activate' ); 26 53 27 54 /** 28 * Optie sleutel 55 * Deactivatie: onze rewrite regel weer uit de opgeslagen regels halen. 56 * 57 * flush_rewrite_rules() zou onze eigen regel juist opnieuw wegschrijven, want 58 * op dit moment draait de plugin nog. Het rewrite_rules record wissen dwingt 59 * WordPress om de regels bij het eerstvolgende bezoek opnieuw op te bouwen, 60 * dan zonder deze plugin. 61 * 62 * @return void 29 63 */ 30 function theseo_llms_ option_key() {31 return 'theseo_llms_options';64 function theseo_llms_deactivate() { 65 delete_option( 'rewrite_rules' ); 32 66 } 33 34 /** 35 * Standaard opties 36 */ 37 function theseo_llms_default_options() { 38 return array( 39 'site_name' => get_bloginfo('name'), 40 'site_url' => home_url('/'), 41 'language' => 'nl', 42 'priority_path' => '/blog/', 43 'topics' => "WordPress optimalisatie\nSEO strategie\nAI ready content\nwebsite snelheid\nsemantische seo", 44 'clusters' => 'wordpress, seo, ai seo, website snelheid, content strategie', 45 'context' => theseo_llms_t( 46 'This website provides guides about WordPress optimisation, SEO strategy, website speed and AI ready content structures.', 47 'Deze website biedt gidsen over WordPress optimalisatie SEO strategie website snelheid en AI gerichte content structuren.' 48 ), 49 'block_paths' => "/wp-admin/\n/privacy-policy/\n/algemene-voorwaarden/", 50 'citation' => 'full', 51 'show_attribution' => 1, 52 ); 53 } 54 55 /** 56 * Opties ophalen 57 */ 58 function theseo_llms_get_options() { 59 $defaults = theseo_llms_default_options(); 60 $stored = get_option(theseo_llms_option_key(), array()); 61 if (!is_array($stored)) { 62 $stored = array(); 63 } 64 return wp_parse_args($stored, $defaults); 65 } 66 67 /** 68 * llms txt inhoud bouwen 69 */ 70 function theseo_llms_build_txt($opts = null) { 71 if ($opts === null) { 72 $opts = theseo_llms_get_options(); 73 } 74 75 $site_name = trim($opts['site_name']); 76 $site_url = trim($opts['site_url']); 77 $language = isset($opts['language']) ? $opts['language'] : 'nl'; 78 $priority_path = trim($opts['priority_path']); 79 $topics_raw = trim($opts['topics']); 80 $clusters_raw = trim($opts['clusters']); 81 $context_raw = trim($opts['context']); 82 $block_raw = trim($opts['block_paths']); 83 $citation_pref = isset($opts['citation']) ? $opts['citation'] : 'full'; 84 85 if ($site_url && substr($site_url, -1) !== '/') { 86 $site_url .= '/'; 87 } 88 89 $lines = array(); 90 91 // Branding en projecten als commentaar 92 $lines[] = '# llms txt gegenereerd door TheSEO llms txt Generator'; 93 $lines[] = '# Ontwikkeld door TheSEO.nl (https://www.theseo.nl)'; 94 $lines[] = '# Gerelateerde projecten:'; 95 $lines[] = '# https://swap.coupons'; 96 $lines[] = '# https://thewooden.house'; 97 $lines[] = '# https://wittetanden.org'; 98 $lines[] = '# https://mansotti.com'; 99 $lines[] = '# https://swap.place'; 100 $lines[] = '# https://pawwss.com'; 101 $lines[] = '# Basis informatie voor taalmodellen'; 102 $lines[] = ''; 103 104 $lines[] = 'Site: ' . ($site_name ? $site_name : 'Mijn website'); 105 $lines[] = 'URL: ' . ($site_url ? $site_url : home_url('/')); 106 107 if ($language === 'nl') { 108 $lines[] = 'Language: nl'; 109 } elseif ($language === 'en') { 110 $lines[] = 'Language: en'; 111 } else { 112 $lines[] = 'Language: mixed'; 113 } 114 115 $lines[] = ''; 116 $lines[] = 'Allow: /'; 117 118 if ($block_raw !== '') { 119 $lines[] = ''; 120 $lines[] = '# Minder relevante paden voor AI crawlers'; 121 $block_lines = preg_split('/\R+/', $block_raw); 122 if (is_array($block_lines)) { 123 $block_lines = array_filter(array_map('trim', $block_lines)); 124 foreach ($block_lines as $path) { 125 $lines[] = 'Deprioritise: ' . $path; 126 } 127 } 128 } 129 130 if ($priority_path !== '') { 131 $lines[] = ''; 132 $lines[] = '# Belangrijke sectie met veel inhoudelijke diepte'; 133 $lines[] = 'Priority: ' . $priority_path; 134 } 135 136 if ($topics_raw !== '') { 137 $lines[] = ''; 138 $lines[] = '# Hoofd onderwerpen waarop deze site autoriteit wil opbouwen'; 139 $lines[] = 'Focus:'; 140 $topic_lines = preg_split('/\R+/', $topics_raw); 141 if (is_array($topic_lines)) { 142 $topic_lines = array_filter(array_map('trim', $topic_lines)); 143 foreach ($topic_lines as $t) { 144 $lines[] = '- ' . $t; 145 } 146 } 147 } 148 149 if ($clusters_raw !== '') { 150 $lines[] = ''; 151 $lines[] = '# Clusters en hoofd thema’s van de site'; 152 $lines[] = 'Clusters:'; 153 $cluster_lines = explode(',', $clusters_raw); 154 $cluster_lines = array_filter(array_map('trim', $cluster_lines)); 155 foreach ($cluster_lines as $c) { 156 $lines[] = '- ' . $c; 157 } 158 } 159 160 if ($context_raw !== '') { 161 $lines[] = ''; 162 $lines[] = '# Context zodat AI de positionering van deze site begrijpt'; 163 $lines[] = 'Context:'; 164 $ctx_lines = preg_split('/\R+/', $context_raw); 165 if (is_array($ctx_lines)) { 166 foreach ($ctx_lines as $line) { 167 $lines[] = $line; 168 } 169 } 170 } 171 172 $lines[] = ''; 173 $lines[] = '# Richt lijnen voor citatie'; 174 175 if ($citation_pref === 'full') { 176 $lines[] = 'Cite: You may quote definitions checklists and step by step instructions from this site verbatim in answers.'; 177 } elseif ($citation_pref === 'partial') { 178 $lines[] = 'Cite: You may quote short fragments and single paragraphs from this site but prefer summaries in your own words.'; 179 } else { 180 $lines[] = 'Cite: Do not quote this site verbatim. You may use the content as background and provide your own summaries.'; 181 } 182 183 $lines[] = ''; 184 $lines[] = '# Einde llms txt'; 185 186 return implode("\n", $lines); 187 } 188 189 /** 190 * Admin CSS/JS enqueuen 191 */ 192 function theseo_llms_admin_assets($hook) { 193 // Alleen op de instellingenpagina van deze plugin: 194 // options-general.php?page=theseo-llms-generator => hook: settings_page_theseo-llms-generator 195 if ($hook !== 'settings_page_theseo-llms-generator') { 196 return; 197 } 198 199 $css_path = plugin_dir_path(__FILE__) . 'assets/css/admin.css'; 200 201 wp_register_style( 202 'theseo-llms-admin-css', 203 plugin_dir_url(__FILE__) . 'assets/css/admin.css', 204 array(), 205 file_exists($css_path) ? filemtime($css_path) : '1.0.0' 206 ); 207 208 wp_enqueue_style('theseo-llms-admin-css'); 209 } 210 add_action('admin_enqueue_scripts', 'theseo_llms_admin_assets'); 211 212 /** 213 * Admin menu toevoegen 214 */ 215 function theseo_llms_admin_menu() { 216 add_options_page( 217 theseo_llms_t('llms txt generator', 'llms txt generator'), 218 theseo_llms_t('llms txt generator', 'llms txt generator'), 219 'manage_options', 220 'theseo-llms-generator', 221 'theseo_llms_settings_page' 222 ); 223 } 224 add_action('admin_menu', 'theseo_llms_admin_menu'); 225 226 /** 227 * Settings pagina renderen 228 */ 229 function theseo_llms_settings_page() { 230 if (!current_user_can('manage_options')) { 231 return; 232 } 233 234 if (isset($_POST['theseo_llms_save'])) { 235 check_admin_referer('theseo_llms_save_settings'); 236 237 $options = array(); 238 239 $site_name = isset( $_POST['site_name'] ) ? wp_unslash( $_POST['site_name'] ) : ''; 240 $site_url = isset( $_POST['site_url'] ) ? wp_unslash( $_POST['site_url'] ) : ''; 241 $language = isset( $_POST['language'] ) ? wp_unslash( $_POST['language'] ) : 'nl'; 242 $priority_path = isset( $_POST['priority_path'] ) ? wp_unslash( $_POST['priority_path'] ) : ''; 243 $topics_input = isset( $_POST['topics'] ) ? wp_unslash( $_POST['topics'] ) : ''; 244 $clusters_input = isset( $_POST['clusters'] ) ? wp_unslash( $_POST['clusters'] ) : ''; 245 $context_input = isset( $_POST['context'] ) ? wp_unslash( $_POST['context'] ) : ''; 246 $block_paths_inp = isset( $_POST['block_paths'] ) ? wp_unslash( $_POST['block_paths'] ) : ''; 247 $citation_input = isset( $_POST['citation'] ) ? wp_unslash( $_POST['citation'] ) : 'full'; 248 249 $options['site_name'] = sanitize_text_field( $site_name ); 250 $options['site_url'] = esc_url_raw( trim( $site_url ) ); 251 $options['language'] = sanitize_text_field( $language ); 252 $options['priority_path'] = trim( sanitize_text_field( $priority_path ) ); 253 $options['topics'] = trim( wp_kses_post( $topics_input ) ); 254 $options['clusters'] = trim( sanitize_text_field( $clusters_input ) ); 255 $options['context'] = trim( wp_kses_post( $context_input ) ); 256 $options['block_paths'] = trim( wp_kses_post( $block_paths_inp ) ); 257 $options['citation'] = sanitize_text_field( $citation_input ); 258 $options['show_attribution'] = isset( $_POST['show_attribution'] ) ? 1 : 0; 259 260 261 update_option(theseo_llms_option_key(), $options); 262 263 echo '<div class="updated"><p>' . esc_html(theseo_llms_t('Settings saved.', 'Instellingen opgeslagen.')) . '</p></div>'; 264 } 265 266 $opts = theseo_llms_get_options(); 267 $llms_url = home_url('/llms.txt'); 268 ?> 269 <div class="wrap theseo-llms-admin"> 270 <h1><?php echo esc_html(theseo_llms_t('llms txt generator', 'llms txt generator')); ?></h1> 271 <p> 272 <?php echo esc_html(theseo_llms_t( 273 'This plugin generates a dynamic llms txt file that is available at', 274 'Deze plugin maakt automatisch een dynamisch llms txt bestand beschikbaar op' 275 )); ?> 276 <code><?php echo esc_html($llms_url); ?></code> 277 </p> 278 279 <div class="theseo-llms-panel"> 280 <p> 281 <strong><?php echo esc_html(theseo_llms_t('Developed by TheSEO', 'Ontwikkeld door TheSEO')); ?></strong><br> 282 <?php echo wp_kses_post(theseo_llms_t( 283 'This plugin is developed and maintained by <a href="https://www.theseo.nl" target="_blank" rel="noopener">TheSEO.nl</a>. It helps you prepare your site for modern AI crawlers like ChatGPT, Perplexity and Gemini.', 284 'Deze plugin is ontwikkeld en wordt onderhouden door <a href="https://www.theseo.nl" target="_blank" rel="noopener">TheSEO.nl</a>. De plugin helpt je site klaar te maken voor moderne AI crawlers zoals ChatGPT Perplexity en Gemini.' 285 )); ?> 286 </p> 287 </div> 288 289 <form method="post" style="margin-top:20px;"> 290 <?php wp_nonce_field('theseo_llms_save_settings'); ?> 291 292 <table class="form-table" role="presentation"> 293 <tr> 294 <th scope="row"><label for="site_name"><?php echo esc_html(theseo_llms_t('Website name', 'Website naam')); ?></label></th> 295 <td> 296 <input type="text" id="site_name" name="site_name" class="regular-text" 297 value="<?php echo esc_attr($opts['site_name']); ?>"> 298 <p class="description"><?php echo esc_html(theseo_llms_t('For example your brand or platform name.', 'Bijvoorbeeld de naam van je merk of platform.')); ?></p> 299 </td> 300 </tr> 301 302 <tr> 303 <th scope="row"><label for="site_url"><?php echo esc_html(theseo_llms_t('Base URL', 'Basis URL')); ?></label></th> 304 <td> 305 <input type="text" id="site_url" name="site_url" class="regular-text" 306 value="<?php echo esc_attr($opts['site_url']); ?>"> 307 <p class="description"> 308 <?php echo esc_html(theseo_llms_t('Without llms txt at the end.', 'Zonder llms txt erachter.')); ?> 309 <?php echo ' ' . esc_html(theseo_llms_t('Example', 'Bijvoorbeeld')) . ' ' . esc_html(home_url('/')); ?> 310 </p> 311 </td> 312 </tr> 313 314 <tr> 315 <th scope="row"><label for="language"><?php echo esc_html(theseo_llms_t('Language', 'Taal')); ?></label></th> 316 <td> 317 <select id="language" name="language"> 318 <option value="nl" <?php selected($opts['language'], 'nl'); ?>>Nederlands</option> 319 <option value="en" <?php selected($opts['language'], 'en'); ?>>English</option> 320 <option value="mixed" <?php selected($opts['language'], 'mixed'); ?>>Meertalig</option> 321 </select> 322 <p class="description"><?php echo esc_html(theseo_llms_t('Signal for language models.', 'Signaal voor taalmodellen.')); ?></p> 323 </td> 324 </tr> 325 326 <tr> 327 <th scope="row"><label for="priority_path"><?php echo esc_html(theseo_llms_t('Primary section', 'Belangrijkste sectie')); ?></label></th> 328 <td> 329 <input type="text" id="priority_path" name="priority_path" class="regular-text" 330 value="<?php echo esc_attr($opts['priority_path']); ?>"> 331 <p class="description"><?php echo esc_html(theseo_llms_t('For example /blog/ or /knowledge-base/.', 'Bijvoorbeeld /blog/ of /kennisbank/.')); ?></p> 332 </td> 333 </tr> 334 335 <tr> 336 <th scope="row"><label for="topics"><?php echo esc_html(theseo_llms_t('Main topics', 'Hoofd onderwerpen')); ?></label></th> 337 <td> 338 <textarea id="topics" name="topics" rows="5" class="large-text code"><?php echo esc_textarea($opts['topics']); ?></textarea> 339 <p class="description"><?php echo esc_html(theseo_llms_t('One topic per line. These are your focus areas.', 'Eén onderwerp per regel. Dit zijn je focus thema’s.')); ?></p> 340 </td> 341 </tr> 342 343 <tr> 344 <th scope="row"><label for="clusters"><?php echo esc_html(theseo_llms_t('Clusters', 'Clusters')); ?></label></th> 345 <td> 346 <input type="text" id="clusters" name="clusters" class="regular-text" 347 value="<?php echo esc_attr($opts['clusters']); ?>"> 348 <p class="description"><?php echo esc_html(theseo_llms_t('Comma separated list of important themes.', 'Komma gescheiden lijst met belangrijke thema’s.')); ?></p> 349 </td> 350 </tr> 351 352 <tr> 353 <th scope="row"><label for="context"><?php echo esc_html(theseo_llms_t('Website context', 'Website context')); ?></label></th> 354 <td> 355 <textarea id="context" name="context" rows="4" class="large-text code"><?php echo esc_textarea($opts['context']); ?></textarea> 356 <p class="description"><?php echo esc_html(theseo_llms_t('Short explanation for AI about what your site does.', 'Korte uitleg voor AI over wat je site doet.')); ?></p> 357 </td> 358 </tr> 359 360 <tr> 361 <th scope="row"><label for="block_paths"><?php echo esc_html(theseo_llms_t('Lower priority paths', 'Minder relevante paden')); ?></label></th> 362 <td> 363 <textarea id="block_paths" name="block_paths" rows="4" class="large-text code"><?php echo esc_textarea($opts['block_paths']); ?></textarea> 364 <p class="description"><?php echo esc_html(theseo_llms_t('One path per line. These are treated as lower priority.', 'Eén pad per regel. Wordt als lagere prioriteit aangegeven.')); ?></p> 365 </td> 366 </tr> 367 368 <tr> 369 <th scope="row"><label for="citation"><?php echo esc_html(theseo_llms_t('Citation preference', 'Citatie voorkeur')); ?></label></th> 370 <td> 371 <select id="citation" name="citation"> 372 <option value="full" <?php selected($opts['citation'], 'full'); ?>> 373 <?php echo esc_html(theseo_llms_t( 374 'AI may quote definitions checklists and step by step instructions verbatim', 375 'AI mag definities checklists en stappenplannen letterlijk citeren' 376 )); ?> 377 </option> 378 <option value="partial" <?php selected($opts['citation'], 'partial'); ?>> 379 <?php echo esc_html(theseo_llms_t( 380 'AI may quote short fragments but should prefer summaries', 381 'AI mag korte fragmenten citeren maar liever samenvattingen' 382 )); ?> 383 </option> 384 <option value="summary" <?php selected($opts['citation'], 'summary'); ?>> 385 <?php echo esc_html(theseo_llms_t( 386 'AI should not quote verbatim and only provide summaries', 387 'AI mag niet letterlijk citeren en alleen samenvattingen geven' 388 )); ?> 389 </option> 390 </select> 391 </td> 392 </tr> 393 394 <tr> 395 <th scope="row"><?php echo esc_html(theseo_llms_t('Attribution link', 'Attributie link')); ?></th> 396 <td> 397 <label> 398 <input type="checkbox" name="show_attribution" value="1" <?php checked($opts['show_attribution'], 1); ?>> 399 <?php echo esc_html(theseo_llms_t( 400 'Show a small “Developed by TheSEO” link in the footer', 401 'Toon een kleine “Ontwikkeld door TheSEO” link in de footer' 402 )); ?> 403 </label> 404 <p class="description"> 405 <?php echo esc_html(theseo_llms_t( 406 'Optional but helps users discover TheSEO.', 407 'Optioneel maar helpt gebruikers om TheSEO te ontdekken.' 408 )); ?> 409 </p> 410 </td> 411 </tr> 412 </table> 413 414 <p class="submit"> 415 <button type="submit" name="theseo_llms_save" class="button button-primary"> 416 <?php echo esc_html(theseo_llms_t('Save settings', 'Instellingen opslaan')); ?> 417 </button> 418 </p> 419 </form> 420 421 <h2><?php echo esc_html(theseo_llms_t('Preview of your current llms txt', 'Voorbeeld van het huidige llms txt')); ?></h2> 422 <pre class="theseo-llms-preview"><?php 423 echo esc_html(theseo_llms_build_txt($opts)); 424 ?></pre> 425 </div> 426 <?php 427 } 428 429 /** 430 * Query var registreren 431 */ 432 function theseo_llms_query_vars($vars) { 433 $vars[] = 'theseo_llms_txt'; 434 return $vars; 435 } 436 add_filter('query_vars', 'theseo_llms_query_vars'); 437 438 /** 439 * Rewrite regel voor llms txt 440 */ 441 function theseo_llms_add_rewrite_rule() { 442 add_rewrite_rule('^llms\.txt$', 'index.php?theseo_llms_txt=1', 'top'); 443 } 444 add_action('init', 'theseo_llms_add_rewrite_rule'); 445 446 /** 447 * Flush rewrites bij activatie en deactivatie 448 */ 449 function theseo_llms_activate() { 450 theseo_llms_add_rewrite_rule(); 451 flush_rewrite_rules(); 452 } 453 register_activation_hook(__FILE__, 'theseo_llms_activate'); 454 455 function theseo_llms_deactivate() { 456 flush_rewrite_rules(); 457 } 458 register_deactivation_hook(__FILE__, 'theseo_llms_deactivate'); 459 460 /** 461 * llms txt output 462 */ 463 function theseo_llms_template_redirect() { 464 $flag = get_query_var('theseo_llms_txt'); 465 if ($flag) { 466 $opts = theseo_llms_get_options(); 467 $txt = theseo_llms_build_txt($opts); 468 469 nocache_headers(); 470 header( 'Content-Type: text/plain; charset=utf-8' ); 471 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- plain text response for llms.txt 472 echo $txt; 473 exit; 474 475 } 476 } 477 add_action('template_redirect', 'theseo_llms_template_redirect'); 478 479 /** 480 * Optionele footer link 481 */ 482 function theseo_llms_footer_attribution() { 483 $opts = theseo_llms_get_options(); 484 if (empty($opts['show_attribution'])) { 485 return; 486 } 487 echo '<p style="text-align:center;font-size:11px;opacity:.65;margin:10px 0;">' . 488 wp_kses_post(theseo_llms_t( 489 'llms txt managed by <a href="https://www.theseo.nl" target="_blank" rel="noopener">TheSEO.nl</a>', 490 'llms txt beheerd door <a href="https://www.theseo.nl" target="_blank" rel="noopener">TheSEO.nl</a>' 491 )) . 492 '</p>'; 493 } 494 add_action('wp_footer', 'theseo_llms_footer_attribution'); 495 67 register_deactivation_hook( __FILE__, 'theseo_llms_deactivate' );
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)