| name | bitrix-landing |
| description | Covers Landing module โ sites/landings, blocks repository, publish/unpublish flow, hooks (Metrika/GA/pixels), customization limits vs classic CMS. Applied for Sites24/landing pages, storefronts, knowledge bases on landing. Key terms โ Landing, Site, Block, BlockRepo, publication, unpublic, hooks, PAGE, STORE. |
Landing Sites (landing)
Baseline: main 23.0+. Verified against kernel module landing in this repo.
Block-based sites (Sites24 / Landing) live in module landing, not in classic site templates. For classic CMS sites/templates/menus see skill bitrix-cms-basics.
\Bitrix\Main\Loader::includeModule('landing');
Entity Model
| Layer | Facade | Internal ORM |
|---|
| Site | \Bitrix\Landing\Site | \Bitrix\Landing\Internals\SiteTable |
| Page (landing) | \Bitrix\Landing\Landing | \Bitrix\Landing\Internals\LandingTable |
| Block instance | \Bitrix\Landing\Block | \Bitrix\Landing\Internals\BlockTable |
| Domain / folder | \Bitrix\Landing\Domain, \Bitrix\Landing\Folder | internals tables |
Site and Landing extend \Bitrix\Landing\Internals\BaseTable and expose ORM-style getList / add / update / delete. Prefer facades over raw internals.
Site types (see \Bitrix\Landing\Site\Type): PAGE, STORE, SMN, scopes KNOWLEDGE, GROUP, MAINPAGE, pseudo-scope crm_forms.
Publication paths (constants on \Bitrix\Landing\Manager):
Manager::PUBLICATION_PATH โ /pub/site/
Manager::PUBLICATION_PATH_SITEMAN โ /lp/
Create / Read Pages
use Bitrix\Landing\Landing;
use Bitrix\Landing\Site;
$res = Landing::getList([
'select' => ['ID', 'TITLE', 'CODE', 'ACTIVE', 'PUBLIC', 'SITE_ID'],
'filter' => ['SITE_ID' => $siteId, '=DELETED' => 'N'],
]);
$landing = Landing::createInstance($landingId);
if (!$landing->exist()) {
}
$addResult = Landing::addByTemplate($siteId, 'empty', [
'TITLE' => 'Promo',
'CODE' => 'promo',
]);
Sites:
$siteUrl = Site::getPublicUrl($siteId, full: true, hostInclude: true);
$addSite = Site::addByTemplate('empty', 'PAGE');
Blocks Overview
Blocks are HTML fragments from a repository (BlockRepo::BLOCKS_DIR = 'blocks'). Paths resolved via BlockRepo::getGeneralPaths() โ typically /bitrix/blocks/ and /local/blocks/ (getLocalPath('blocks')).
use Bitrix\Landing\Block;
use Bitrix\Landing\Block\BlockRepo;
$landing = Landing::createInstance($landingId, ['skip_files' => false]);
$block = $landing->addBlock('01.big_with_text', [
// optional content overrides
]);
$blocks = $landing->getBlocks();
$one = $landing->getBlockById($blockId);
$repo = (new BlockRepo())->getRepository();
Useful block APIs: Block::createFromRepository(), Block::publicationBlocks(), getManifest(), saveContent() / content mutators on the instance.
Custom blocks: place under /local/blocks/<namespace>/<code>/ with block.php + .description.php (same layout as kernel install/blocks/bitrix/...). Clear repo cache after deploy: Block::clearRepositoryCache() / BlockRepo cache.
Publish Flow
Orienting APIs (do not invent REST wrappers):
| Action | API |
|---|
| Publish one page | $landing->publication() โ bool |
| Dry-run publish errors | $landing->fakePublication() |
| Unpublish page | $landing->unpublic() |
| Publish whole site | Site::publication($siteId, mark: true) โ Result |
| Unpublish site | Site::unpublic($siteId) / Site::publication($id, false) |
| Public URL | $landing->getPublicUrl(), Site::getPublicUrl() |
| Rights | $landing->canPublication(), $landing->canEdit() |
$landing = Landing::createInstance($landingId);
if ($landing->canPublication() && $landing->publication()) {
$url = $landing->getPublicUrl();
} else {
$errors = $landing->getError();
}
$siteResult = Site::publication($siteId, true);
if (!$siteResult->isSuccess()) {
foreach ($siteResult->getErrors() as $error) {
}
}
AJAX/public-action layer (admin UI): \Bitrix\Landing\PublicAction\Landing::publication($lid) and related methods in publicaction/landing.php โ same domain, UI-oriented.
Soft delete: Landing::markDelete / markUnDelete, Site::markDelete โ recycle bin, not hard delete().
Hooks (SEO / Counters)
Page/site extras via \Bitrix\Landing\Hook / Landing::getAdditionalFields / saveAdditionalFields. Relevant hook classes under lib/hook/page/:
YaCounter โ Yandex.Metrika counter ID
GaCounter, Gtm โ Google Analytics / GTM
MetaMain, MetaOg, MetaRobots, MetaYandexVerification, MetaGoogleVerification
PixelFb, PixelVk, Robots
Do not confuse with \Bitrix\Landing\Metrika\Metrika โ that is Bitrix product analytics (AnalyticsEvent) on publish, not Yandex.Metrika.
Landing vs Classic CMS
| Need | Prefer |
|---|
| Marketing LP, block builder, STORE landing | landing |
| Multisite + PHP templates, menus, includes | classic CMS (bitrix-cms-basics) |
| Structured catalog/news with properties | iblock (bitrix-iblocks) |
| Deep custom PHP page logic | classic template / component โ not a landing block |
Landing pages are not site templates under /local/templates/. Mixing: a Bitrix site (CSite) can host publication paths; content model is still Landing entities.
Customization Limits
- Prefer hooks, custom blocks in
/local/blocks/, REST/placements โ avoid editing /bitrix/modules/landing/.
- Tariff/restriction gates:
\Bitrix\Landing\Restriction\Manager, Manager::FEATURE_* constants.
- Rights:
\Bitrix\Landing\Rights, \Bitrix\Landing\Role.
- Dynamic blocks / CRM forms have separate scopes โ check
Site\Type before assuming public URL.
- Internal URL rules:
\Bitrix\Landing\Internals\UrlRewriteTable (b_landing_urlrewrite) maps RULE โ LANDING_ID inside a landing site โ not a global SEO 301 table.
Checklist