Sitemap Pages – multilingual site map for the Page module (Cotonti)
The Sitemap Pages plugin generates separate XML sitemap files for each language specified in the settings, and optionally one common index file (sitemap index).
- Category Extentions
- SEO and optimization
- Availability
- Free
Sitemap Pages – multilingual sitemap for the Page module (Cotonti)
The Sitemap Pages plugin generates individual XML sitemap files for each language specified in the settings and, optionally, a single index file (sitemap index). For languages other than the primary one, only categories and pages that have translations in the standard i18n plugin (tables cot_i18n_structure and cot_i18n_pages) are included in the map.
System Requirements and Dependencies
- Cotonti version 1.0+ (tested with PHP 8.5+ and MySQL 8.4).
- The
pagemodule – must be installed and active. - The
i18nplugin (Content Internationalization) – must be installed and active. The plugin uses its tables (cot_i18n_structureandcot_i18n_pages) to determine which categories and pages have translations for a specific language. - mod_rewrite in Apache (or an equivalent in Nginx) must be configured for clean URLs to work.
Plugin Structure
The plugin is located in the folder plugins/sitemap_pages/ and contains the following files:
sitemap_pages/
├── sitemap_pages.setup.php # Header, metadata and plugin settings
├── sitemap_pages.ajax.php # Main request handler (AJAX)
├── inc/
│ └── sitemap_pages.functions.php # Functions: map generation, URL and language handling
├── lang/
│ ├── sitemap_pages.ru.lang.php # Russian setting labels
│ └── sitemap_pages.en.lang.php # English setting labels
├── tpl/
│ ├── sitemap_pages.tpl # Template for a regular urlset
│ └── sitemap_pages.index.tpl # Template for the index file (sitemapindex)
└── setup/
└── sitemap_pages.install.php # Automatically adds a sitemap link to robots.txt on install
The templates already contain the correct XML markup and do not require manual editing.
Installation
- Download the
sitemap_pagesfolder and copy it to theplugins/directory of your Cotonti site. - Go to the admin panel: Extensions → Plugins.
- Find
Pages Sitemap (multilingual)in the list and click Install. - During installation, the plugin automatically adds the line
Sitemap: https://yoursite/sitemap-pages.xmltorobots.txt(if the file is writable). Any previous mentions ofsitemap-pages.xmlare removed to avoid duplicates.
After installation, the plugin is ready for configuration.
Admin Settings
Go to Extensions → Plugins → Pages Sitemap (multilingual) → Configuration.
| Parameter | Default Value | Description |
|---|---|---|
| Languages (languages) | empty | A comma-separated list of languages, e.g., en,ru,ua. If left empty, all active languages from the Cotonti configuration (Cot::$cfg['languages']) are used. |
| Default language (default_lang) | ua | The language for which no prefix is added to the URL (e.g., /page.php?id=1 instead of /ua/page.php?id=1). |
| Use clean URLs (use_pretty_urls) | 0 (disabled) | If enabled (1), map URLs will look like /sitemap-pages.xml and /en/sitemap-pages.xml. If disabled, direct links with index.php?r=sitemap_pages are used. It is recommended to enable after setting up .htaccess. |
| Include category pagination (pageCategoryPagination) | 1 (enabled) | If a category has multiple pages of entries, URLs with parameters ?d=2, ?d=3, etc. will be added to the map. |
| Page change frequency (page_freq) | weekly | The value of the <changefreq> tag for pages. |
| Page priority (page_prio) | 0.5 | The value of the <priority> tag for pages. |
| Max URLs per map part (perpage) | 50000 | If the total number of URLs exceeds this number, the map will be split into multiple files (usually not necessary). |
| Cache time to live (cache_ttl) | 3600 | The period (in seconds) after which the cached maps are considered stale and will be regenerated on the next request. |
After changing settings, click Save.
.htaccess Configuration
To enable clean URLs (if you have turned on use_pretty_urls), add the following lines to the root .htaccess right after the rule RewriteRule ^sitemap\.xml$ ...:
RewriteRule ^sitemap-pages\.xml$ index.php?r=sitemap_pages [QSA,L]
RewriteRule ^(en|ru|pl|ua)/sitemap-pages\.xml$ index.php?r=sitemap_pages&l=$1 [QSA,L]
Important: the
[QSA](Query String Append) flag is required, because Cotonti’s language rule may already add a?l=enparameter, and withoutQSAit will be lost.
Make sure these rules are placed before the line # All the rest goes through standard rewrite gateway.
robots.txt Configuration
During installation, the plugin automatically adds the following line:
Sitemap: https://yoursite/sitemap-pages.xml
If the automatic addition fails (for example, robots.txt is not writable), add this line manually at the end of the file.
If you want to list all language maps directly, you can add:
Sitemap: https://yoursite/sitemap-pages.xml
Sitemap: https://yoursite/en/sitemap-pages.xml
Sitemap: https://yoursite/ru/sitemap-pages.xml
Sitemap: https://yoursite/pl/sitemap-pages.xml
However, it is preferable to use the index file (see below) and specify only that.
Browser Check
Right after installation and configuration, you can open the following addresses (the cache will be created automatically on first access):
- Default language (ua):
https://yoursite/sitemap-pages.xml - English version:
https://yoursite/en/sitemap-pages.xml - Russian version:
https://yoursite/ru/sitemap-pages.xml - Polish version:
https://yoursite/pl/sitemap-pages.xml - Index file (list of all languages):
https://yoursite/index.php?r=sitemap_pages&a=index
Each of these links will show an XML document with page URLs (and categories, if pagination is enabled). If you see an empty <urlset>, check whether there are translated pages for that language in the cot_i18n_pages table and whether the i18n plugin is enabled with correct locales.
How to Submit to Google Search Console
- Sign in to Google Search Console (https://search.google.com/search-console).
- Select the desired property (website).
- In the left menu, go to: Index → Sitemaps.
- Click Add a new sitemap.
- Paste the index file URL:
https://yoursite/index.php?r=sitemap_pages&a=index - Click Submit.
Google will read the index file and automatically add all the language sub-maps listed in it. You can also submit each language map individually, but it is not necessary.
After submission, check the status — it should show “Success” and the number of discovered pages.
Caching and Cache Clearing
The plugin saves generated XML files in the folder datas/cache/sitemap_pages/. Inside you will see:
ua.xml– map for the default language.en.xml,ru.xml,pl.xml– maps for other languages.*.count– auxiliary files with record counts.sitemap_pages_index.xml– the index file (if it was requested).
If you change the plugin settings or modify the code, delete all files from this folder manually (via FTP or a file manager). The cache will be regenerated automatically on the next request to any map. In everyday use, clearing is not required – only when changes are made.
Troubleshooting
- All language URLs show only
ua.xml.
Cause: missing the[QSA]flag in the.htaccessrules (see section 5). AddQSAto both lines. - The URL contains a duplicated language prefix (
/en/en/page.php?id=1).
Cause: thesitemap_pages_urlfunction does not remove the already added prefix. Make sure thatinc/sitemap_pages.functions.phpuses the correct version of the function (it cleans the path of known prefixes). - Empty file for some languages.
This means there are no records in thecot_i18n_pages(orcot_i18n_structure) table with the corresponding locale. Check the translations in thei18nplugin. - The map does not update after changing settings.
Clear the cache manually (delete the contents ofdatas/cache/sitemap_pages/). - Error “XML declaration allowed only at the start of the document” in the browser.
Make sure that thesitemap_pages.tplandsitemap_pages.index.tpltemplates do not contain the line<?xml version="1.0" encoding="UTF-8"?>, and that the script itself starts with the correct XML declaration (it is added programmatically). Also check that the files do not have a BOM or extra whitespace at the beginning. - Google Search Console does not accept the map.
Make sure the file conforms to the Sitemap Protocol standard. Use an XML sitemap validator to check, for example:
https://www.xml-sitemaps.com/validate-xml-sitemap.html
Additional Notes
- The
sitemap_pages.index.tpltemplate is only used for the page with?a=indexand generates an<sitemapindex>. If you do not plan to use the index, you can leave this template as is. - The plugin is completely independent from the old
sitemapplugin. You can continue using both simultaneously for different modules. - When adding a new language, make sure it is present in:
- the plugin settings (
languages); - the
.htaccessrules (the(en|ru|pl|ua)list); - the prefix removal function (
$knownLangsinsitemap_pages_url).
- the plugin settings (
- All questions, suggestions, and bug reports can be sent to support:
https://abuyfile.com/forums/cotonti/custom/plugs/
Which Is Better: One Huge File or Separate Maps by Module and Language?
Direct answer: separate maps by module and language are better for my specific project. One huge file creates more problems than it solves.
Here is a comparison on key points.
✅ Advantages of Separate Maps (My Approach)
- Generation performance
Each map is generated only for its own module (market / page) and language. This is faster, uses less memory, and does not block the site. A huge combined file would have to be completely rebuilt even if only one page changed. - Flexible caching
Each module has its own cache TTL (Time To Live – the cache lifetime in seconds). Products might update daily, while pages update weekly. A single file lacks this flexibility – everything would share the same TTL. - Fault tolerance
If the product map generation breaks, the page map continues to work. In a monolithic file, one error breaks everything. - Ease of debugging
You can immediately see which module/language caused the problem. The logic of each module is isolated. - Alignment with Cotonti architecture
Cotonti is modular – plugins likesitemap_marketandsitemap_pagesare independent, they can be installed and updated separately. A monolith would break this concept. - SEO transparency
Search engines get a clear structure: a separate map for products, a separate one for pages, each in multiple language versions. This simplifies indexing and coverage analysis in Search Console. - Avoiding limits
Google accepts files up to 50,000 URLs and 50 MB. By splitting by module and language, you avoid hitting the limit without additional fragmentation.
❌ Disadvantages of Separate Maps
- More entries in robots.txt
Instead of a singleSitemapline, you either need to list several maps or add an index file (sitemapindex) that points to the others. This is not a problem, just a minor complication. - Slightly more requests from search engines
Instead of one file, the bot will fetch several. But this is negligible load, and Google handles multiple sitemap files without issues.
🤔 What Would Have Happened with One Big File
- Generation would take many times longer, using more memory.
- Every update to any module would require the entire file to be rebuilt from scratch.
- It would be harder to stay within the 50,000 URL limit – you would still need to split into parts, losing the point of a monolith.
- Debugging would become more complex: any error in one module would break the entire map.
In the old monolithic plugin, all modules (market, page, forums, users) were gathered into one XML file (or several parts if the limit was exceeded). In that setup:
- Settings like
market_freq,page_freq,forums_freq,users_freqonly set the<changefreq>tag inside the XML – they told the search engine how often the content supposedly changes. But they did not control the actual regeneration of the map. - The actual regeneration frequency was determined by a single parameter
cache_ttlfor the whole plugin. As soon as the cache expired (more seconds than specified incache_ttlhad passed since the last generation), data from all modules was collected anew – even if products update every 5 minutes and pages once a month.
Thus, adding a single new product forced the entire giant file to be rebuilt: market categories and products, pages, forums, users. The more modules were enabled, the longer and more resource-intensive each regeneration became.
In the new approach (separate plugins), each module has its own cache_ttl, so:
- The product map can regenerate every 30 minutes,
- The page map – once a day,
- The forum map – once a week.
When a product is updated, only the product map is rebuilt; the page and forum maps remain in cache and consume no resources. That is the flexibility the monolith lacked.
Conclusion:
Conclusion: the current approach — separate maps by module and language — is optimal for Cotonti. It scales well, runs faster, and better matches the system’s modular architecture. One huge file only wins in the minimalism of robots.txt, but that advantage is neutralized by using an index file (sitemapindex), which you can easily enable.
Notes on Sitemap Pages Plugin Setup and Operation
1. “Languages” Setting (languages) – Do You Need to Include the Default Language?
In short: now it is not necessary to include the default language in the languages field. The sitemap_pages_get_languages() function always forcibly adds the default language (default_lang) to the list if it is missing.
How it works with different input scenarios:
- The
languagesfield is filled (e.g.,en,ru,pl)
The plugin takes the specified languages and addsdefault_langto them (if not already in the list). As a result, the index will contain all listed languages + the default language. This guarantees that the primary language is never omitted, even if the admin forgets to include it. - The
languagesfield is empty
The plugin retrieves all active locales from theCot::$cfg['plugin']['i18n']['locales']setting (e.g.,ua, en, ru, pl) and also addsdefault_langif it happens to be missing. Thus, the index includes all available site languages without the need to list them manually.
Recommendation:
If you want all languages supported by the i18n plugin to appear in the sitemap, simply leave the languages field empty. If you need to limit the set of languages (for example, exclude a language), list the desired codes separated by commas — the default language will be added automatically.
2. How Settings Affect the Index File (?r=sitemap_pages&a=index)
The index file is built strictly based on the language array returned by the sitemap_pages_get_languages() function. Therefore:
- Regardless of the configuration (empty or a list), the index always contains the default language.
- If additional languages are listed in the
languagesfield, they also appear in the index. - If the field is empty, the index includes all locales registered in the i18n plugin.
As a result, you get a complete index where each language has a separate <sitemap> entry pointing to the corresponding language map (e.g., /sitemap-pages.xml for the default language and /en/sitemap-pages.xml for English).
3. Why the File at ?r=sitemap_pages&a=index Is Needed and What It Should Contain
This is a Sitemap Index file — a standard element of the Sitemaps protocol designed to combine multiple sitemaps into a single entry point.
Purpose:
- Allows you to submit one URL to search engines, which automatically reveals all language versions of the maps.
- Complies with search engine limits (no more than 50,000 URLs or 50 MB per file) — splitting by language removes these limits.
- Simplifies management: when adding a new language, you don’t need to modify
robots.txt, just update the plugin settings.
What the Index Must Contain:
- A root
<sitemapindex>element with the correct namespace. - For each active language — a separate
<sitemap>block containing:<loc>— the absolute URL of the language map (for the primary language – without a prefix, for others – with a prefix like/en/).<lastmod>— the last modification date of that map.
- All languages for which at least one page or category exists.
What Must Not Be Present:
<url>elements (they are allowed only inside regular sitemaps, not in an index).- Missing languages (the primary language must always be present).
- Duplicate links to the same language map.
- Broken links to non-existent map files.
- Languages for which there are no translated pages or translated categories (they can still be present, but then the map will be empty — this is allowed but not optimal; it is better to exclude them if no translation is planned).
Example of a Correct Index for Four Languages (ua, en, ru, pl):
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://yourproject.com/sitemap-pages.xml</loc>
<lastmod>2026-08-04T09:02:52+00:00</lastmod>
</sitemap>
<sitemap>
<loc>https://yourproject.com/en/sitemap-pages.xml</loc>
<lastmod>2026-08-04T09:02:52+00:00</lastmod>
</sitemap>
<sitemap>
<loc>https://yourproject.com/ru/sitemap-pages.xml</loc>
<lastmod>2026-08-04T09:02:52+00:00</lastmod>
</sitemap>
<sitemap>
<loc>https://yourproject.com/pl/sitemap-pages.xml</loc>
<lastmod>2026-08-04T09:02:52+00:00</lastmod>
</sitemap>
</sitemapindex>
This is the file you should submit to Google Search Console — it will ensure the indexing of all language versions of your site.
Adding a Rewrite Rule for the Index File
If you want to create a rewrite rule for the sitemap index URL https://yourproject.com/index.php?r=sitemap_pages&a=index so that it becomes a clean URL:
Add the following rule to the root .htaccess right after the lines
RewriteRule ^sitemap-pages\.xml$ index.php?r=sitemap_pages [QSA,L]
RewriteRule ^(en|ru|pl|ua)/sitemap-pages\.xml$ index.php?r=sitemap_pages&l=$1 [QSA,L]
and before the line
# All the rest goes through standard rewrite gateway
this directive:
RewriteRule ^sitemap-pages-index\.xml$ index.php?r=sitemap_pages&a=index [QSA,L]
After that, the index file will be available at the clean URL:https://yourproject.com/sitemap-pages-index.xml
Do not remove the existing rule for ?r=sitemap_pages&a=index — it will work in parallel. But for Google Search Console, now use specifically https://yourproject.com/sitemap-pages-index.xml.
Offline
webitproff
Last logged: 2026-09-19 10:26
- Publication date 2026-08-03 23:04
- Updated 2026-09-13 14:17
Page Discussion in Telegram
Последние сообщения
- i18n modified - Модифицированный плагин мультиязычности
webitproff, 2026-09-19 07:55i18n modified - Модифицированный плагин мультиязычности
- Пропали ссылки на плагины в шаблонах
webitproff, 2026-09-19 06:07еще по теме, если есть ложное срабатывание при проверке активности плагина, - читать статью “Баг в ядре Cotonti при проверки активности плагина с всего одним хуком”
- Market PRO + всё, что связано с ЧПУ
webitproff, 2026-09-13 01:11частиный functions.custom.php <?php /** * Файл: system/functions.custom.php * * Читать инструкцию https://github.com/webitproff/functions.custom.php-cotonti/blob/main/README.md * * Пользоват...
- Market PRO + всё, что связано с ЧПУ
webitproff, 2026-09-13 01:09пресет правил/plugins/urleditor/presets/marketplace.datforums m=posts&q=&d= forums/{forums_url_structure()}/page{$d} forums m=posts&q=* forums/{forums_url_structure()} forums ...
- Tab "вкладка товаров" на странице профиля пользователя
webitproff, 2026-09-13 00:43Подробное описание файла market.userdetails.php1. Общая информация Параметр Значение Имя файла market.userdetails.php Расположение modules/market/market.userdetails.php Хук Cotonti users.details.ta...
- Multicat Market - Плагин для CMF Cotonti
webitproff, 2026-09-11 23:11Multicat MarketПлагин для модуля Market v5+ CMF Cotonti, позволяющий назначать одному товару (странице модуля Market) сразу несколько категорий структуры market. Вся реализация выполнена через стандар...
- Market PRO — модуль интернет-магазина и торговой площадки для Cotonti
webitproff, 2026-09-10 13:44Market PRO — модуль интернет-магазина и торговой площадки для CotontiГотовое решение для создания как классического интернет-магазина с одним продавцом, так и полноценной торговой площадки (маркетплей...
- Полное руководство по функции cot_market_enum()
webitproff, 2026-09-10 02:56Полное руководство по функции cot_market_enum()Функция cot_market_enum() — это мощный генератор списков товаров для модуля Market в Cotonti. Она позволяет вывести товары в любом месте сайта: на главно...
- В формах добавления и редактирования пропали картинки
webitproff, 2026-09-09 17:21Решил я “допекти” модуль товаров под котонти верону основательно. в процессе доработок тестирую, по привычке по ссылке гружу картинку к товару и какой-то там эрор без смысловой нагрузки и картинки нет...
- Инструкция: вывод в шаблон имени и ссылки на профиль пользователя в Cotonti
webitproff, 2026-09-07 15:15Инструкция: вывод имени и ссылки на профиль пользователя в CotontiВ этой инструкции описано, как получить данные о пользователе (текущем или владельце любой сущности) и передать их в шаблон в виде трё...
Market PRO Showcase
CMS, Script and Engine - website of an online showcase, online store of digital products and digital goods. Different prices in different currencies for the product. Online cryptocurrency payment for goods and services.