From 79174cf235f4d5e76444c50b5f4febba9a4202be Mon Sep 17 00:00:00 2001 From: Ivan Bochkarev Date: Tue, 20 Oct 2026 22:49:27 +0600 Subject: [PATCH 1/6] docs(building-sites/contexts): fact-check pass, en/ru/es sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The section was written for MODX 2. The pages now describe what MODX 3 does, and the facts are taken from the code of the 3.x branch. **Fixed** - The path to the contexts is **Admin → Contexts** (`?a=context`), not "System -> Contexts" and not a "Tools" menu — the menu of the core has no `tools` entry at all (`_build/data/transport.core.menus.php:299`). - The button of the grid is **Create**, not "Create New" — the lexicon key `context_create` does not exist in 3.x (`manager/assets/modext/widgets/core/modx.grid.js:1184`). - The row menu of the grid offers **Edit**, not "Update Context" (`manager/assets/modext/widgets/system/modx.grid.context.js:161`). - The form of a new context asks for four fields: `key`, `name`, `description` and `rank`; the first two are required (`modx.grid.context.js:297-330`). The keys `mgr`, `web` and `root` are reserved (`core/src/Revolution/modContext.php:31`). - A new context is granted access right away: the **Administrator** group gets the *Context* policy and the anonymous user gets the *Load Only* policy (`core/src/Revolution/Processors/Context/Create.php:63-72,116-134`). The page said the opposite — that the `load` permission has to be added by hand since 2.2. - The access to a context is granted on the **Contexts** tab of the **Access Permissions** tab of a user group, reached through the lock icon in the user menu → **Access Control Lists** — not through a "Security/Permissions" menu, which does not exist in 3.x. - The instruction to edit `$modx->initialize('web');` in `index.php` is gone: the line does not exist in 3.x (`index.php:55-59` reads the context key from `config.context.php` next to it). - The file `core.config.php` is called `config.core.php`, and it holds an absolute path to the core — the installer writes it that way (`config.core.php:7`). - The Apache block drops `NameVirtualHost` and `TransferLog`, both of which are gone in Apache 2.4. **Added** - The two contexts of the core (`web` and `mgr`) and the constants `CONTEXT_DEFAULT` and `CONTEXT_MANAGER`. - The API: `switchContext()`, `getContext()`, `reloadContext()`, `modContext::getOption()` and `makeUrl($id, $context)`. The limitation of `switchContext()` — it does not load a custom session handler, the gateway sets it — is stated. - The events of the contexts, and a note that `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` and `OnBeforeRequest` do not exist in MODX 3. - The system settings that steer the contexts, with their values by default. - The processors of the contexts with the permission each one needs. - The media source of an element per context, the table `context_resource`, the values by default of the session settings, and the order the `cultureKey` of a request is taken from. **Rewritten** - The page of the second domain opens with the fact that MODX 3 does not match a host with a context by itself: the context is chosen by the gateway. The recipe now builds the gateway with `config.context.php`. Both the Russian pages and the Spanish page of the section follow the English one: the same headings, the same tables and the same examples. --- en/building-sites/contexts.md | 156 ++++++++++++++--- en/building-sites/contexts/gateway-plugin.md | 65 +++++--- en/building-sites/contexts/virtual-host.md | 134 +++++++-------- es/building-sites/contexts.md | 167 +++++++++++++++---- ru/building-sites/contexts.md | 154 ++++++++++++++--- ru/building-sites/contexts/gateway-plugin.md | 63 ++++--- ru/building-sites/contexts/virtual-host.md | 133 +++++++-------- 7 files changed, 592 insertions(+), 280 deletions(-) diff --git a/en/building-sites/contexts.md b/en/building-sites/contexts.md index 19a1642bd..8d116eb0c 100644 --- a/en/building-sites/contexts.md +++ b/en/building-sites/contexts.md @@ -1,56 +1,166 @@ --- title: "Contexts" -_old_id: "66" -_old_uri: "2.x/administering-your-site/contexts" +description: "Contexts in MODX: how they override system settings, how to create one, how access to them is granted, and the API, events and processors behind them." --- - Contexts allow MODX configuration settings to be overridden, extended, isolated, or shared across domains, sub-domains, sub-sites, multi-sites, cultural-specific sections, specific web applications, and so on. +A Context is a named set of configuration overrides that a request runs under: it carries its own settings, its own branch of the resource tree and its own access rules. - You can easily create a context from the Contexts menu under Tools. The context will then show up in your resource tree. Resources can easily be dragged between contexts to move them from one context to another. - - Note: there's nothing fundamentally _different_ about resources in different contexts, except that they now inherit the configuration settings of the context they are in. So, if you create a new context, you'll have to override the context settings in the context for any real, distinguishable change to appear. +MODX ships with two contexts — `web` (Website) for the front end and `mgr` (Manager) for the manager. A context is addressed by its **key**; that key is what you pass to `initialize()` and `switchContext()`. The **name** is a label for the interface. ## Creating a Context - First, go to the Contexts page, via System -> Contexts. Then, click on "Create New" in the grid. This will prompt you for a key and description. From there, right-click on your newly-created context, and click "Update Context". +Contexts are managed in the manager: **Admin** (the gear in the top menu) → **Contexts** (`?a=context`). The **Create** button opens a form with four fields: + +| Field | Required | Meaning | +| --- | --- | --- | +| `key` | yes | the identifier of the context; the value used in `initialize()` and `switchContext()` | +| `name` | yes | the label shown in the manager and in the resource tree | +| `description` | no | free text | +| `rank` | no | the order of the context in the tree | - This will bring you to a screen displaying the Context, and an empty grid of settings. From here you can add Context-specific settings that will override any System Settings. Your new context will be completely empty, requiring you to include any and all settings you will be using. +The keys `mgr`, `web` and `root` are reserved by the core. - Note that new contexts don't automatically get "load" permission for Anonymous users in 2.2+ - you'll need to add that in manually. +A new context is granted access right away: the **Administrator** user group receives the *Context* policy, and the anonymous user receives the *Load Only* policy — the right `load` and nothing else. The anonymous access is skipped when the request to the processor carries `enableAnonymous=0`. - When you create a new context besides the default "web" context, you may need to apply context settings to the web context as well. +Contexts appear in the resource tree as their own branch, and resources are moved between contexts by dragging them. ## Context Settings - You can create settings for any defined context by clicking on **System -> Contexts**, then right-click any context and select "Update Context". +The settings of a context override the [System settings](building-sites/settings) of the same name, and the settings of a user override the settings of the context. The order is: - Each context can have its own settings that override or extend the [System Settings](building-sites/settings "System Settings"). Contextual settings can in turn be overridden or extended by [User Settings](administering-your-site/security/users#Users-UsersUserSettings). The hierarchy to remember is this: +``` +System setting → Context setting → User setting +``` - System Setting -> Context Setting -> User Setting +A context setting is edited on the **Context Settings** tab of the context page: **Contexts** → right-click a context → **Edit**. Changing a setting clears the cache of that context, so a manual cache clear is not needed. -## Context Access +The settings a context usually overrides: -When creating a new context, make sure your desired user-groups have access to it: +| Setting | What it changes | +| --- | --- | +| `base_url` | the path part of the URLs of the context | +| `http_host` | the host the URLs are built for | +| `site_url` | the full URL of the context: scheme, host and path | +| `site_start` | the resource that opens the context | +| `cultureKey`, `locale` | the language and the locale of the request | +| `session_name`, `session_cookie_path`, `session_cookie_domain` | the session cookie of the context | + +The session settings of a context keep the values of the core unless they are overridden: + +| Setting | Value by default | +| --- | --- | +| `session_name` | empty — PHP keeps its own default | +| `session_cookie_path` | `MODX_BASE_URL`, with `base_url` as the fallback | +| `session_cookie_domain` | empty | +| `session_cookie_secure` | `false` | +| `session_cookie_httponly` | `true` | +| `session_cookie_samesite` | empty | +| `session_cookie_lifetime` | `0` | + +## Context Access -`Security/Permissions -> Edit desired User Group -> Permissions -> Context Access` +Access to a context is granted per user group on the **Contexts** tab of the access panel: the lock icon in the user menu → **Access Control Lists** → a user group → **Access Permissions** → **Contexts**. The tab lists the contexts and the policy the group holds on each of them. -## Retrieving Context Settings +A policy on a context decides which of the five access areas applies: Context, Resource Group, Element Category, Media Source and Namespace. A policy without an area covers the context itself. - Retrieving a Context Setting is no different than retrieving any other System Setting -- in fact, you may not be aware that a given setting is being set at the System or Context (or at the User) level. +## Reading Context Settings - In a template or Chunk: +A setting of the current context is read like any other setting — the level it comes from is not visible to the reader: ``` php [[++my_context_setting]] ``` - Programmatically in a Snippet: - ``` php $setting = $modx->getOption('my_context_setting'); ``` +The setting of a specific context is read from the context itself: + +``` php +$setting = $modx->context->getOption('my_context_setting'); +$setting = $modx->getContext('web')->getOption('my_context_setting'); +``` + +The language of a request is taken from the first source that has a value: the `cultureKey` parameter of the request, the `cultureKey` of the session, the `cultureKey` of the context, and finally the `cultureKey` System setting. The code accepts only the characters `A-Z`, `a-z`, `0-9`, `_` and `-` in it. + +## Choosing a Context at Runtime + +A request starts in the context named by the gateway. Two mechanisms change that: + +- the gateway file `config.context.php` next to `index.php` — the file returns the key of the context to start in. See [Serving a Second Domain](building-sites/contexts/virtual-host); +- a Plugin on the `OnHandleRequest` event that calls `switchContext()`. See [Using a Gateway Plugin](building-sites/contexts/gateway-plugin). + +The method that switches the context at runtime: + +``` php +if ($modx->switchContext('domain2')) { + // the request continues in the context "domain2" +} +``` + +`switchContext($contextKey, $reload = false)` returns `false` when the context was not loaded, so the result has to be checked. Switching the context does **not** load a custom session handler — the handler is set by the gateway. A context with its own session handler needs a gateway of its own. + +## Events + +| Event | When it fires | +| --- | --- | +| `OnContextInit` | a context is loaded: on every request and on every `switchContext()` | +| `OnContextBeforeSave` | before a context is saved | +| `OnContextSave` | after a context is saved | +| `OnContextUpdate` | a context is updated in the manager | +| `OnContextBeforeRemove` | before a context is removed | +| `OnContextRemove` | after a context is removed | +| `OnContextFormPrerender` | before the form of a context is rendered | +| `OnContextFormRender` | after the form of a context is rendered | + +The events of MODX 2 that are often named in older material — `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` and `OnBeforeRequest` — do not exist in MODX 3. + +## System Settings + +| Setting | Value by default | What it does | +| --- | --- | --- | +| `default_context` | `web` | the context new resources are created in | +| `access_context_enabled` | `true` | checks the access to a context on every request; switching it off ignores every context access rule | +| `allow_forward_across_contexts` | `false` | lets a symlink and `sendForward()` reach a resource in another context | +| `cache_context_settings` | `true` | caches the settings of the contexts | +| `use_context_resource_table` | `true` | keeps the table of resources that belong to several contexts | +| `context_tree_sort` | `true` | sorts the contexts in the resource tree by name | +| `context_tree_sortby` | `rank` | the field the contexts of the tree are sorted by | +| `context_tree_sortdir` | `ASC` | the direction of the sorting | + +## Processors + +The processors of the contexts and the permission each of them needs: + +| Processor | Permission | +| --- | --- | +| `Context/Create` | `new_context` | +| `Context/Duplicate` | `new_context` | +| `Context/Get` | `view_context` | +| `Context/GetList` | `view_context` | +| `Context/Update` | `edit_context` | +| `Context/UpdateFromGrid` | `edit_context` | +| `Context/Remove` | `delete_context` | +| `Context/Setting/Create` | `settings` | +| `Context/Setting/Get` | `settings` | +| `Context/Setting/GetList` | `settings` | +| `Context/Setting/Remove` | `settings` | +| `Context/Setting/Update` | the `save` policy of the context | + +`Context/Duplicate` copies the settings, the access rules and the media sources of the context, and — with `duplicateResources=1` — its resources as well. + +## Media Sources of a Context + +The media source of an element can be set for a single context. The element then uses the source of its own context, and falls back to the default source of the element when the context has none. + +## One Resource in Several Contexts + +A resource normally belongs to one context. With `use_context_resource_table` enabled, the table `context_resource` holds the resources that belong to several of them, and such a resource is found in each of the listed contexts. + ## See Also -1. [Creating a Subdomain from a Folder using Virtual Hosts](building-sites/contexts/virtual-host) -2. [Using One Gateway Plugin to Manage Multiple Domains](building-sites/contexts/gateway-plugin) \ No newline at end of file +1. [Serving a Second Domain](building-sites/contexts/virtual-host) +2. [Using a Gateway Plugin](building-sites/contexts/gateway-plugin) +3. [System Settings](building-sites/settings) +4. [Access Control Lists](building-sites/client-proofing/security/policies/acls) diff --git a/en/building-sites/contexts/gateway-plugin.md b/en/building-sites/contexts/gateway-plugin.md index 672be346a..19c33d626 100644 --- a/en/building-sites/contexts/gateway-plugin.md +++ b/en/building-sites/contexts/gateway-plugin.md @@ -1,48 +1,59 @@ --- -title: "Using a GatewayManager Plugin" -_old_id: "333" -_old_uri: "2.x/administering-your-site/contexts/using-one-gateway-plugin-to-manage-multiple-domains" +title: "Using a Gateway Plugin" +description: "Serving several domains from one MODX installation: switching the context by host with a Plugin on OnHandleRequest, or with a gateway of its own." --- -You have a choice when sharing a single database and manager across multiple domains. You can choose to use the primary front-end context (known as 'web') to handle all domains or you can create a unique gateway file for each domain to directly initialize a specific context. If you use a single gateway, you would use a plugin to switch contexts registered to the `OnHandleRequest` event, something like so: +One installation can serve several domains. The context of the request is what tells them apart, and two mechanisms choose it: a Plugin that switches the context, or a gateway file that starts in it. + +## Switching the Context by Host + +The event `OnHandleRequest` fires at the start of every request — in the front end and in the manager alike. A Plugin on it reads the host and switches the context: ``` php context->get('key') == 'mgr') { - return; +if ($modx->context->get('key') === 'mgr') { + return; } -switch ($_SERVER['HTTP_HOST']) { - case 'domain2.tld': - // if the http_host is of a specific domain, switch the context - $modx->switchContext('domain2.tld'); - break; - case 'domain3.tld': - // if the http_host is of a specific domain, switch the context - $modx->switchContext('domain3.tld'); - break; - default: - // by default, don't do anything - break; +$hosts = [ + 'domain2.tld' => 'domain2', + 'domain3.tld' => 'domain3', +]; + +$host = $_SERVER['HTTP_HOST'] ?? ''; +if (isset($hosts[$host])) { + $modx->switchContext($hosts[$host]); } -?> ``` -Alternatively, you would simply copy the index.php file from the default web context (along with the core.config.php and .htaccess for rewrite rules altered appropriately) to another directory and change the line +The plugin returns nothing in the manager, because the manager must stay in the `mgr` context. + +`switchContext($contextKey, $reload = false)` returns `false` when the context was not loaded. The result is worth checking before the rest of the request relies on the new context: ``` php -$modx->initialize('web'); +if (!$modx->switchContext('domain2')) { + $modx->log(modX::LOG_LEVEL_ERROR, 'The context "domain2" was not found.'); +} ``` -to +## A Gateway of Its Own + +The second mechanism does not need a Plugin. The file `index.php` reads the context from `config.context.php` next to it: ``` php -$modx->initialize('aContextNameOfYourChoice'); + Contexts. Click _Create New_ to create a new context. Give it a name of "dev" and click _Save_. +## Creating the Context -Next, in the Resource Tree (to the left) create a "Dev Home" Resource. Place it in the root of the "dev" context. Also, while you're at it, create a "Dev Docs" Resource as well with an alias of "documentation". We'll use this to test our context links. +Create the context in the manager: **Admin** → **Contexts** → **Create**. The **Context Key** is `dev` — the key is what the gateway names — and the name is free. The keys `mgr`, `web` and `root` are reserved by the core. -Your tree should look something like this: +Then create the resources of the domain in the branch of the context in the resource tree. The tree looks like this: ![](subctx1.png) -From there, go ahead and right-click on the "dev" Context in the tree, and click "Edit Context". From here we'll see a Context Settings tab. Click on it, and you'll need to add a few settings: +## The Settings of the Context -- **base\_url** - Set this to "**/**" (no quotes) since we're making the root of the URL our base. -- **http\_host** - Set this to **dev.modxcms.com** (or your subdomain name) -- **site\_start** - Set this to the **ID of your "Dev Home" resource**. -- **site\_url** - Set this to **** (or your subdomain url). Don't forget the **_trailing slash_**. Remember this setting is: **scheme + _http\_host_ + base\_url** +Four settings on the **Context Settings** tab of the context decide how the URLs of the domain are built: -You can add other context-specific settings, such as error\_page, unauthorized\_page, cultureKey, and others if you so choose. All system settings can be overridden by setting them on a context. +| Setting | Value | +| --- | --- | +| `base_url` | `/` | +| `http_host` | `dev.example.com` | +| `site_start` | the ID of the resource that opens the domain | +| `site_url` | `http://dev.example.com/` — the scheme, the host and the path, with a trailing slash | -**Note: LINKING BETWEEN CONTEXTS** -If you're going to be **linking back to the 'web' context from this context ('dev')**, you'll want to **add those same Context Settings (with 'web'-specific values, of course) to the 'web' context**. This allows MODX to know where to redirect 'web' context URLs back to. +Any other setting can be overridden here as well — `cultureKey` for the language of the domain, for example. Changing a setting clears the cache of the context, so a manual cache clear is not needed. -After creating the settings, clear your site cache. +## The Gateway Directory -## Creating the Virtual Host +The gateway is a directory of its own with four files: -**cPanel Users** -cPanel will make the necessary changes automatically when you create a new sub domain. Manually editing the Virtual Hosts is not recommended. +| File | What it holds | +| --- | --- | +| `index.php` | a copy of the `index.php` of the installation | +| `config.core.php` | a copy of the `config.core.php` of the installation | +| `.htaccess` | a copy of the `.htaccess` of the installation | +| `config.context.php` | the key of the context | -Now we need to do some Apache work. (If you're not using Apache, you can at least follow the same idea and customize it to your server.) Go to Apache's httpd.conf file, and add these lines, changing where necessary for your domain name: +`config.context.php` holds one line: ``` php -NameVirtualHost dev.modxcms.com - - ServerAdmin dev@modxcms.com - DocumentRoot /home/modxcms.com/public_html/dev - ServerName dev.modxcms.com - ErrorLog logs/devmodxcms-error_log - TransferLog logs/devmodxcms-access_log - +initialize('web'); +``` apache + + ServerName dev.example.com + DocumentRoot /home/example.com/public_html/dev + ErrorLog logs/dev-error_log + CustomLog logs/dev-access_log + ``` -Change 'web' to 'dev'. Save the file and close. +Restart the web server and open `http://dev.example.com/` — the resource named by `site_start` answers. -#### .htaccess +## Links Between the Contexts -You'll only need to edit one line here (and maybe not at all). Find this line (near the top): +A link to a resource of another context names that context: -``` php -RewriteBase / +``` +[[~135:context=`web`]] ``` -Make sure that's set to /, not anything else. It should match the **base\_url** context setting you set up earlier. - -#### config.core.php - -What is really important here is to make sure this line points to your MODX core folder: +The URL is absolute, because the resource lives in another context. A link without a context stays in the context of the request and is relative: -``` php - define('MODX_CORE_PATH', dirname(__FILE__) . '/core/'); +``` +[[~135]] ``` -If the main domain is "up one level" on the filesystem, you should be able to use the following: +The same holds in PHP: ``` php - define('MODX_CORE_PATH', dirname(dirname(__FILE__)) . '/core/'); +$url = $modx->makeUrl(135, 'web'); ``` -## Final Steps - -Clear your site cache again, refresh the Resource tree, and click 'Preview' on your "Dev Home" document. You should now be showing the page at the following URL: - -> - -Create a `[[~135]]` link to the "Dev Docs" Resource in the "Dev Home" Resource. Reload your page. Note the link properly builds to: - -> - -And you're done! - ## See Also -- [Contexts](building-sites/contexts "Contexts") -- Contexts as subfolders (from the forums: ) +1. [Contexts](building-sites/contexts) +2. [Using a Gateway Plugin](building-sites/contexts/gateway-plugin) +3. [System Settings](building-sites/settings) diff --git a/es/building-sites/contexts.md b/es/building-sites/contexts.md index f42c44ea9..cffa33fdb 100644 --- a/es/building-sites/contexts.md +++ b/es/building-sites/contexts.md @@ -1,65 +1,166 @@ --- title: "Contextos" -_old_id: "66" -_old_uri: "2.x/administering-your-site/contexts" +description: "Contextos en MODX: cómo anulan los ajustes del sistema, cómo crear uno, cómo se concede el acceso y la API, los eventos y los procesadores que hay detrás." --- - Los contextos permiten que los ajustes de configuración de MODX se anulen, amplíen, aislen o se compartan entre dominios, subdominios, subsitios, sitios múltiples, secciones culturales específicas, aplicaciones web específicas, etc. +Un Contexto es un conjunto con nombre de anulaciones de configuración sobre el que se ejecuta una petición: lleva sus propios ajustes, su propia rama del árbol de recursos y sus propias reglas de acceso. - Puedes crear fácilmente un contexto desde la entrada Contextos en el manú Sistema. El contexto se mostrará en tu árbol de recursos. Los recursos se pueden arrastrar fácilmente entre contextos para moverlos de un contexto a otro. - - Nota: no hay nada fundamentalmente _diferente_ acerca de los recursos en diferentes contextos, excepto que ahora heredan las configuraciones del contexto en el que se encuentran. Por tanto, si creas un nuevo contexto, tendrás que editar la configuración del mismo para que aparezca algún cambio real distinguible. +MODX incluye dos contextos: `web` (Website) para el front end y `mgr` (Manager) para el gestor. Un contexto se direcciona por su **clave**; esa clave es la que se pasa a `initialize()` y a `switchContext()`. El **nombre** es solo una etiqueta para la interfaz. ## Creando un contexto - Primero, vete a la página Contextos, a través de Sistema(_*icono de rueda dentada en el menú superior_) -> Contextos. Luego, haz clic en el botón "Crear Nuevo" (_encima de la cuadrícula_). - - ![](contextos.png) - - Esto te pedirá una clave, un nombre y una descripción, y un numero de posición (en base al cuál se ordenarán los contextos en el árbol de la parte izquierda del Manager). - - ![](contexto-2.png) - - Una vez creado, haz clic con el botón derecho sobre el contexto recién aparecido en la cuadrícula, y haz clic en "Actualizar Contexto". - +Los contextos se gestionan en el gestor: **Admin** (el engranaje del menú superior) → **Contexts** (`?a=context`). El botón **Create** abre un formulario con cuatro campos: - Esto te llevará a una página con 3 pestañas que muestran el contexto, una cuadrícula de configuraciones vacía y una cuadrícula con los permisos de acceso al mismo. Desde aquí puedes agregar configuraciones específicas del contexto que reasignará cualquier configuración del sistema. Tu nuevo contexto estará completamente vacío, lo que requiere que incluyas todas y cada una de las configuraciones que necesites que utilice (por ej. site_start = Id de la página de inicio de tu nuevo contexto). +| Campo | Obligatorio | Significado | +| --- | --- | --- | +| `key` | sí | el identificador del contexto; el valor que se usa en `initialize()` y en `switchContext()` | +| `name` | sí | la etiqueta que se muestra en el gestor y en el árbol de recursos | +| `description` | no | texto libre | +| `rank` | no | el orden del contexto en el árbol | - Ten en cuenta que los nuevos contextos no obtienen automáticamente permisos de "carga" para usuarios anónimos en 2.2+; deberás concederlos manualmente. +Las claves `mgr`, `web` y `root` están reservadas por el núcleo. -Cuando creas un nuevo contexto además del contexto "web" predeterminado, es posible que también debas aplicar la configuración de contexto al contexto web. +Un contexto nuevo recibe acceso de inmediato: el grupo de usuarios **Administrator** recibe la política *Context* y el usuario anónimo recibe la política *Load Only*, el derecho `load` y nada más. El acceso anónimo se omite cuando la petición al procesador lleva `enableAnonymous=0`. -## Configuraciones de contexto +Los contextos aparecen en el árbol de recursos como una rama propia, y los recursos se mueven entre contextos arrastrándolos. - Puedes crear configuraciones para cualquier contexto definido haciendo clic en ** Sistema -> Contextos**. Luego haz clic con el botón derecho en cualquier contexto y selecciona "Actualizar Contexto". +## Ajustes de contexto - Cada contexto puede tener su propia configuración que anula o extiende las [Configuraciones de Sistema](/current/en/building-sites/settings "Configuraciones de Sistema"). Las configuraciones de contexto, a su vez pueden ser anuladadas o extendidas por las [Configuraciones de Usuario](/current/en/building-sites/client-proofing/security/users#Users-UsersUserSettings). La jerarquía a recordar es esta: +Los ajustes de un contexto anulan los [Ajustes del Sistema](/current/en/building-sites/settings) del mismo nombre, y los ajustes de un usuario anulan los del contexto. El orden es: - Configuración del sistema -> Configuración del contexto -> Configuración del usuario +``` +Ajuste del sistema → Ajuste del contexto → Ajuste del usuario +``` -## Acceso al contexto +Un ajuste de contexto se edita en la pestaña **Context Settings** de la página del contexto: **Contexts** → clic derecho en un contexto → **Edit**. Cambiar un ajuste borra la caché de ese contexto, así que no hace falta limpiar la caché a mano. + +Los ajustes que un contexto suele anular: -Al crear un nuevo contexto, asegúrate de que los grupos de usuarios que quieras tengan acceso a él: +| Ajuste | Qué cambia | +| --- | --- | +| `base_url` | la parte de ruta de las URL del contexto | +| `http_host` | el host para el que se construyen las URL | +| `site_url` | la URL completa del contexto: esquema, host y ruta | +| `site_start` | el recurso que abre el contexto | +| `cultureKey`, `locale` | el idioma y la configuración regional de la petición | +| `session_name`, `session_cookie_path`, `session_cookie_domain` | la cookie de sesión del contexto | + +Los ajustes de sesión de un contexto conservan los valores del núcleo salvo que se anulen: + +| Ajuste | Valor por defecto | +| --- | --- | +| `session_name` | vacío — PHP conserva el suyo | +| `session_cookie_path` | `MODX_BASE_URL`, con `base_url` como alternativa | +| `session_cookie_domain` | vacío | +| `session_cookie_secure` | `false` | +| `session_cookie_httponly` | `true` | +| `session_cookie_samesite` | vacío | +| `session_cookie_lifetime` | `0` | + +## Acceso al contexto -`Sistema -> Listas de Control de Acceso -> Actualizar Grupo de Usuarios deseado -> Permisos -> Acceso a Contextos` +El acceso a un contexto se concede por grupo de usuarios en la pestaña **Contexts** del panel de acceso: el icono del candado en el menú de usuario → **Access Control Lists** → un grupo de usuarios → **Access Permissions** → **Contexts**. La pestaña enumera los contextos y la política que cada grupo tiene sobre ellos. -## Recuperando configuraciones de contexto +Una política sobre un contexto decide cuál de las cinco áreas de acceso se aplica: Context, Resource Group, Element Category, Media Source y Namespace. Una política sin área cubre el contexto mismo. - Recuperar una configuración de contexto no es diferente a recuperar cualquier otra configuración del sistema; de hecho, es posible que no te dés cuenta de que se está obteniendo una configuración determinada en el nivel de sistema o de contexto (o en el de usuario). +## Leyendo ajustes de contexto - En una plantilla o Chunk: +Un ajuste del contexto actual se lee como cualquier otro ajuste; el nivel del que procede no es visible para quien lee: ``` php [[++my_context_setting]] ``` - Programáticamente en un Snippet: - ``` php $setting = $modx->getOption('my_context_setting'); ``` +El ajuste de un contexto concreto se lee del propio contexto: + +``` php +$setting = $modx->context->getOption('my_context_setting'); +$setting = $modx->getContext('web')->getOption('my_context_setting'); +``` + +El idioma de una petición se toma de la primera fuente que tenga valor: el parámetro `cultureKey` de la petición, el `cultureKey` de la sesión, el `cultureKey` del contexto y, por último, el ajuste del sistema `cultureKey`. El código solo admite en él los caracteres `A-Z`, `a-z`, `0-9`, `_` y `-`. + +## Elegir un contexto durante la petición + +Una petición empieza en el contexto que indique la puerta de entrada. Dos mecanismos lo cambian: + +- el archivo `config.context.php` junto a `index.php` — el archivo devuelve la clave del contexto en el que empieza la petición. Ver [Servir un segundo dominio](/current/en/building-sites/contexts/virtual-host); +- un Plugin en el evento `OnHandleRequest` que llame a `switchContext()`. Ver [Uso de un Plugin de puerta](/current/en/building-sites/contexts/gateway-plugin). + +El método que cambia el contexto durante la ejecución: + +``` php +if ($modx->switchContext('domain2')) { + // la petición continúa en el contexto "domain2" +} +``` + +`switchContext($contextKey, $reload = false)` devuelve `false` cuando el contexto no se cargó, así que conviene comprobar el resultado. Cambiar el contexto **no** carga un manejador de sesión propio: lo define la puerta de entrada. Un contexto con su propio manejador de sesión necesita su propia puerta de entrada. + +## Eventos + +| Evento | Cuándo se dispara | +| --- | --- | +| `OnContextInit` | se carga un contexto: en cada petición y en cada `switchContext()` | +| `OnContextBeforeSave` | antes de guardar un contexto | +| `OnContextSave` | después de guardar un contexto | +| `OnContextUpdate` | se actualiza un contexto en el gestor | +| `OnContextBeforeRemove` | antes de eliminar un contexto | +| `OnContextRemove` | después de eliminar un contexto | +| `OnContextFormPrerender` | antes de dibujar el formulario de un contexto | +| `OnContextFormRender` | después de dibujar el formulario de un contexto | + +Los eventos de MODX 2 que se citan a menudo en material antiguo — `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` y `OnBeforeRequest` — no existen en MODX 3. + +## Ajustes del sistema + +| Ajuste | Valor por defecto | Qué hace | +| --- | --- | --- | +| `default_context` | `web` | el contexto en el que se crean los recursos nuevos | +| `access_context_enabled` | `true` | comprueba el acceso a un contexto en cada petición; desactivarlo ignora todas las reglas de acceso a contextos | +| `allow_forward_across_contexts` | `false` | permite que un enlace simbólico y `sendForward()` lleguen a un recurso de otro contexto | +| `cache_context_settings` | `true` | cachea los ajustes de los contextos | +| `use_context_resource_table` | `true` | mantiene la tabla de recursos que pertenecen a varios contextos | +| `context_tree_sort` | `true` | ordena los contextos del árbol de recursos por nombre | +| `context_tree_sortby` | `rank` | el campo por el que se ordenan los contextos del árbol | +| `context_tree_sortdir` | `ASC` | la dirección de la ordenación | + +## Procesadores + +Los procesadores de los contextos y el permiso que necesita cada uno: + +| Procesador | Permiso | +| --- | --- | +| `Context/Create` | `new_context` | +| `Context/Duplicate` | `new_context` | +| `Context/Get` | `view_context` | +| `Context/GetList` | `view_context` | +| `Context/Update` | `edit_context` | +| `Context/UpdateFromGrid` | `edit_context` | +| `Context/Remove` | `delete_context` | +| `Context/Setting/Create` | `settings` | +| `Context/Setting/Get` | `settings` | +| `Context/Setting/GetList` | `settings` | +| `Context/Setting/Remove` | `settings` | +| `Context/Setting/Update` | la política `save` del contexto | + +`Context/Duplicate` copia los ajustes, las reglas de acceso y las fuentes de medios del contexto, y — con `duplicateResources=1` — también sus recursos. + +## Fuentes de medios de un contexto + +La fuente de medios de un elemento se puede fijar para un contexto concreto. El elemento usa entonces la fuente de su propio contexto y, si el contexto no tiene ninguna, vuelve a la fuente por defecto del elemento. + +## Un recurso en varios contextos + +Un recurso pertenece normalmente a un contexto. Con `use_context_resource_table` activada, la tabla `context_resource` guarda los recursos que pertenecen a varios de ellos, y cada recurso así se encuentra en todos los contextos listados. + ## Ver también -1. [Crear un subdominio desde una carpeta usando hosts virtuales](/current/en/building-sites/contexts/virtual-host) -2. [Uso de un Plugin de puertas para administrar múltiples dominios](/current/en/building-sites/contexts/gateway-plugin) +1. [Servir un segundo dominio](/current/en/building-sites/contexts/virtual-host) +2. [Uso de un Plugin de puerta](/current/en/building-sites/contexts/gateway-plugin) +3. [Ajustes del Sistema](/current/en/building-sites/settings) +4. [Listas de Control de Acceso](/current/en/building-sites/client-proofing/security/policies/acls) diff --git a/ru/building-sites/contexts.md b/ru/building-sites/contexts.md index 439ee551c..f1c7dac0e 100644 --- a/ru/building-sites/contexts.md +++ b/ru/building-sites/contexts.md @@ -1,55 +1,167 @@ --- title: "Контексты" translation: "building-sites/contexts" +description: "Контексты в MODX: как они переопределяют системные настройки, как создать контекст, как выдаётся доступ к нему, а также API, события и процессоры контекстов." --- -Контексты позволяют переопределять, расширять, изолировать или совместно использовать настройки MODX между доменами, поддоменами, мультисайтами, языковыми версиями, специфическими веб-приложениями и т.п. +Контекст — это именованный набор переопределений конфигурации, в котором выполняется запрос: у него свои настройки, своя ветка дерева ресурсов и свои правила доступа. -Вы можете легко создать контекст через меню "Контексты". Контекст появится в вашем дереве ресурсов. Ресурсы можно легко перемещать из одного контекста в другой перетаскиванием. - -Примечание: нет принципиальных _различий_ в ресурсах, расположенных в разных контекстах, кроме того, что они теперь наследуют настройки контекста, в котором они находятся. Поэтому, если вы создаете новый контекст, вам придется переопределить настройки контекста, чтобы изменения применились. +В MODX поставляется два контекста — `web` (Website) для фронтенда и `mgr` (Manager) для менеджера. Контекст адресуется **ключом**; именно этот ключ передаётся в `initialize()` и `switchContext()`. **Имя** — только подпись в интерфейсе. ## Создание контекста -Сначала перейдите на страницу "Контексты" через "Система" -> "Контексты". Затем нажмите "Создать новый". Форма попросит ввести ключ и описание. Далее нажмите правой кнопкой мыши по созданному контексту и выберите "Обновить контекст". +Контексты управляются в менеджере: **Admin** (шестерёнка в верхнем меню) → **Contexts** (`?a=context`). Кнопка **Create** открывает форму с четырьмя полями: + +| Поле | Обязательное | Значение | +| --- | --- | --- | +| `key` | да | идентификатор контекста; значение, которое используется в `initialize()` и `switchContext()` | +| `name` | да | подпись, которая показывается в менеджере и в дереве ресурсов | +| `description` | нет | свободный текст | +| `rank` | нет | порядок контекста в дереве | -Вы перейдете в окно контекста с пустым списком настроек. Отсюда вы можете добавить контекстно-зависимые настройки, которые будут переопределять любые настройки системы. Ваш новый контекст будет полностью пустым, и вам потребуется указать все настройки, которые вы будете использовать. +Ключи `mgr`, `web` и `root` зарезервированы ядром. -Обратите внимание, что новые контексты не получают автоматически разрешение "load" для анонимных пользователей в версии 2.2+ - вам нужно добавить это вручную. +Новый контекст сразу получает доступ: группа пользователей **Administrator** — политику *Context*, анонимный пользователь — политику *Load Only*, то есть право `load` и больше ничего. Анонимный доступ пропускается, если в запрос к процессору передан `enableAnonymous=0`. -Когда вы создаете новый контекст, помимо стандартного контекста "web", вам может потребоваться применить настройки и к контексту "web". +Контексты появляются в дереве ресурсов отдельной веткой, а ресурсы переносятся между контекстами перетаскиванием. ## Настройки контекста -Вы можете создать настройки для любого определенного контекста, нажав **Система -> Контексты**, затем нажмите правой кнопкой мыши любой контекст и выберите "Обновить контекст". +Настройки контекста переопределяют [системные настройки](building-sites/settings) с тем же именем, а настройки пользователя переопределяют настройки контекста. Порядок такой: -Каждый контекст может иметь свои собственные настройки, которые переопределяют или расширяют [Системные настройки](building-sites/settings "Системные настройки"). Настройки контекста, в свою очередь, могут быть переопределены или расширены с помощью [Настройки пользователя](administering-your-site/security/users#Users-UsersUserSettings). Иерархия такова: +``` +Системная настройка → Настройка контекста → Настройка пользователя +``` -Системные настройки -> Настройка контекста -> Настройка пользователя +Настройка контекста правится на вкладке **Context Settings** страницы контекста: **Contexts** → правый клик по контексту → **Edit**. Смена настройки сбрасывает кэш этого контекста, поэтому очищать кэш вручную не нужно. -## Доступ к контексту +Настройки, которые контекст обычно переопределяет: -При создании нового контекста убедитесь, что нужные группы пользователей имеют к нему доступ: +| Настройка | Что меняет | +| --- | --- | +| `base_url` | часть пути в URL контекста | +| `http_host` | хост, под который собираются URL | +| `site_url` | полный URL контекста: схема, хост и путь | +| `site_start` | ресурс, который открывается в контексте | +| `cultureKey`, `locale` | язык и локаль запроса | +| `session_name`, `session_cookie_path`, `session_cookie_domain` | cookie сессии контекста | + +Настройки сессии в контексте сохраняют значения ядра, если их не переопределили: + +| Настройка | Значение по умолчанию | +| --- | --- | +| `session_name` | пусто — PHP оставляет своё значение | +| `session_cookie_path` | `MODX_BASE_URL`, с запасным вариантом `base_url` | +| `session_cookie_domain` | пусто | +| `session_cookie_secure` | `false` | +| `session_cookie_httponly` | `true` | +| `session_cookie_samesite` | пусто | +| `session_cookie_lifetime` | `0` | + +## Доступ к контексту -`Контроль доступа -> Изменить нужную группу пользователей -> Права доступа -> Доступ к контексту` +Доступ к контексту выдаётся группам пользователей на вкладке **Contexts** панели доступа: иконка замка в меню пользователя → **Access Control Lists** → группа пользователей → **Access Permissions** → **Contexts**. На вкладке перечислены контексты и политика, которая у группы есть на каждом из них. -## Получение настроек контекста +Политика на контексте определяет, какая из пяти областей доступа действует: Context, Resource Group, Element Category, Media Source и Namespace. Политика без области покрывает сам контекст. -Получение настройки контекста ничем не отличается от получения любой другой настройки системы. Фактически, вы можете не знать, что данный параметр устанавливается на уровне системы или контекста (или на уровне пользователя). +## Чтение настроек контекста -В шаблоне или чанке: +Настройку текущего контекста читают как любую другую настройку — уровень, с которого она пришла, читателю не виден: ``` php [[++my_context_setting]] ``` -Программно в сниппете: - ``` php $setting = $modx->getOption('my_context_setting'); ``` +Настройку конкретного контекста читают у самого контекста: + +``` php +$setting = $modx->context->getOption('my_context_setting'); +$setting = $modx->getContext('web')->getOption('my_context_setting'); +``` + +Язык запроса берётся из первого источника, где есть значение: параметр `cultureKey` запроса, `cultureKey` сессии, `cultureKey` контекста и, наконец, системная настройка `cultureKey`. Код допускает в нём только символы `A-Z`, `a-z`, `0-9`, `_` и `-`. + +## Выбор контекста во время запроса + +Запрос начинается в контексте, который называет гейтвей. Сменить контекст могут два механизма: + +- файл гейтвея `config.context.php` рядом с `index.php` — файл возвращает ключ контекста, в котором начинается запрос. См. [Второй домен](building-sites/contexts/virtual-host); +- плагин на событие `OnHandleRequest`, который вызывает `switchContext()`. См. [Плагин шлюза](building-sites/contexts/gateway-plugin). + +Метод, который переключает контекст во время выполнения: + +``` php +if ($modx->switchContext('domain2')) { + // запрос продолжается в контексте "domain2" +} +``` + +`switchContext($contextKey, $reload = false)` возвращает `false`, когда контекст не загрузился, поэтому результат стоит проверять. Переключение контекста **не** подгружает свой session handler — его задаёт гейтвей. Контексту с собственным session handler нужен отдельный гейтвей. + +## События + +| Событие | Когда вызывается | +| --- | --- | +| `OnContextInit` | контекст загружен: на каждом запросе и при каждом `switchContext()` | +| `OnContextBeforeSave` | перед сохранением контекста | +| `OnContextSave` | после сохранения контекста | +| `OnContextUpdate` | контекст обновлён в менеджере | +| `OnContextBeforeRemove` | перед удалением контекста | +| `OnContextRemove` | после удаления контекста | +| `OnContextFormPrerender` | до отрисовки формы контекста | +| `OnContextFormRender` | после отрисовки формы контекста | + +События MODX 2, которые часто встречаются в старых материалах — `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` и `OnBeforeRequest` — в MODX 3 не существуют. + +## Системные настройки + +| Настройка | Значение по умолчанию | Что делает | +| --- | --- | --- | +| `default_context` | `web` | контекст, в котором создаются новые ресурсы | +| `access_context_enabled` | `true` | проверяет доступ к контексту на каждом запросе; отключение игнорирует все правила доступа к контекстам | +| `allow_forward_across_contexts` | `false` | разрешает символьной ссылке и `sendForward()` доходить до ресурса в другом контексте | +| `cache_context_settings` | `true` | кэширует настройки контекстов | +| `use_context_resource_table` | `true` | ведёт таблицу ресурсов, принадлежащих нескольким контекстам | +| `context_tree_sort` | `true` | сортирует контексты в дереве ресурсов по названию | +| `context_tree_sortby` | `rank` | поле, по которому сортируются контексты дерева | +| `context_tree_sortdir` | `ASC` | направление сортировки | + +## Процессоры + +Процессоры контекстов и требуемое право для каждого из них: + +| Процессор | Право | +| --- | --- | +| `Context/Create` | `new_context` | +| `Context/Duplicate` | `new_context` | +| `Context/Get` | `view_context` | +| `Context/GetList` | `view_context` | +| `Context/Update` | `edit_context` | +| `Context/UpdateFromGrid` | `edit_context` | +| `Context/Remove` | `delete_context` | +| `Context/Setting/Create` | `settings` | +| `Context/Setting/Get` | `settings` | +| `Context/Setting/GetList` | `settings` | +| `Context/Setting/Remove` | `settings` | +| `Context/Setting/Update` | политика `save` контекста | + +`Context/Duplicate` копирует настройки, правила доступа и источники медиа контекста, а с `duplicateResources=1` — ещё и его ресурсы. + +## Источники медиа контекста + +Источник медиа элемента можно задать для отдельного контекста. Тогда элемент берёт источник своего контекста, а если у контекста источника нет — источник элемента по умолчанию. + +## Один ресурс в нескольких контекстах + +Обычно ресурс принадлежит одному контексту. Когда включена настройка `use_context_resource_table`, таблица `context_resource` хранит ресурсы, принадлежащие нескольким контекстам, и такой ресурс находится в каждом из указанных. + ## Смотрите также -1. [Создание поддомена из папки с использованием виртуальных хостов](building-sites/contexts/virtual-host) -2. [Использование одного шлюза для управления несколькими доменами](building-sites/contexts/gateway-plugin) +1. [Второй домен](building-sites/contexts/virtual-host) +2. [Плагин шлюза](building-sites/contexts/gateway-plugin) +3. [Системные настройки](building-sites/settings) +4. [ACL](building-sites/client-proofing/security/policies/acls) diff --git a/ru/building-sites/contexts/gateway-plugin.md b/ru/building-sites/contexts/gateway-plugin.md index 66e62c8a9..27f3f0dee 100644 --- a/ru/building-sites/contexts/gateway-plugin.md +++ b/ru/building-sites/contexts/gateway-plugin.md @@ -1,47 +1,60 @@ --- -title: "Использование плагина GatewayManager" +title: "Использование плагина шлюза" translation: "building-sites/contexts/gateway-plugin" +description: "Несколько доменов с одной установки MODX: переключение контекста по хосту плагином на OnHandleRequest или отдельным гейтвеем." --- -У вас есть выбор при совместном использовании одной базы данных и менеджера в нескольких доменах. Вы можете использовать первичный интерфейсный интерфейс (известный как «web») для обработки всех доменов, или вы можете создать уникальный файл шлюза для каждого домена, чтобы напрямую инициализировать определенный контекст. Если вы используете один шлюз, вы бы использовали плагин для переключения контекстов, зарегистрированных в событии `OnHandleRequest`, что-то вроде этого: +Одна установка может обслуживать несколько доменов. Различает их контекст запроса, и выбирают его два механизма: плагин, который переключает контекст, или гейтвей, который начинает в нём работу. + +## Переключение контекста по хосту + +Событие `OnHandleRequest` вызывается в начале каждого запроса — и на фронтенде, и в менеджере. Плагин на него читает хост и переключает контекст: ``` php context->get('key') == 'mgr') { - return; +if ($modx->context->get('key') === 'mgr') { + return; } -switch ($_SERVER['HTTP_HOST']) { - case 'domain2.tld': - // если http_host принадлежит конкретному домену, переключить контекст - $modx->switchContext('domain2.tld'); - break; - case 'domain3.tld': - // если http_host принадлежит конкретному домену, переключить контекст - $modx->switchContext('domain3.tld'); - break; - default: - // по умолчанию ничего не делать - break; +$hosts = [ + 'domain2.tld' => 'domain2', + 'domain3.tld' => 'domain3', +]; + +$host = $_SERVER['HTTP_HOST'] ?? ''; +if (isset($hosts[$host])) { + $modx->switchContext($hosts[$host]); } -?> ``` -В качестве альтернативы, вы просто скопируете файл index.php из веб-контекста по умолчанию (вместе с core.config.php и .htaccess для правил перезаписи, измененных соответствующим образом) в другой каталог и измените строку +Плагин ничего не возвращает в менеджере, потому что менеджер должен остаться в контексте `mgr`. + +`switchContext($contextKey, $reload = false)` возвращает `false`, когда контекст не загрузился. Результат стоит проверять, прежде чем дальнейшая работа запроса будет опираться на новый контекст: ``` php -$modx->initialize('web'); +if (!$modx->switchContext('domain2')) { + $modx->log(modX::LOG_LEVEL_ERROR, 'The context "domain2" was not found.'); +} ``` -в +## Собственный гейтвей + +Второй механизм обходится без плагина. Файл `index.php` читает контекст из файла `config.context.php` рядом с ним: ``` php -$modx->initialize('aContextNameOfYourChoice'); + Контексты. Нажмите _Создать новый_, чтобы создать новый контекст. Дайте ему имя "dev" и нажмите _Сохранить_. +## Создание контекста -Затем в дереве ресурсов (слева) создайте ресурс "Dev Home". Поместите его в корень контекста «dev». Кроме того, пока вы это делаете, создайте ресурс "Dev Docs" с псевдонимом "документация". Мы будем использовать это для проверки наших контекстных ссылок. +Создайте контекст в менеджере: **Admin** → **Contexts** → **Create**. **Context Key** — это `dev`: именно ключ называет гейтвей, а имя свободное. Ключи `mgr`, `web` и `root` зарезервированы ядром. -Ваше дерево должно выглядеть примерно так: +Затем создайте ресурсы домена в ветке контекста в дереве ресурсов. Дерево выглядит так: ![](subctx1.png) -Оттуда идите вперед и щелкните правой кнопкой мыши на контексте «dev» в дереве и нажмите «Изменить контекст». Отсюда мы увидим вкладку Настройки контекста. Нажмите на нее, и вам нужно будет добавить несколько настроек: +## Настройки контекста -- **base\_url** - Установите это в "**/**" (без кавычек), так как мы указываем корень URL нашей базы. -- **http\_host** - Установите это в **dev.modxcms.com** (или ваше имя поддомена) -- **site\_start** - Установите это **Идентификатор вашего ресурса "Dev Home"**. -- **site\_url** - Установите это в **** (или ваш поддомен URL). Не забывайте **_косую черту_**. Помните, что этот параметр: **scheme + _http\_host_ + base\_url** +Четыре настройки на вкладке **Context Settings** контекста определяют, как собираются URL домена: -Вы можете добавить другие специфичные для контекста настройки, такие как error\_page, unauthorized\_page, cultureKey и другие, если вы того пожелаете. Все системные настройки могут быть переопределены путем установки их в контексте. +| Настройка | Значение | +| --- | --- | +| `base_url` | `/` | +| `http_host` | `dev.example.com` | +| `site_start` | ID ресурса, который открывает домен | +| `site_url` | `http://dev.example.com/` — схема, хост и путь, с косой чертой в конце | -**Примечание: СВЯЗЬ МЕЖДУ КОНТЕКСТАМИ** -Если вы собираетесь **ссылаться на контекст «web» из этого контекста («dev»)**, вам нужно **добавить те же самые настройки контекста (со значениями, специфичными для web), конечно) в контексте «сети»**. Это позволяет MODX знать, куда перенаправлять URL-адреса веб-контекста. +Любую другую настройку здесь тоже можно переопределить — например, `cultureKey` для языка домена. Смена настройки сбрасывает кэш контекста, поэтому очищать кэш вручную не нужно. -После создания настроек очистите кеш сайта. +## Каталог гейтвея -## Создание виртуального хоста +Гейтвей — это отдельный каталог с четырьмя файлами: -### Пользователи cPanel +| Файл | Что в нём | +| --- | --- | +| `index.php` | копия `index.php` установки | +| `config.core.php` | копия `config.core.php` установки | +| `.htaccess` | копия `.htaccess` установки | +| `config.context.php` | ключ контекста | -cPanel автоматически внесет необходимые изменения при создании нового субдомена. Редактирование виртуальных хостов вручную не рекомендуется. - -Теперь нам нужно немного поработать с Apache. (Если вы не используете Apache, вы можете, по крайней мере, следовать той же идее и настроить ее на своем сервере.) Перейдите в файл Apache httpd.conf и добавьте эти строки, меняя их, где необходимо, для вашего доменного имени: +В `config.context.php` одна строка: ``` php -NameVirtualHost dev.modxcms.com - - ServerAdmin dev@modxcms.com - DocumentRoot /home/modxcms.com/public_html/dev - ServerName dev.modxcms.com - ErrorLog logs/devmodxcms-error_log - TransferLog logs/devmodxcms-access_log - +initialize('web'); +``` apache + + ServerName dev.example.com + DocumentRoot /home/example.com/public_html/dev + ErrorLog logs/dev-error_log + CustomLog logs/dev-access_log + ``` -Измените «web» на «dev». Сохраните файл и закройте. +Перезапустите веб-сервер и откройте `http://dev.example.com/` — ответит ресурс, названный в `site_start`. -#### .htaccess +## Ссылки между контекстами -Вам нужно будет отредактировать только одну строку здесь (и, возможно, не совсем). Найдите эту строку (в начале): +Ссылка на ресурс другого контекста называет этот контекст: -``` php -RewriteBase / +``` +[[~135:context=`web`]] ``` -Убедитесь, что установлено значение /, а не что-либо еще. Он должен соответствовать настройке контекста **base\_url**, которую вы установили ранее. - -#### config.core.php - -Здесь действительно важно убедиться, что эта строка указывает на вашу основную папку MODX: +URL получается абсолютным, потому что ресурс лежит в другом контексте. Ссылка без контекста остаётся в контексте запроса и относительная: -``` php -define('MODX_CORE_PATH', dirname(__FILE__) . '/core/'); +``` +[[~135]] ``` -Если основной домен «на один уровень» выше в файловой системе, вы сможете использовать следующее: +То же и в PHP: ``` php -define('MODX_CORE_PATH', dirname(dirname(__FILE__)) . '/core/'); +$url = $modx->makeUrl(135, 'web'); ``` -## Заключительные шаги - -Снова очистите кэш сайта, обновите дерево ресурсов и нажмите «Предварительный просмотр» в своем документе «Dev Home». Теперь вы должны показывать страницу по следующему URL: - -> - -Создайте ссылку `[[~135]` на ресурс «Dev Docs» в ресурсе «Dev Home». Перезагрузите страницу. Обратите внимание, что ссылка правильно построена для: - -> - -И вы сделали это! - ## Смотрите также -- [Контексты](building-sites/contexts "Контексты") -- Контексты как подпапки (на форуме: ) +1. [Контексты](building-sites/contexts) +2. [Плагин шлюза](building-sites/contexts/gateway-plugin) +3. [Системные настройки](building-sites/settings) From 538f2d25a2d0aee8867b4060875e6713deae2d35 Mon Sep 17 00:00:00 2001 From: Ivan Bochkarev Date: Tue, 20 Oct 2026 22:54:41 +0600 Subject: [PATCH 2/6] docs(building-sites/contexts): editorial pass on the section Cut redundancy, lift the answers up, turn prose into lists and tables. - contexts.md: de-duplicate the session settings tables, turn the cultureKey precedence into a numbered list, point the session-handler warning at the gateway-plugin page - gateway-plugin.md: tighten the wording around the plugin example, make "The Session Handler" the single place where the rule is explained - virtual-host.md: turn the gateway directory setup into a numbered list of three steps No headings were renamed, so no anchors and no external links changed. --- en/building-sites/contexts.md | 40 +++++++++++-------- en/building-sites/contexts/gateway-plugin.md | 10 ++--- en/building-sites/contexts/virtual-host.md | 42 ++++++++++---------- 3 files changed, 50 insertions(+), 42 deletions(-) diff --git a/en/building-sites/contexts.md b/en/building-sites/contexts.md index 8d116eb0c..ca8ad216f 100644 --- a/en/building-sites/contexts.md +++ b/en/building-sites/contexts.md @@ -3,9 +3,9 @@ title: "Contexts" description: "Contexts in MODX: how they override system settings, how to create one, how access to them is granted, and the API, events and processors behind them." --- -A Context is a named set of configuration overrides that a request runs under: it carries its own settings, its own branch of the resource tree and its own access rules. +A Context is a named set of configuration overrides that a request runs under: its own settings, its own branch of the resource tree and its own access rules. -MODX ships with two contexts — `web` (Website) for the front end and `mgr` (Manager) for the manager. A context is addressed by its **key**; that key is what you pass to `initialize()` and `switchContext()`. The **name** is a label for the interface. +MODX ships with two contexts — `web` (Website) for the front end and `mgr` (Manager) for the manager. A context is addressed by its **key**, the value passed to `initialize()` and `switchContext()`. The **name** is a label for the interface. ## Creating a Context @@ -13,26 +13,26 @@ Contexts are managed in the manager: **Admin** (the gear in the top menu) → ** | Field | Required | Meaning | | --- | --- | --- | -| `key` | yes | the identifier of the context; the value used in `initialize()` and `switchContext()` | +| `key` | yes | the identifier of the context | | `name` | yes | the label shown in the manager and in the resource tree | | `description` | no | free text | | `rank` | no | the order of the context in the tree | The keys `mgr`, `web` and `root` are reserved by the core. -A new context is granted access right away: the **Administrator** user group receives the *Context* policy, and the anonymous user receives the *Load Only* policy — the right `load` and nothing else. The anonymous access is skipped when the request to the processor carries `enableAnonymous=0`. +A new context is granted access right away: the **Administrator** user group receives the *Context* policy, the anonymous user the *Load Only* policy — the right `load` and nothing else. The anonymous access is skipped when the request to the processor carries `enableAnonymous=0`. -Contexts appear in the resource tree as their own branch, and resources are moved between contexts by dragging them. +Contexts appear in the resource tree as their own branch. Resources are moved between contexts by dragging them. ## Context Settings -The settings of a context override the [System settings](building-sites/settings) of the same name, and the settings of a user override the settings of the context. The order is: +Context settings override the [System settings](building-sites/settings) of the same name, and user settings override the settings of the context. The order is: ``` System setting → Context setting → User setting ``` -A context setting is edited on the **Context Settings** tab of the context page: **Contexts** → right-click a context → **Edit**. Changing a setting clears the cache of that context, so a manual cache clear is not needed. +A context setting is edited on the **Context Settings** tab: **Contexts** → right-click a context → **Edit**. Changing a setting clears the cache of that context, so no manual cache clear is needed. The settings a context usually overrides: @@ -43,14 +43,13 @@ The settings a context usually overrides: | `site_url` | the full URL of the context: scheme, host and path | | `site_start` | the resource that opens the context | | `cultureKey`, `locale` | the language and the locale of the request | -| `session_name`, `session_cookie_path`, `session_cookie_domain` | the session cookie of the context | -The session settings of a context keep the values of the core unless they are overridden: +The session settings configure the session cookie of the context and keep the values of the core unless the context overrides them: | Setting | Value by default | | --- | --- | | `session_name` | empty — PHP keeps its own default | -| `session_cookie_path` | `MODX_BASE_URL`, with `base_url` as the fallback | +| `session_cookie_path` | `MODX_BASE_URL`, or the `base_url` setting when it is set | | `session_cookie_domain` | empty | | `session_cookie_secure` | `false` | | `session_cookie_httponly` | `true` | @@ -59,7 +58,7 @@ The session settings of a context keep the values of the core unless they are ov ## Context Access -Access to a context is granted per user group on the **Contexts** tab of the access panel: the lock icon in the user menu → **Access Control Lists** → a user group → **Access Permissions** → **Contexts**. The tab lists the contexts and the policy the group holds on each of them. +Access to a context is granted per user group on the **Contexts** tab of the access panel: the lock icon in the user menu → **Access Control Lists** → a user group → **Access Permissions** → **Contexts**. A policy on a context decides which of the five access areas applies: Context, Resource Group, Element Category, Media Source and Namespace. A policy without an area covers the context itself. @@ -75,14 +74,21 @@ A setting of the current context is read like any other setting — the level it $setting = $modx->getOption('my_context_setting'); ``` -The setting of a specific context is read from the context itself: +The setting of a specific context is read from that context: ``` php $setting = $modx->context->getOption('my_context_setting'); $setting = $modx->getContext('web')->getOption('my_context_setting'); ``` -The language of a request is taken from the first source that has a value: the `cultureKey` parameter of the request, the `cultureKey` of the session, the `cultureKey` of the context, and finally the `cultureKey` System setting. The code accepts only the characters `A-Z`, `a-z`, `0-9`, `_` and `-` in it. +The language of a request is taken from the first source that has a value: + +1. the `cultureKey` parameter of the request +2. the `cultureKey` of the session +3. the `cultureKey` of the context +4. the `cultureKey` System setting + +The code accepts only the characters `A-Z`, `a-z`, `0-9`, `_` and `-` in a `cultureKey`. ## Choosing a Context at Runtime @@ -91,7 +97,7 @@ A request starts in the context named by the gateway. Two mechanisms change that - the gateway file `config.context.php` next to `index.php` — the file returns the key of the context to start in. See [Serving a Second Domain](building-sites/contexts/virtual-host); - a Plugin on the `OnHandleRequest` event that calls `switchContext()`. See [Using a Gateway Plugin](building-sites/contexts/gateway-plugin). -The method that switches the context at runtime: +The method that switches the context: ``` php if ($modx->switchContext('domain2')) { @@ -99,7 +105,9 @@ if ($modx->switchContext('domain2')) { } ``` -`switchContext($contextKey, $reload = false)` returns `false` when the context was not loaded, so the result has to be checked. Switching the context does **not** load a custom session handler — the handler is set by the gateway. A context with its own session handler needs a gateway of its own. +`switchContext($contextKey, $reload = false)` returns `false` when the context was not loaded, so the result has to be checked. + +Switching the context does **not** load a custom session handler — the handler is set by the gateway: see [Using a Gateway Plugin](building-sites/contexts/gateway-plugin). ## Events @@ -152,7 +160,7 @@ The processors of the contexts and the permission each of them needs: ## Media Sources of a Context -The media source of an element can be set for a single context. The element then uses the source of its own context, and falls back to the default source of the element when the context has none. +The media source of an element can be set for a single context. The element uses the source of its own context and keeps the default source of the element when the context has none. ## One Resource in Several Contexts diff --git a/en/building-sites/contexts/gateway-plugin.md b/en/building-sites/contexts/gateway-plugin.md index 19c33d626..608570c75 100644 --- a/en/building-sites/contexts/gateway-plugin.md +++ b/en/building-sites/contexts/gateway-plugin.md @@ -26,9 +26,9 @@ if (isset($hosts[$host])) { } ``` -The plugin returns nothing in the manager, because the manager must stay in the `mgr` context. +The early return keeps the manager in the `mgr` context. -`switchContext($contextKey, $reload = false)` returns `false` when the context was not loaded. The result is worth checking before the rest of the request relies on the new context: +`switchContext($contextKey, $reload = false)` returns `false` when the context was not loaded. Check the result before the rest of the request relies on the new context: ``` php if (!$modx->switchContext('domain2')) { @@ -38,18 +38,18 @@ if (!$modx->switchContext('domain2')) { ## A Gateway of Its Own -The second mechanism does not need a Plugin. The file `index.php` reads the context from `config.context.php` next to it: +This mechanism needs no Plugin. The file `index.php` reads the context from `config.context.php` next to it: ``` php Date: Tue, 20 Oct 2026 22:56:20 +0600 Subject: [PATCH 3/6] docs(building-sites/contexts): port the editorial pass to the RU and ES locales MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The English pages went through an editorial pass; the Russian and the Spanish pages follow them with the same cuts: - the row about the session cookie is gone from the table of the settings a context overrides — those settings were named twice — and the defaults table keeps them with a lead sentence that says what they do; - the four sources of the `cultureKey` of a request are a numbered list in all three locales; - the session handler rule is stated once, in the gateway plugin page, and the contexts page links to it; - the gateway directory is a numbered list of three steps with the sample inside each step, and the table of the four files follows the order of the steps; - the heading of the session handler section in the Russian page is translated. The structure of the three locales is identical: the same headings, the same tables with the same number of rows and the same code examples. --- es/building-sites/contexts.md | 38 +++++++++++-------- ru/building-sites/contexts.md | 38 +++++++++++-------- ru/building-sites/contexts/gateway-plugin.md | 12 +++--- ru/building-sites/contexts/virtual-host.md | 40 ++++++++++---------- 4 files changed, 72 insertions(+), 56 deletions(-) diff --git a/es/building-sites/contexts.md b/es/building-sites/contexts.md index cffa33fdb..e1ccab839 100644 --- a/es/building-sites/contexts.md +++ b/es/building-sites/contexts.md @@ -3,9 +3,9 @@ title: "Contextos" description: "Contextos en MODX: cómo anulan los ajustes del sistema, cómo crear uno, cómo se concede el acceso y la API, los eventos y los procesadores que hay detrás." --- -Un Contexto es un conjunto con nombre de anulaciones de configuración sobre el que se ejecuta una petición: lleva sus propios ajustes, su propia rama del árbol de recursos y sus propias reglas de acceso. +Un Contexto es un conjunto con nombre de anulaciones de configuración sobre el que se ejecuta una petición: sus propios ajustes, su propia rama del árbol de recursos y sus propias reglas de acceso. -MODX incluye dos contextos: `web` (Website) para el front end y `mgr` (Manager) para el gestor. Un contexto se direcciona por su **clave**; esa clave es la que se pasa a `initialize()` y a `switchContext()`. El **nombre** es solo una etiqueta para la interfaz. +MODX incluye dos contextos: `web` (Website) para el front end y `mgr` (Manager) para el gestor. Un contexto se direcciona por su **clave**, el valor que se pasa a `initialize()` y a `switchContext()`. El **nombre** es solo una etiqueta para la interfaz. ## Creando un contexto @@ -13,16 +13,16 @@ Los contextos se gestionan en el gestor: **Admin** (el engranaje del menú super | Campo | Obligatorio | Significado | | --- | --- | --- | -| `key` | sí | el identificador del contexto; el valor que se usa en `initialize()` y en `switchContext()` | +| `key` | sí | el identificador del contexto | | `name` | sí | la etiqueta que se muestra en el gestor y en el árbol de recursos | | `description` | no | texto libre | | `rank` | no | el orden del contexto en el árbol | Las claves `mgr`, `web` y `root` están reservadas por el núcleo. -Un contexto nuevo recibe acceso de inmediato: el grupo de usuarios **Administrator** recibe la política *Context* y el usuario anónimo recibe la política *Load Only*, el derecho `load` y nada más. El acceso anónimo se omite cuando la petición al procesador lleva `enableAnonymous=0`. +Un contexto nuevo recibe acceso de inmediato: el grupo de usuarios **Administrator** recibe la política *Context* y el usuario anónimo la política *Load Only*, el derecho `load` y nada más. El acceso anónimo se omite cuando la petición al procesador lleva `enableAnonymous=0`. -Los contextos aparecen en el árbol de recursos como una rama propia, y los recursos se mueven entre contextos arrastrándolos. +Los contextos aparecen en el árbol de recursos como una rama propia. Los recursos se mueven entre contextos arrastrándolos. ## Ajustes de contexto @@ -32,7 +32,7 @@ Los ajustes de un contexto anulan los [Ajustes del Sistema](/current/en/building Ajuste del sistema → Ajuste del contexto → Ajuste del usuario ``` -Un ajuste de contexto se edita en la pestaña **Context Settings** de la página del contexto: **Contexts** → clic derecho en un contexto → **Edit**. Cambiar un ajuste borra la caché de ese contexto, así que no hace falta limpiar la caché a mano. +Un ajuste de contexto se edita en la pestaña **Context Settings**: **Contexts** → clic derecho en un contexto → **Edit**. Cambiar un ajuste borra la caché de ese contexto, así que no hace falta limpiar la caché a mano. Los ajustes que un contexto suele anular: @@ -43,14 +43,13 @@ Los ajustes que un contexto suele anular: | `site_url` | la URL completa del contexto: esquema, host y ruta | | `site_start` | el recurso que abre el contexto | | `cultureKey`, `locale` | el idioma y la configuración regional de la petición | -| `session_name`, `session_cookie_path`, `session_cookie_domain` | la cookie de sesión del contexto | -Los ajustes de sesión de un contexto conservan los valores del núcleo salvo que se anulen: +Los ajustes de sesión configuran la cookie de sesión del contexto y conservan los valores del núcleo salvo que el contexto los anule: | Ajuste | Valor por defecto | | --- | --- | | `session_name` | vacío — PHP conserva el suyo | -| `session_cookie_path` | `MODX_BASE_URL`, con `base_url` como alternativa | +| `session_cookie_path` | `MODX_BASE_URL`, o el ajuste `base_url` cuando está definido | | `session_cookie_domain` | vacío | | `session_cookie_secure` | `false` | | `session_cookie_httponly` | `true` | @@ -59,7 +58,7 @@ Los ajustes de sesión de un contexto conservan los valores del núcleo salvo qu ## Acceso al contexto -El acceso a un contexto se concede por grupo de usuarios en la pestaña **Contexts** del panel de acceso: el icono del candado en el menú de usuario → **Access Control Lists** → un grupo de usuarios → **Access Permissions** → **Contexts**. La pestaña enumera los contextos y la política que cada grupo tiene sobre ellos. +El acceso a un contexto se concede por grupo de usuarios en la pestaña **Contexts** del panel de acceso: el icono del candado en el menú de usuario → **Access Control Lists** → un grupo de usuarios → **Access Permissions** → **Contexts**. Una política sobre un contexto decide cuál de las cinco áreas de acceso se aplica: Context, Resource Group, Element Category, Media Source y Namespace. Una política sin área cubre el contexto mismo. @@ -75,14 +74,21 @@ Un ajuste del contexto actual se lee como cualquier otro ajuste; el nivel del qu $setting = $modx->getOption('my_context_setting'); ``` -El ajuste de un contexto concreto se lee del propio contexto: +El ajuste de un contexto concreto se lee de ese contexto: ``` php $setting = $modx->context->getOption('my_context_setting'); $setting = $modx->getContext('web')->getOption('my_context_setting'); ``` -El idioma de una petición se toma de la primera fuente que tenga valor: el parámetro `cultureKey` de la petición, el `cultureKey` de la sesión, el `cultureKey` del contexto y, por último, el ajuste del sistema `cultureKey`. El código solo admite en él los caracteres `A-Z`, `a-z`, `0-9`, `_` y `-`. +El idioma de una petición se toma de la primera fuente que tenga valor: + +1. el parámetro `cultureKey` de la petición +2. el `cultureKey` de la sesión +3. el `cultureKey` del contexto +4. el ajuste del sistema `cultureKey` + +El código solo admite en un `cultureKey` los caracteres `A-Z`, `a-z`, `0-9`, `_` y `-`. ## Elegir un contexto durante la petición @@ -91,7 +97,7 @@ Una petición empieza en el contexto que indique la puerta de entrada. Dos mecan - el archivo `config.context.php` junto a `index.php` — el archivo devuelve la clave del contexto en el que empieza la petición. Ver [Servir un segundo dominio](/current/en/building-sites/contexts/virtual-host); - un Plugin en el evento `OnHandleRequest` que llame a `switchContext()`. Ver [Uso de un Plugin de puerta](/current/en/building-sites/contexts/gateway-plugin). -El método que cambia el contexto durante la ejecución: +El método que cambia el contexto: ``` php if ($modx->switchContext('domain2')) { @@ -99,7 +105,9 @@ if ($modx->switchContext('domain2')) { } ``` -`switchContext($contextKey, $reload = false)` devuelve `false` cuando el contexto no se cargó, así que conviene comprobar el resultado. Cambiar el contexto **no** carga un manejador de sesión propio: lo define la puerta de entrada. Un contexto con su propio manejador de sesión necesita su propia puerta de entrada. +`switchContext($contextKey, $reload = false)` devuelve `false` cuando el contexto no se cargó, así que conviene comprobar el resultado. + +Cambiar el contexto **no** carga un manejador de sesión propio: lo define la puerta de entrada, ver [Uso de un Plugin de puerta](/current/en/building-sites/contexts/gateway-plugin). ## Eventos @@ -152,7 +160,7 @@ Los procesadores de los contextos y el permiso que necesita cada uno: ## Fuentes de medios de un contexto -La fuente de medios de un elemento se puede fijar para un contexto concreto. El elemento usa entonces la fuente de su propio contexto y, si el contexto no tiene ninguna, vuelve a la fuente por defecto del elemento. +La fuente de medios de un elemento se puede fijar para un contexto concreto. El elemento usa la fuente de su propio contexto y conserva la fuente por defecto del elemento cuando el contexto no tiene ninguna. ## Un recurso en varios contextos diff --git a/ru/building-sites/contexts.md b/ru/building-sites/contexts.md index f1c7dac0e..02724abfa 100644 --- a/ru/building-sites/contexts.md +++ b/ru/building-sites/contexts.md @@ -4,9 +4,9 @@ translation: "building-sites/contexts" description: "Контексты в MODX: как они переопределяют системные настройки, как создать контекст, как выдаётся доступ к нему, а также API, события и процессоры контекстов." --- -Контекст — это именованный набор переопределений конфигурации, в котором выполняется запрос: у него свои настройки, своя ветка дерева ресурсов и свои правила доступа. +Контекст — это именованный набор переопределений конфигурации, в котором выполняется запрос: свои настройки, своя ветка дерева ресурсов и свои правила доступа. -В MODX поставляется два контекста — `web` (Website) для фронтенда и `mgr` (Manager) для менеджера. Контекст адресуется **ключом**; именно этот ключ передаётся в `initialize()` и `switchContext()`. **Имя** — только подпись в интерфейсе. +В MODX поставляется два контекста — `web` (Website) для фронтенда и `mgr` (Manager) для менеджера. Контекст адресуется **ключом** — значением, которое передаётся в `initialize()` и `switchContext()`. **Имя** — только подпись в интерфейсе. ## Создание контекста @@ -14,7 +14,7 @@ description: "Контексты в MODX: как они переопределя | Поле | Обязательное | Значение | | --- | --- | --- | -| `key` | да | идентификатор контекста; значение, которое используется в `initialize()` и `switchContext()` | +| `key` | да | идентификатор контекста | | `name` | да | подпись, которая показывается в менеджере и в дереве ресурсов | | `description` | нет | свободный текст | | `rank` | нет | порядок контекста в дереве | @@ -23,17 +23,17 @@ description: "Контексты в MODX: как они переопределя Новый контекст сразу получает доступ: группа пользователей **Administrator** — политику *Context*, анонимный пользователь — политику *Load Only*, то есть право `load` и больше ничего. Анонимный доступ пропускается, если в запрос к процессору передан `enableAnonymous=0`. -Контексты появляются в дереве ресурсов отдельной веткой, а ресурсы переносятся между контекстами перетаскиванием. +Контексты появляются в дереве ресурсов отдельной веткой. Ресурсы переносятся между контекстами перетаскиванием. ## Настройки контекста -Настройки контекста переопределяют [системные настройки](building-sites/settings) с тем же именем, а настройки пользователя переопределяют настройки контекста. Порядок такой: +Настройки контекста переопределяют [системные настройки](building-sites/settings) с тем же именем, а настройки пользователя — настройки контекста. Порядок такой: ``` Системная настройка → Настройка контекста → Настройка пользователя ``` -Настройка контекста правится на вкладке **Context Settings** страницы контекста: **Contexts** → правый клик по контексту → **Edit**. Смена настройки сбрасывает кэш этого контекста, поэтому очищать кэш вручную не нужно. +Настройка контекста правится на вкладке **Context Settings**: **Contexts** → правый клик по контексту → **Edit**. Смена настройки сбрасывает кэш этого контекста, поэтому очищать кэш вручную не нужно. Настройки, которые контекст обычно переопределяет: @@ -44,14 +44,13 @@ description: "Контексты в MODX: как они переопределя | `site_url` | полный URL контекста: схема, хост и путь | | `site_start` | ресурс, который открывается в контексте | | `cultureKey`, `locale` | язык и локаль запроса | -| `session_name`, `session_cookie_path`, `session_cookie_domain` | cookie сессии контекста | -Настройки сессии в контексте сохраняют значения ядра, если их не переопределили: +Настройки сессии настраивают cookie сессии контекста и сохраняют значения ядра, если контекст их не переопределяет: | Настройка | Значение по умолчанию | | --- | --- | | `session_name` | пусто — PHP оставляет своё значение | -| `session_cookie_path` | `MODX_BASE_URL`, с запасным вариантом `base_url` | +| `session_cookie_path` | `MODX_BASE_URL` или настройка `base_url`, если она задана | | `session_cookie_domain` | пусто | | `session_cookie_secure` | `false` | | `session_cookie_httponly` | `true` | @@ -60,7 +59,7 @@ description: "Контексты в MODX: как они переопределя ## Доступ к контексту -Доступ к контексту выдаётся группам пользователей на вкладке **Contexts** панели доступа: иконка замка в меню пользователя → **Access Control Lists** → группа пользователей → **Access Permissions** → **Contexts**. На вкладке перечислены контексты и политика, которая у группы есть на каждом из них. +Доступ к контексту выдаётся группам пользователей на вкладке **Contexts** панели доступа: иконка замка в меню пользователя → **Access Control Lists** → группа пользователей → **Access Permissions** → **Contexts**. Политика на контексте определяет, какая из пяти областей доступа действует: Context, Resource Group, Element Category, Media Source и Namespace. Политика без области покрывает сам контекст. @@ -76,14 +75,21 @@ description: "Контексты в MODX: как они переопределя $setting = $modx->getOption('my_context_setting'); ``` -Настройку конкретного контекста читают у самого контекста: +Настройку конкретного контекста читают у этого контекста: ``` php $setting = $modx->context->getOption('my_context_setting'); $setting = $modx->getContext('web')->getOption('my_context_setting'); ``` -Язык запроса берётся из первого источника, где есть значение: параметр `cultureKey` запроса, `cultureKey` сессии, `cultureKey` контекста и, наконец, системная настройка `cultureKey`. Код допускает в нём только символы `A-Z`, `a-z`, `0-9`, `_` и `-`. +Язык запроса берётся из первого источника, где есть значение: + +1. параметр `cultureKey` запроса +2. `cultureKey` сессии +3. `cultureKey` контекста +4. системная настройка `cultureKey` + +Код допускает в `cultureKey` только символы `A-Z`, `a-z`, `0-9`, `_` и `-`. ## Выбор контекста во время запроса @@ -92,7 +98,7 @@ $setting = $modx->getContext('web')->getOption('my_context_setting'); - файл гейтвея `config.context.php` рядом с `index.php` — файл возвращает ключ контекста, в котором начинается запрос. См. [Второй домен](building-sites/contexts/virtual-host); - плагин на событие `OnHandleRequest`, который вызывает `switchContext()`. См. [Плагин шлюза](building-sites/contexts/gateway-plugin). -Метод, который переключает контекст во время выполнения: +Метод, который переключает контекст: ``` php if ($modx->switchContext('domain2')) { @@ -100,7 +106,9 @@ if ($modx->switchContext('domain2')) { } ``` -`switchContext($contextKey, $reload = false)` возвращает `false`, когда контекст не загрузился, поэтому результат стоит проверять. Переключение контекста **не** подгружает свой session handler — его задаёт гейтвей. Контексту с собственным session handler нужен отдельный гейтвей. +`switchContext($contextKey, $reload = false)` возвращает `false`, когда контекст не загрузился, поэтому результат стоит проверять. + +Переключение контекста **не** подгружает свой session handler — его задаёт гейтвей: см. [Плагин шлюза](building-sites/contexts/gateway-plugin). ## События @@ -153,7 +161,7 @@ if ($modx->switchContext('domain2')) { ## Источники медиа контекста -Источник медиа элемента можно задать для отдельного контекста. Тогда элемент берёт источник своего контекста, а если у контекста источника нет — источник элемента по умолчанию. +Источник медиа элемента можно задать для отдельного контекста. Элемент берёт источник своего контекста и сохраняет источник элемента по умолчанию, если у контекста источника нет. ## Один ресурс в нескольких контекстах diff --git a/ru/building-sites/contexts/gateway-plugin.md b/ru/building-sites/contexts/gateway-plugin.md index 27f3f0dee..b8a2b1ea0 100644 --- a/ru/building-sites/contexts/gateway-plugin.md +++ b/ru/building-sites/contexts/gateway-plugin.md @@ -27,9 +27,9 @@ if (isset($hosts[$host])) { } ``` -Плагин ничего не возвращает в менеджере, потому что менеджер должен остаться в контексте `mgr`. +Ранний выход оставляет менеджер в контексте `mgr`. -`switchContext($contextKey, $reload = false)` возвращает `false`, когда контекст не загрузился. Результат стоит проверять, прежде чем дальнейшая работа запроса будет опираться на новый контекст: +`switchContext($contextKey, $reload = false)` возвращает `false`, когда контекст не загрузился. Проверьте результат, прежде чем дальнейшая работа запроса будет опираться на новый контекст: ``` php if (!$modx->switchContext('domain2')) { @@ -39,18 +39,18 @@ if (!$modx->switchContext('domain2')) { ## Собственный гейтвей -Второй механизм обходится без плагина. Файл `index.php` читает контекст из файла `config.context.php` рядом с ним: +Этот механизм обходится без плагина. Файл `index.php` читает контекст из файла `config.context.php` рядом с ним: ``` php Date: Tue, 20 Oct 2026 23:17:00 +0600 Subject: [PATCH 4/6] docs(building-sites/contexts): drop the unused screenshots of the MODX 2 panel The two frames showed the Contexts grid and the "Crear Contexto" window of MODX 2. The page of the section is written for MODX 3 and no longer refers to them, so nothing points at them any more. --- es/building-sites/contexto-2.png | Bin 12114 -> 0 bytes es/building-sites/contextos.png | Bin 27003 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 es/building-sites/contexto-2.png delete mode 100644 es/building-sites/contextos.png diff --git a/es/building-sites/contexto-2.png b/es/building-sites/contexto-2.png deleted file mode 100644 index b46671b0114200a396c779968d0cc79a65895b51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12114 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 z 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 X{YbfR`c}GP{tic64wwDM@7(_Y)K`HI From 8f3d0f33b7d1c0acf0adff862bdffb7663e2ab65 Mon Sep 17 00:00:00 2001 From: Ivan Bochkarev Date: Wed, 21 Oct 2026 10:04:17 +0600 Subject: [PATCH 5/6] docs(building-sites/contexts): address the review of #677 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four remarks, all of them about how the page talks to the reader. **The two approaches to several domains were not told apart.** The page of the virtual host read as if it were the only way to serve a second domain. It now says that it describes the approach where every domain has a virtual host and a directory of its own on the same machine, and that when several domains point at one virtual host a Plugin picks the context instead — with a link to the other page. The title goes back to **Using Virtual Hosts**, which keeps that distinction. The URL of the page does not change. **The introduction of the gateway plugin page was vague.** It now opens with the two approaches side by side, says which one the page is about, and links to the other. The section that described the second approach in half is gone — the gateway plugin page is about the Plugin. **The gateway directory did not say what the copies have in common.** Three sentences now say that the copies of `index.php`, `config.core.php` and `.htaccess` point at the same core and the same database, and that only the context differs between the directories. **The anonymous access was described through the processor.** The page named the property `enableAnonymous=0` of the request. The reader sees the access in the manager: the entry of the anonymous user shows as **(anonymous)** in the **Access Permissions** tab of the context, and removing it there takes the access away. The Russian and the Spanish pages follow. --- en/building-sites/contexts.md | 6 ++--- en/building-sites/contexts/gateway-plugin.md | 24 ++++++++------------ en/building-sites/contexts/virtual-host.md | 10 +++++--- es/building-sites/contexts.md | 2 +- ru/building-sites/contexts.md | 6 ++--- ru/building-sites/contexts/gateway-plugin.md | 24 ++++++++------------ ru/building-sites/contexts/virtual-host.md | 10 +++++--- 7 files changed, 39 insertions(+), 43 deletions(-) diff --git a/en/building-sites/contexts.md b/en/building-sites/contexts.md index ca8ad216f..39b070a53 100644 --- a/en/building-sites/contexts.md +++ b/en/building-sites/contexts.md @@ -20,7 +20,7 @@ Contexts are managed in the manager: **Admin** (the gear in the top menu) → ** The keys `mgr`, `web` and `root` are reserved by the core. -A new context is granted access right away: the **Administrator** user group receives the *Context* policy, the anonymous user the *Load Only* policy — the right `load` and nothing else. The anonymous access is skipped when the request to the processor carries `enableAnonymous=0`. +A new context is granted access right away: the **Administrator** user group receives the *Context* policy, the anonymous user the *Load Only* policy — the right `load` and nothing else. The anonymous entry shows as **(anonymous)** in the **Access Permissions** tab of the context, and removing it there takes that access away. Contexts appear in the resource tree as their own branch. Resources are moved between contexts by dragging them. @@ -94,7 +94,7 @@ The code accepts only the characters `A-Z`, `a-z`, `0-9`, `_` and `-` in a `cult A request starts in the context named by the gateway. Two mechanisms change that: -- the gateway file `config.context.php` next to `index.php` — the file returns the key of the context to start in. See [Serving a Second Domain](building-sites/contexts/virtual-host); +- the gateway file `config.context.php` next to `index.php` — the file returns the key of the context to start in. See [Using Virtual Hosts](building-sites/contexts/virtual-host); - a Plugin on the `OnHandleRequest` event that calls `switchContext()`. See [Using a Gateway Plugin](building-sites/contexts/gateway-plugin). The method that switches the context: @@ -168,7 +168,7 @@ A resource normally belongs to one context. With `use_context_resource_table` en ## See Also -1. [Serving a Second Domain](building-sites/contexts/virtual-host) +1. [Using Virtual Hosts](building-sites/contexts/virtual-host) 2. [Using a Gateway Plugin](building-sites/contexts/gateway-plugin) 3. [System Settings](building-sites/settings) 4. [Access Control Lists](building-sites/client-proofing/security/policies/acls) diff --git a/en/building-sites/contexts/gateway-plugin.md b/en/building-sites/contexts/gateway-plugin.md index 608570c75..45ea39ae4 100644 --- a/en/building-sites/contexts/gateway-plugin.md +++ b/en/building-sites/contexts/gateway-plugin.md @@ -1,9 +1,14 @@ --- title: "Using a Gateway Plugin" -description: "Serving several domains from one MODX installation: switching the context by host with a Plugin on OnHandleRequest, or with a gateway of its own." +description: "Serving several domains from one MODX installation: the Plugin that switches the context by host, and the approach with a virtual host and a directory for every domain." --- -One installation can serve several domains. The context of the request is what tells them apart, and two mechanisms choose it: a Plugin that switches the context, or a gateway file that starts in it. +One installation can serve several domains, and the context of the request is what tells them apart. Two approaches do that: + +- **One virtual host, several domains.** Every domain points at the same virtual host, and a Plugin on `OnHandleRequest` reads the host and switches the context. This is the approach of this page. +- **A virtual host and a directory for every domain.** Each domain gets a virtual host of its own and a gateway directory with its own `config.context.php`. See [Using Virtual Hosts](building-sites/contexts/virtual-host). + +The first approach needs nothing but the Plugin. ## Switching the Context by Host @@ -36,24 +41,13 @@ if (!$modx->switchContext('domain2')) { } ``` -## A Gateway of Its Own - -This mechanism needs no Plugin. The file `index.php` reads the context from `config.context.php` next to it: - -``` php -getContext('web')->getOption('my_context_setting'); Запрос начинается в контексте, который называет гейтвей. Сменить контекст могут два механизма: -- файл гейтвея `config.context.php` рядом с `index.php` — файл возвращает ключ контекста, в котором начинается запрос. См. [Второй домен](building-sites/contexts/virtual-host); +- файл гейтвея `config.context.php` рядом с `index.php` — файл возвращает ключ контекста, в котором начинается запрос. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host); - плагин на событие `OnHandleRequest`, который вызывает `switchContext()`. См. [Плагин шлюза](building-sites/contexts/gateway-plugin). Метод, который переключает контекст: @@ -169,7 +169,7 @@ if ($modx->switchContext('domain2')) { ## Смотрите также -1. [Второй домен](building-sites/contexts/virtual-host) +1. [Использование виртуальных хостов](building-sites/contexts/virtual-host) 2. [Плагин шлюза](building-sites/contexts/gateway-plugin) 3. [Системные настройки](building-sites/settings) 4. [ACL](building-sites/client-proofing/security/policies/acls) diff --git a/ru/building-sites/contexts/gateway-plugin.md b/ru/building-sites/contexts/gateway-plugin.md index b8a2b1ea0..9c8bb770c 100644 --- a/ru/building-sites/contexts/gateway-plugin.md +++ b/ru/building-sites/contexts/gateway-plugin.md @@ -1,10 +1,15 @@ --- title: "Использование плагина шлюза" translation: "building-sites/contexts/gateway-plugin" -description: "Несколько доменов с одной установки MODX: переключение контекста по хосту плагином на OnHandleRequest или отдельным гейтвеем." +description: "Несколько доменов с одной установки MODX: плагин, который переключает контекст по хосту, и подход со своим виртуальным хостом и каталогом каждому домену." --- -Одна установка может обслуживать несколько доменов. Различает их контекст запроса, и выбирают его два механизма: плагин, который переключает контекст, или гейтвей, который начинает в нём работу. +Одна установка может обслуживать несколько доменов, и различает их контекст запроса. Делают это двумя подходами: + +- **Один виртуальный хост, несколько доменов.** Каждый домен указывает на один и тот же виртуальный хост, а плагин на `OnHandleRequest` читает хост и переключает контекст. Именно этот подход описан на странице. +- **Свой виртуальный хост и свой каталог каждому домену.** У каждого домена свой виртуальный хост и свой каталог гейтвея со своим `config.context.php`. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host). + +Первому подходу нужен только плагин. ## Переключение контекста по хосту @@ -37,24 +42,13 @@ if (!$modx->switchContext('domain2')) { } ``` -## Собственный гейтвей - -Этот механизм обходится без плагина. Файл `index.php` читает контекст из файла `config.context.php` рядом с ним: - -``` php - Date: Fri, 23 Oct 2026 12:55:36 +0600 Subject: [PATCH 6/6] docs(building-sites/contexts): match the manager labels and the 3.x runtime The pages named fields the form does not show, listed an event that is not registered, and gave the session cookie a lifetime of 0. --- en/building-sites/contexts.md | 122 ++++++++---------- en/building-sites/contexts/gateway-plugin.md | 18 +-- en/building-sites/contexts/virtual-host.md | 46 ++++--- es/building-sites/contexts.md | 125 ++++++++----------- ru/building-sites/contexts.md | 108 +++++++--------- ru/building-sites/contexts/gateway-plugin.md | 16 +-- ru/building-sites/contexts/virtual-host.md | 32 +++-- 7 files changed, 208 insertions(+), 259 deletions(-) diff --git a/en/building-sites/contexts.md b/en/building-sites/contexts.md index 39b070a53..d4f9f69eb 100644 --- a/en/building-sites/contexts.md +++ b/en/building-sites/contexts.md @@ -1,70 +1,77 @@ --- title: "Contexts" -description: "Contexts in MODX: how they override system settings, how to create one, how access to them is granted, and the API, events and processors behind them." +description: "Contexts in MODX: how they override system settings, how to create one, and how access to them is granted." --- -A Context is a named set of configuration overrides that a request runs under: its own settings, its own branch of the resource tree and its own access rules. +A Context is a named set of configuration overrides that a request runs under. It has its own settings, its own branch of the resource tree and its own access rules. -MODX ships with two contexts — `web` (Website) for the front end and `mgr` (Manager) for the manager. A context is addressed by its **key**, the value passed to `initialize()` and `switchContext()`. The **name** is a label for the interface. +MODX ships with two contexts: `web` (Website) for the front end and `mgr` (Manager) for the manager. The **key** is the value passed to `initialize()` and `switchContext()`. The **name** is a label in the interface. ## Creating a Context -Contexts are managed in the manager: **Admin** (the gear in the top menu) → **Contexts** (`?a=context`). The **Create** button opens a form with four fields: +Open **Admin** (the gear in the top menu) → **Contexts**. **Create** opens a form: | Field | Required | Meaning | | --- | --- | --- | -| `key` | yes | the identifier of the context | -| `name` | yes | the label shown in the manager and in the resource tree | -| `description` | no | free text | -| `rank` | no | the order of the context in the tree | +| **Context Key** | yes | the identifier of the context | +| **Name** | yes | the label shown in the manager and in the resource tree | +| **Description** | no | free text | +| **Rank** | no | the order of the context in the tree | -The keys `mgr`, `web` and `root` are reserved by the core. +The keys `mgr`, `web` and `root` are reserved. A key starts with a letter. After that it may contain letters, digits, a hyphen, a dot and a slash. An underscore is rejected, so `domain_2` is not saved. -A new context is granted access right away: the **Administrator** user group receives the *Context* policy, the anonymous user the *Load Only* policy — the right `load` and nothing else. The anonymous entry shows as **(anonymous)** in the **Access Permissions** tab of the context, and removing it there takes that access away. +A new context gets access immediately: -Contexts appear in the resource tree as their own branch. Resources are moved between contexts by dragging them. +- the **Administrator** user group receives the *Context* policy +- the anonymous user receives the *Load Only* policy: the right `load` and nothing else + +The anonymous entry shows as **(anonymous)** on the context's **Access Permissions** tab. Remove that entry to take the access away. + +Each context is its own branch in the resource tree. Drag a resource to another context. + +**Duplicate** copies the settings, the access rules and the media sources. **Duplicate resources** is checked in that window and copies the resources. Clear the box to leave the resources where they are. ## Context Settings -Context settings override the [System settings](building-sites/settings) of the same name, and user settings override the settings of the context. The order is: +A context setting overrides the [System setting](building-sites/settings) of the same name. A user group setting overrides the context setting. A user setting overrides the user group setting. ``` -System setting → Context setting → User setting +System setting → Context setting → User Group setting → User setting ``` -A context setting is edited on the **Context Settings** tab: **Contexts** → right-click a context → **Edit**. Changing a setting clears the cache of that context, so no manual cache clear is needed. +Edit a setting on the **Context Settings** tab: **Contexts** → right-click a context → **Edit**. Changing a setting clears that context's cache. You do not need to clear the cache by hand. -The settings a context usually overrides: +Settings a context usually overrides: | Setting | What it changes | | --- | --- | -| `base_url` | the path part of the URLs of the context | +| `base_url` | the path in the context's URLs | | `http_host` | the host the URLs are built for | -| `site_url` | the full URL of the context: scheme, host and path | +| `site_url` | the context's full URL: scheme, host and path | | `site_start` | the resource that opens the context | | `cultureKey`, `locale` | the language and the locale of the request | -The session settings configure the session cookie of the context and keep the values of the core unless the context overrides them: +These settings control the context's session cookie. They keep the core values unless the context overrides them: | Setting | Value by default | | --- | --- | -| `session_name` | empty — PHP keeps its own default | +| `session_name` | empty: PHP keeps its own default | | `session_cookie_path` | `MODX_BASE_URL`, or the `base_url` setting when it is set | | `session_cookie_domain` | empty | | `session_cookie_secure` | `false` | | `session_cookie_httponly` | `true` | | `session_cookie_samesite` | empty | -| `session_cookie_lifetime` | `0` | +| `session_cookie_lifetime` | `604800` (7 days). A context can set `0`, and then the cookie lasts until the browser closes | ## Context Access -Access to a context is granted per user group on the **Contexts** tab of the access panel: the lock icon in the user menu → **Access Control Lists** → a user group → **Access Permissions** → **Contexts**. +Access is granted per user group. Open the lock icon in the user menu → **Access Control Lists** → a user group → **Access Permissions** → **Contexts**. -A policy on a context decides which of the five access areas applies: Context, Resource Group, Element Category, Media Source and Namespace. A policy without an area covers the context itself. +A user group's access panel has five tabs: **Contexts**, **Resource Groups**, **Element Categories**, **Media Sources** and **Namespaces**. A policy does not pick the tab. The policy template has to belong to the same group as the tab you are editing. ## Reading Context Settings -A setting of the current context is read like any other setting — the level it comes from is not visible to the reader: +Read the current context's setting like any other setting. The call does not show which level supplied the value: ``` php [[++my_context_setting]] @@ -74,30 +81,29 @@ A setting of the current context is read like any other setting — the level it $setting = $modx->getOption('my_context_setting'); ``` -The setting of a specific context is read from that context: +For a specific context: ``` php $setting = $modx->context->getOption('my_context_setting'); $setting = $modx->getContext('web')->getOption('my_context_setting'); ``` -The language of a request is taken from the first source that has a value: +The request language comes from the first source that has a value: -1. the `cultureKey` parameter of the request -2. the `cultureKey` of the session -3. the `cultureKey` of the context -4. the `cultureKey` System setting +1. the request's `cultureKey` parameter +2. the session's `cultureKey` +3. the user setting `cultureKey` +4. the context's `cultureKey` +5. the `cultureKey` system setting -The code accepts only the characters `A-Z`, `a-z`, `0-9`, `_` and `-` in a `cultureKey`. +If every source is empty, or the value fails the character check, the language is `en`. The check allows `A-Z`, `a-z`, `0-9`, `_` and `-`. In the manager, `manager_language` replaces that result. ## Choosing a Context at Runtime -A request starts in the context named by the gateway. Two mechanisms change that: - -- the gateway file `config.context.php` next to `index.php` — the file returns the key of the context to start in. See [Using Virtual Hosts](building-sites/contexts/virtual-host); -- a Plugin on the `OnHandleRequest` event that calls `switchContext()`. See [Using a Gateway Plugin](building-sites/contexts/gateway-plugin). +A request starts in the context the gateway chooses. Two mechanisms change that: -The method that switches the context: +- the gateway file `config.context.php` next to `index.php`. The file returns the context key the request starts in. See [Using Virtual Hosts](building-sites/contexts/virtual-host); +- a Plugin on `OnHandleRequest` that calls `switchContext()`. See [Using a Gateway Plugin](building-sites/contexts/gateway-plugin). ``` php if ($modx->switchContext('domain2')) { @@ -105,70 +111,48 @@ if ($modx->switchContext('domain2')) { } ``` -`switchContext($contextKey, $reload = false)` returns `false` when the context was not loaded, so the result has to be checked. +`switchContext($contextKey, $reload = false)` returns `false` when the context was not loaded, and when the key is already the current context. In the second case the context is not loaded again. Check the result: on a request that is already in `domain2`, the example above takes the failure branch. -Switching the context does **not** load a custom session handler — the handler is set by the gateway: see [Using a Gateway Plugin](building-sites/contexts/gateway-plugin). +Switching the context during the request does not load a custom session handler, and it does not change the language, the locale or the session cookie. Those come from the context that `index.php` started in. A domain that needs its own language or cookie uses its own directory with `config.context.php`. See [Using Virtual Hosts](building-sites/contexts/virtual-host). ## Events | Event | When it fires | | --- | --- | -| `OnContextInit` | a context is loaded: on every request and on every `switchContext()` | +| `OnContextInit` | a context is loaded. A successful `switchContext()` to a different context loads it. A call for the context that is already current does not | | `OnContextBeforeSave` | before a context is saved | | `OnContextSave` | after a context is saved | -| `OnContextUpdate` | a context is updated in the manager | | `OnContextBeforeRemove` | before a context is removed | | `OnContextRemove` | after a context is removed | -| `OnContextFormPrerender` | before the form of a context is rendered | -| `OnContextFormRender` | after the form of a context is rendered | +| `OnContextFormPrerender` | before a context form is rendered | +| `OnContextFormRender` | after a context form is rendered | -The events of MODX 2 that are often named in older material — `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` and `OnBeforeRequest` — do not exist in MODX 3. +MODX 2 events often named in older material do not exist in MODX 3: `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` and `OnBeforeRequest`. ## System Settings | Setting | Value by default | What it does | | --- | --- | --- | -| `default_context` | `web` | the context new resources are created in | +| `default_context` | `web` | the context the create form uses when the resource is not created inside another context's branch. A branch of the tree uses that branch's context | | `access_context_enabled` | `true` | checks the access to a context on every request; switching it off ignores every context access rule | | `allow_forward_across_contexts` | `false` | lets a symlink and `sendForward()` reach a resource in another context | -| `cache_context_settings` | `true` | caches the settings of the contexts | +| `cache_context_settings` | `true` | caches context settings | | `use_context_resource_table` | `true` | keeps the table of resources that belong to several contexts | -| `context_tree_sort` | `true` | sorts the contexts in the resource tree by name | +| `context_tree_sort` | `true` | turns sorting of contexts in the resource tree on. The field is `context_tree_sortby` | | `context_tree_sortby` | `rank` | the field the contexts of the tree are sorted by | | `context_tree_sortdir` | `ASC` | the direction of the sorting | -## Processors - -The processors of the contexts and the permission each of them needs: - -| Processor | Permission | -| --- | --- | -| `Context/Create` | `new_context` | -| `Context/Duplicate` | `new_context` | -| `Context/Get` | `view_context` | -| `Context/GetList` | `view_context` | -| `Context/Update` | `edit_context` | -| `Context/UpdateFromGrid` | `edit_context` | -| `Context/Remove` | `delete_context` | -| `Context/Setting/Create` | `settings` | -| `Context/Setting/Get` | `settings` | -| `Context/Setting/GetList` | `settings` | -| `Context/Setting/Remove` | `settings` | -| `Context/Setting/Update` | the `save` policy of the context | - -`Context/Duplicate` copies the settings, the access rules and the media sources of the context, and — with `duplicateResources=1` — its resources as well. - ## Media Sources of a Context -The media source of an element can be set for a single context. The element uses the source of its own context and keeps the default source of the element when the context has none. +You can set an element's media source for one context. The element uses its own context's source. With no source on the context, it keeps the element's default source. ## One Resource in Several Contexts -A resource normally belongs to one context. With `use_context_resource_table` enabled, the table `context_resource` holds the resources that belong to several of them, and such a resource is found in each of the listed contexts. +A resource normally belongs to one context. With `use_context_resource_table` on, the `context_resource` table stores resources that belong to several contexts. MODX finds such a resource in each listed context. ## See Also 1. [Using Virtual Hosts](building-sites/contexts/virtual-host) 2. [Using a Gateway Plugin](building-sites/contexts/gateway-plugin) 3. [System Settings](building-sites/settings) -4. [Access Control Lists](building-sites/client-proofing/security/policies/acls) +4. [ACLs](building-sites/client-proofing/security/policies/acls) diff --git a/en/building-sites/contexts/gateway-plugin.md b/en/building-sites/contexts/gateway-plugin.md index 45ea39ae4..6929df6f0 100644 --- a/en/building-sites/contexts/gateway-plugin.md +++ b/en/building-sites/contexts/gateway-plugin.md @@ -3,16 +3,16 @@ title: "Using a Gateway Plugin" description: "Serving several domains from one MODX installation: the Plugin that switches the context by host, and the approach with a virtual host and a directory for every domain." --- -One installation can serve several domains, and the context of the request is what tells them apart. Two approaches do that: +One installation can serve several domains. The request's context tells them apart. Two approaches do that: -- **One virtual host, several domains.** Every domain points at the same virtual host, and a Plugin on `OnHandleRequest` reads the host and switches the context. This is the approach of this page. -- **A virtual host and a directory for every domain.** Each domain gets a virtual host of its own and a gateway directory with its own `config.context.php`. See [Using Virtual Hosts](building-sites/contexts/virtual-host). +- **One virtual host, several domains.** Every domain points at the same virtual host. A Plugin on `OnHandleRequest` reads the host and switches the context. This page covers this approach. +- **A virtual host and a directory for every domain.** Each domain gets its own virtual host and a gateway directory with its own `config.context.php`. See [Using Virtual Hosts](building-sites/contexts/virtual-host). -The first approach needs nothing but the Plugin. +The first approach needs only the Plugin. ## Switching the Context by Host -The event `OnHandleRequest` fires at the start of every request — in the front end and in the manager alike. A Plugin on it reads the host and switches the context: +`OnHandleRequest` fires at the start of every request, on the front end and in the manager. ``` php switchContext('domain2')) { @@ -41,9 +41,11 @@ if (!$modx->switchContext('domain2')) { } ``` +On a request that is already in `domain2`, that check also fails, because the context was not switched. + ## The Session Handler -Switching the context at runtime does not load a custom session handler: the handler is set by the gateway and applies to the whole request. A context with a session handler of its own needs a gateway of its own: see [Using Virtual Hosts](building-sites/contexts/virtual-host). +Switching the context at runtime does not load a custom session handler. It does not change the language, the locale or the session cookie. Those come from the context that `index.php` started in. A domain that needs its own language or cookie uses its own directory with `config.context.php`. See [Using Virtual Hosts](building-sites/contexts/virtual-host). ## See Also diff --git a/en/building-sites/contexts/virtual-host.md b/en/building-sites/contexts/virtual-host.md index 6998140fc..049b9e657 100644 --- a/en/building-sites/contexts/virtual-host.md +++ b/en/building-sites/contexts/virtual-host.md @@ -3,47 +3,45 @@ title: "Using Virtual Hosts" description: "Giving every domain its own virtual host and its own directory on one MODX installation: the context and its settings, the gateway directory with its own config.context.php, and the virtual host of the web server." --- -MODX 3 does not match a host with a context by itself. The gateway that starts a request chooses its context, so a second domain needs a second gateway. +MODX 3 does not match a host with a context by itself. The gateway that starts a request chooses the context, so a second domain needs a second gateway. -This page describes the approach where every domain has a virtual host of its own and a directory of its own on the same machine. When several domains point at one virtual host, a Plugin picks the context instead — see [Using a Gateway Plugin](building-sites/contexts/gateway-plugin). - -The example below builds such a gateway for the context `dev` on the host `dev.example.com`. +Every domain here has its own virtual host and its own directory on the same machine. When several domains point at one virtual host, a Plugin picks the context. See [Using a Gateway Plugin](building-sites/contexts/gateway-plugin). ## Creating the Context -Create the context in the manager: **Admin** → **Contexts** → **Create**. The **Context Key** is `dev` — the key is what the gateway names — and the name is free. The keys `mgr`, `web` and `root` are reserved by the core. +Create the context in the manager: **Admin** → **Contexts** → **Create**. The **Context Key** is `dev`. The keys `mgr`, `web` and `root` are reserved. A key starts with a letter. After that it may contain letters, digits, a hyphen, a dot and a slash. An underscore is rejected. -Then create the resources of the domain in the branch of the context. The tree looks like this: +Then create the domain's resources in the context's branch. The tree looks like this: ![](subctx1.png) -## The Settings of the Context +## Context Settings -Four settings on the **Context Settings** tab of the context decide how the URLs of the domain are built: +Four settings on the context's **Context Settings** tab decide how the domain's URLs are built: | Setting | Value | | --- | --- | | `base_url` | `/` | | `http_host` | `dev.example.com` | | `site_start` | the ID of the resource that opens the domain | -| `site_url` | `http://dev.example.com/` — the scheme, the host and the path, with a trailing slash | +| `site_url` | `http://dev.example.com/` — scheme, host and path, with a trailing slash | -Any other setting can be overridden here as well — `cultureKey` for the language of the domain, for example. Changing a setting clears the cache of the context, so no manual cache clear is needed. +You can override any other setting here too. `cultureKey` sets the domain's language. `session_handler_class` sets the session handler for this gateway. The value is the class name you enter. Changing a setting clears the context's cache. You do not need to clear the cache by hand. ## The Gateway Directory -The gateway is a directory of its own with four files: +The gateway is its own directory with four files: | File | What it holds | | --- | --- | -| `index.php` | a copy of `index.php` from the installation | -| `config.context.php` | the key of the context | -| `config.core.php` | a copy of `config.core.php` from the installation | -| `.htaccess` | a copy of `.htaccess` from the installation | +| `index.php` | a copy of the installation's `index.php` | +| `config.context.php` | the context key | +| `config.core.php` | a copy of the installation's `config.core.php` | +| `.htaccess` | a copy of the installation's `.htaccess` | The three copies point at the same core and the same database. Only the context differs between the directories. -`index.php` works as it is. The other three files are set up as follows: +`index.php` works as it is. Set up the other three files as follows: 1. `config.context.php` holds one line: @@ -52,13 +50,13 @@ The three copies point at the same core and the same database. Only the context return 'dev'; ``` -2. `config.core.php` holds the path to the core of the installation as an absolute path — the installer writes it that way: +2. `config.core.php` holds the absolute path to the installation's core. The installer writes it that way: ``` php define('MODX_CORE_PATH', '/home/example.com/public_html/core/'); ``` -3. `.htaccess` needs one change — `RewriteBase` has to point to the directory of the gateway: +3. `.htaccess` needs one change. `RewriteBase` has to point at the gateway directory: ``` RewriteBase /dev/ @@ -66,28 +64,26 @@ The three copies point at the same core and the same database. Only the context ## The Virtual Host -The web server needs a host of its own for that directory. For Apache 2.4: +The web server needs its own host for that directory. For Apache 2.4: ``` apache ServerName dev.example.com DocumentRoot /home/example.com/public_html/dev - ErrorLog logs/dev-error_log - CustomLog logs/dev-access_log ``` -Restart the web server and open `http://dev.example.com/` — the resource named by `site_start` answers. +Restart the web server and open `http://dev.example.com/`. The resource named by `site_start` answers. -## Links Between the Contexts +## Links Between Contexts -A link to a resource of another context names that context: +A link to another context's resource names that context: ``` [[~135:context=`web`]] ``` -The URL is absolute, because the resource lives in another context. A link without a context stays in the context of the request and is relative: +The URL is absolute when the named context is not the current one. A link without `context` stays relative when the resource belongs to the current context. When that resource belongs to another context, the link is the absolute URL of the context stored on the resource: ``` [[~135]] diff --git a/es/building-sites/contexts.md b/es/building-sites/contexts.md index 989b3a9be..a28add79c 100644 --- a/es/building-sites/contexts.md +++ b/es/building-sites/contexts.md @@ -1,70 +1,78 @@ --- title: "Contextos" -description: "Contextos en MODX: cómo anulan los ajustes del sistema, cómo crear uno, cómo se concede el acceso y la API, los eventos y los procesadores que hay detrás." +description: "Contextos en MODX: cómo anulan los ajustes del sistema, cómo crear uno y cómo se concede el acceso." +translation: "building-sites/contexts" --- -Un Contexto es un conjunto con nombre de anulaciones de configuración sobre el que se ejecuta una petición: sus propios ajustes, su propia rama del árbol de recursos y sus propias reglas de acceso. +Un contexto es un conjunto con nombre de anulaciones de configuración. La petición se ejecuta bajo ese conjunto, con sus propios ajustes, su propia rama del árbol de recursos y sus propias reglas de acceso. -MODX incluye dos contextos: `web` (Website) para el front end y `mgr` (Manager) para el gestor. Un contexto se direcciona por su **clave**, el valor que se pasa a `initialize()` y a `switchContext()`. El **nombre** es solo una etiqueta para la interfaz. +MODX incluye dos contextos: `web` (Website) para la parte pública y `mgr` (Manager) para el gestor. La **clave** es el valor que se pasa a `initialize()` y a `switchContext()`. El **nombre** es una etiqueta de la interfaz. -## Creando un contexto +## Crear un contexto -Los contextos se gestionan en el gestor: **Admin** (el engranaje del menú superior) → **Contexts** (`?a=context`). El botón **Create** abre un formulario con cuatro campos: +Abra **Administrador** (el engranaje del menú superior) → **Contextos**. **Crear** abre un formulario: | Campo | Obligatorio | Significado | | --- | --- | --- | -| `key` | sí | el identificador del contexto | -| `name` | sí | la etiqueta que se muestra en el gestor y en el árbol de recursos | -| `description` | no | texto libre | -| `rank` | no | el orden del contexto en el árbol | +| **Clave del Contexto** | sí | el identificador del contexto | +| **Nombre** | sí | la etiqueta del gestor y del árbol de recursos | +| **Descripción** | no | texto libre | +| **Posición** | no | el orden del contexto en el árbol | -Las claves `mgr`, `web` y `root` están reservadas por el núcleo. +Las claves `mgr`, `web` y `root` están reservadas. La clave empieza por una letra. Después admite letras, dígitos, un guion, un punto y una barra. El guion bajo se rechaza, así que `domain_2` no se guarda. -Un contexto nuevo recibe acceso de inmediato: el grupo de usuarios **Administrator** recibe la política *Context* y el usuario anónimo la política *Load Only*, el derecho `load` y nada más. La entrada del usuario anónimo aparece como **(anonymous)** en la pestaña **Access Permissions** del contexto, y quitarla ahí retira ese acceso. +Un contexto nuevo recibe acceso de inmediato: -Los contextos aparecen en el árbol de recursos como una rama propia. Los recursos se mueven entre contextos arrastrándolos. +- el grupo de usuarios **Administrator** recibe la política *Context* +- el usuario anónimo recibe la política *Load Only*: el derecho `load` y nada más + +La entrada del anónimo aparece como **(anónimo)** en la pestaña **Permisos de Acceso** del contexto. Quítela para retirar ese acceso. + +Cada contexto es una rama propia en el árbol de recursos. Arrastre un recurso a otro contexto. + +**Duplicar** copia los ajustes, las reglas de acceso y las fuentes de medios. En esa ventana la casilla **Duplicar recursos** viene marcada y copia los recursos. Desmárquela para dejar los recursos donde están. ## Ajustes de contexto -Los ajustes de un contexto anulan los [Ajustes del Sistema](/current/en/building-sites/settings) del mismo nombre, y los ajustes de un usuario anulan los del contexto. El orden es: +Un ajuste de contexto anula el [ajuste del sistema](building-sites/settings) del mismo nombre. Un ajuste del grupo de usuarios anula el ajuste del contexto. Un ajuste de usuario anula el ajuste del grupo. ``` -Ajuste del sistema → Ajuste del contexto → Ajuste del usuario +Ajuste del sistema → Ajuste del contexto → Ajuste del grupo de usuarios → Ajuste del usuario ``` -Un ajuste de contexto se edita en la pestaña **Context Settings**: **Contexts** → clic derecho en un contexto → **Edit**. Cambiar un ajuste borra la caché de ese contexto, así que no hace falta limpiar la caché a mano. +Edite un ajuste en la pestaña **Configuraciones del Contexto**: **Contextos** → clic derecho en un contexto → **Editar**. Cambiar un ajuste borra la caché de ese contexto. No hace falta limpiar la caché a mano. -Los ajustes que un contexto suele anular: +Ajustes que un contexto suele anular: | Ajuste | Qué cambia | | --- | --- | -| `base_url` | la parte de ruta de las URL del contexto | +| `base_url` | la ruta en las URL del contexto | | `http_host` | el host para el que se construyen las URL | | `site_url` | la URL completa del contexto: esquema, host y ruta | | `site_start` | el recurso que abre el contexto | | `cultureKey`, `locale` | el idioma y la configuración regional de la petición | -Los ajustes de sesión configuran la cookie de sesión del contexto y conservan los valores del núcleo salvo que el contexto los anule: +Estos ajustes configuran la cookie de sesión del contexto. Conservan los valores del núcleo salvo que el contexto los anule: | Ajuste | Valor por defecto | | --- | --- | -| `session_name` | vacío — PHP conserva el suyo | +| `session_name` | vacío: PHP conserva el suyo | | `session_cookie_path` | `MODX_BASE_URL`, o el ajuste `base_url` cuando está definido | | `session_cookie_domain` | vacío | | `session_cookie_secure` | `false` | | `session_cookie_httponly` | `true` | | `session_cookie_samesite` | vacío | -| `session_cookie_lifetime` | `0` | +| `session_cookie_lifetime` | `604800` (7 días). Un contexto puede guardar `0`, y entonces la cookie dura hasta cerrar el navegador | ## Acceso al contexto -El acceso a un contexto se concede por grupo de usuarios en la pestaña **Contexts** del panel de acceso: el icono del candado en el menú de usuario → **Access Control Lists** → un grupo de usuarios → **Access Permissions** → **Contexts**. +El acceso se concede por grupo de usuarios. Abra el icono del candado en el menú de usuario → **Listas de Control de Acceso** → un grupo de usuarios → **Permisos de Acceso** → **Contextos**. -Una política sobre un contexto decide cuál de las cinco áreas de acceso se aplica: Context, Resource Group, Element Category, Media Source y Namespace. Una política sin área cubre el contexto mismo. +El panel de acceso del grupo de usuarios tiene cinco pestañas: **Contextos**, **Grupos de Recursos**, **Categorías de Elementos**, **Media Sources** y **Namespaces**. La política no elige la pestaña. La plantilla de la política tiene que pertenecer al mismo grupo que la pestaña. -## Leyendo ajustes de contexto +## Leer los ajustes de contexto -Un ajuste del contexto actual se lee como cualquier otro ajuste; el nivel del que procede no es visible para quien lee: +Lea el ajuste del contexto actual como cualquier otro ajuste. La llamada no muestra de qué nivel sale el valor: ``` php [[++my_context_setting]] @@ -74,7 +82,7 @@ Un ajuste del contexto actual se lee como cualquier otro ajuste; el nivel del qu $setting = $modx->getOption('my_context_setting'); ``` -El ajuste de un contexto concreto se lee de ese contexto: +Para un contexto concreto: ``` php $setting = $modx->context->getOption('my_context_setting'); @@ -85,19 +93,18 @@ El idioma de una petición se toma de la primera fuente que tenga valor: 1. el parámetro `cultureKey` de la petición 2. el `cultureKey` de la sesión -3. el `cultureKey` del contexto -4. el ajuste del sistema `cultureKey` +3. el ajuste de usuario `cultureKey` +4. el `cultureKey` del contexto +5. el ajuste del sistema `cultureKey` -El código solo admite en un `cultureKey` los caracteres `A-Z`, `a-z`, `0-9`, `_` y `-`. +Si todas las fuentes están vacías o el valor no pasa el filtro de caracteres, el idioma es `en`. Se admiten `A-Z`, `a-z`, `0-9`, `_` y `-`. En el gestor, después de eso se usa `manager_language`. ## Elegir un contexto durante la petición -Una petición empieza en el contexto que indique la puerta de entrada. Dos mecanismos lo cambian: - -- el archivo `config.context.php` junto a `index.php` — el archivo devuelve la clave del contexto en el que empieza la petición. Ver [Servir un segundo dominio](/current/en/building-sites/contexts/virtual-host); -- un Plugin en el evento `OnHandleRequest` que llame a `switchContext()`. Ver [Uso de un Plugin de puerta](/current/en/building-sites/contexts/gateway-plugin). +Una petición empieza en el contexto que elige la puerta de entrada. -El método que cambia el contexto: +- `config.context.php`, junto a `index.php`, devuelve la clave del contexto donde empieza la petición. Ver [Servir un segundo dominio](building-sites/contexts/virtual-host). +- Un Plugin en `OnHandleRequest` llama a `switchContext()`. Ver [Uso de un Plugin de puerta](building-sites/contexts/gateway-plugin). ``` php if ($modx->switchContext('domain2')) { @@ -105,70 +112,48 @@ if ($modx->switchContext('domain2')) { } ``` -`switchContext($contextKey, $reload = false)` devuelve `false` cuando el contexto no se cargó, así que conviene comprobar el resultado. +`switchContext($contextKey, $reload = false)` devuelve `false` cuando el contexto no se cargó y cuando la clave ya es la actual. En el segundo caso el contexto no se vuelve a cargar. Compruebe el resultado. En una petición que ya está en `domain2`, el ejemplo toma la rama de fallo. -Cambiar el contexto **no** carga un manejador de sesión propio: lo define la puerta de entrada, ver [Uso de un Plugin de puerta](/current/en/building-sites/contexts/gateway-plugin). +Cambiar el contexto durante la petición no carga un manejador de sesión propio. Tampoco cambia el idioma, la configuración regional ni la cookie de sesión. Esos valores salen del contexto con el que arrancó `index.php`. Un dominio con idioma o cookie propios usa un directorio propio con `config.context.php`. Ver [Servir un segundo dominio](building-sites/contexts/virtual-host). ## Eventos | Evento | Cuándo se dispara | | --- | --- | -| `OnContextInit` | se carga un contexto: en cada petición y en cada `switchContext()` | +| `OnContextInit` | se carga un contexto. Un `switchContext()` correcto hacia otro contexto lo carga. La llamada para el contexto que ya es el actual no lo carga | | `OnContextBeforeSave` | antes de guardar un contexto | | `OnContextSave` | después de guardar un contexto | -| `OnContextUpdate` | se actualiza un contexto en el gestor | | `OnContextBeforeRemove` | antes de eliminar un contexto | | `OnContextRemove` | después de eliminar un contexto | -| `OnContextFormPrerender` | antes de dibujar el formulario de un contexto | -| `OnContextFormRender` | después de dibujar el formulario de un contexto | +| `OnContextFormPrerender` | antes de mostrar el formulario del contexto | +| `OnContextFormRender` | después de mostrar el formulario del contexto | -Los eventos de MODX 2 que se citan a menudo en material antiguo — `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` y `OnBeforeRequest` — no existen en MODX 3. +Los eventos de MODX 2 que se citan a menudo en material antiguo no existen en MODX 3: `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` y `OnBeforeRequest`. ## Ajustes del sistema | Ajuste | Valor por defecto | Qué hace | | --- | --- | --- | -| `default_context` | `web` | el contexto en el que se crean los recursos nuevos | +| `default_context` | `web` | el contexto del formulario de creación, salvo cuando el recurso se crea dentro de la rama de otro contexto. La rama del árbol fija el suyo | | `access_context_enabled` | `true` | comprueba el acceso a un contexto en cada petición; desactivarlo ignora todas las reglas de acceso a contextos | | `allow_forward_across_contexts` | `false` | permite que un enlace simbólico y `sendForward()` lleguen a un recurso de otro contexto | -| `cache_context_settings` | `true` | cachea los ajustes de los contextos | +| `cache_context_settings` | `true` | guarda en caché los ajustes de los contextos | | `use_context_resource_table` | `true` | mantiene la tabla de recursos que pertenecen a varios contextos | -| `context_tree_sort` | `true` | ordena los contextos del árbol de recursos por nombre | +| `context_tree_sort` | `true` | activa la ordenación de los contextos del árbol de recursos. El campo lo fija `context_tree_sortby` | | `context_tree_sortby` | `rank` | el campo por el que se ordenan los contextos del árbol | | `context_tree_sortdir` | `ASC` | la dirección de la ordenación | -## Procesadores - -Los procesadores de los contextos y el permiso que necesita cada uno: - -| Procesador | Permiso | -| --- | --- | -| `Context/Create` | `new_context` | -| `Context/Duplicate` | `new_context` | -| `Context/Get` | `view_context` | -| `Context/GetList` | `view_context` | -| `Context/Update` | `edit_context` | -| `Context/UpdateFromGrid` | `edit_context` | -| `Context/Remove` | `delete_context` | -| `Context/Setting/Create` | `settings` | -| `Context/Setting/Get` | `settings` | -| `Context/Setting/GetList` | `settings` | -| `Context/Setting/Remove` | `settings` | -| `Context/Setting/Update` | la política `save` del contexto | - -`Context/Duplicate` copia los ajustes, las reglas de acceso y las fuentes de medios del contexto, y — con `duplicateResources=1` — también sus recursos. - ## Fuentes de medios de un contexto -La fuente de medios de un elemento se puede fijar para un contexto concreto. El elemento usa la fuente de su propio contexto y conserva la fuente por defecto del elemento cuando el contexto no tiene ninguna. +La fuente de medios de un elemento se puede fijar para un contexto. El elemento usa la fuente de su propio contexto. Si el contexto no tiene ninguna, el elemento conserva su fuente por defecto. ## Un recurso en varios contextos -Un recurso pertenece normalmente a un contexto. Con `use_context_resource_table` activada, la tabla `context_resource` guarda los recursos que pertenecen a varios de ellos, y cada recurso así se encuentra en todos los contextos listados. +Un recurso pertenece normalmente a un contexto. Con `use_context_resource_table` activada, la tabla `context_resource` guarda los recursos que pertenecen a varios contextos. Cada recurso así se encuentra en todos los contextos listados. ## Ver también -1. [Servir un segundo dominio](/current/en/building-sites/contexts/virtual-host) -2. [Uso de un Plugin de puerta](/current/en/building-sites/contexts/gateway-plugin) -3. [Ajustes del Sistema](/current/en/building-sites/settings) -4. [Listas de Control de Acceso](/current/en/building-sites/client-proofing/security/policies/acls) +1. [Servir un segundo dominio](building-sites/contexts/virtual-host) +2. [Uso de un Plugin de puerta](building-sites/contexts/gateway-plugin) +3. [Ajustes del Sistema](building-sites/settings) +4. [Listas de Control de Acceso](building-sites/client-proofing/security/policies/acls) diff --git a/ru/building-sites/contexts.md b/ru/building-sites/contexts.md index 2f658d5bf..507b09853 100644 --- a/ru/building-sites/contexts.md +++ b/ru/building-sites/contexts.md @@ -1,71 +1,78 @@ --- title: "Контексты" translation: "building-sites/contexts" -description: "Контексты в MODX: как они переопределяют системные настройки, как создать контекст, как выдаётся доступ к нему, а также API, события и процессоры контекстов." +description: "Контексты в MODX: как они переопределяют системные настройки, как создать контекст и как выдаётся доступ к нему." --- -Контекст — это именованный набор переопределений конфигурации, в котором выполняется запрос: свои настройки, своя ветка дерева ресурсов и свои правила доступа. +Контекст — именованный набор переопределений конфигурации. Запрос выполняется в этом наборе. У него свои настройки, своя ветка дерева ресурсов и свои правила доступа. -В MODX поставляется два контекста — `web` (Website) для фронтенда и `mgr` (Manager) для менеджера. Контекст адресуется **ключом** — значением, которое передаётся в `initialize()` и `switchContext()`. **Имя** — только подпись в интерфейсе. +В поставке MODX два контекста: `web` (Website) для фронтенда и `mgr` (Manager) для менеджера. **Ключ** — значение, которое передаётся в `initialize()` и `switchContext()`. **Имя** — подпись в интерфейсе. ## Создание контекста -Контексты управляются в менеджере: **Admin** (шестерёнка в верхнем меню) → **Contexts** (`?a=context`). Кнопка **Create** открывает форму с четырьмя полями: +Откройте **Админ** (шестерёнка в верхнем меню) → **Контексты**. Кнопка **Создать** открывает форму с четырьмя полями: | Поле | Обязательное | Значение | | --- | --- | --- | -| `key` | да | идентификатор контекста | -| `name` | да | подпись, которая показывается в менеджере и в дереве ресурсов | -| `description` | нет | свободный текст | -| `rank` | нет | порядок контекста в дереве | +| **Ключ контекста** | да | идентификатор контекста | +| **Название** | да | подпись в менеджере и в дереве ресурсов | +| **Описание** | нет | свободный текст | +| **Сортировка** | нет | порядок контекста в дереве | -Ключи `mgr`, `web` и `root` зарезервированы ядром. +Ключи `mgr`, `web` и `root` зарезервированы. Ключ начинается с буквы. Дальше допустимы буквы, цифры, дефис, точка и слэш. Подчёркивание отклоняется, поэтому `domain_2` не сохранится. -Новый контекст сразу получает доступ: группа пользователей **Administrator** — политику *Context*, анонимный пользователь — политику *Load Only*, то есть право `load` и больше ничего. Запись анонимного пользователя видна как **(anonymous)** на вкладке **Access Permissions** контекста, и её удаление там снимает этот доступ. +Новый контекст сразу получает доступ: -Контексты появляются в дереве ресурсов отдельной веткой. Ресурсы переносятся между контекстами перетаскиванием. +- группа пользователей **Administrator** получает политику *Context* +- анонимный пользователь получает политику *Load Only*: право `load` и больше ничего + +Запись анонима видна как **(аноним)** на вкладке **Права доступа** этого контекста. Удалите её там, чтобы снять этот доступ. + +Каждый контекст — отдельная ветка в дереве ресурсов. Перетащите ресурс, чтобы перенести его в другой контекст. + +**Копировать** копирует настройки, правила доступа и источники медиа. В этом окне включён флажок **Копировать ресурсы**, и вместе с ним копируются ресурсы. Снимите флажок, чтобы ресурсы остались на месте. ## Настройки контекста -Настройки контекста переопределяют [системные настройки](building-sites/settings) с тем же именем, а настройки пользователя — настройки контекста. Порядок такой: +Настройка контекста переопределяет [системную настройку](building-sites/settings) с тем же именем. Настройка группы пользователей переопределяет настройку контекста. Настройка пользователя переопределяет настройку группы. ``` -Системная настройка → Настройка контекста → Настройка пользователя +Системная настройка → Настройка контекста → Настройка группы пользователей → Настройка пользователя ``` -Настройка контекста правится на вкладке **Context Settings**: **Contexts** → правый клик по контексту → **Edit**. Смена настройки сбрасывает кэш этого контекста, поэтому очищать кэш вручную не нужно. +Правьте настройку на вкладке **Настройки контекста**: **Контексты** → правый клик по контексту → **Редактировать**. Смена настройки сбрасывает кэш этого контекста. Очищать кэш вручную не нужно. Настройки, которые контекст обычно переопределяет: | Настройка | Что меняет | | --- | --- | -| `base_url` | часть пути в URL контекста | +| `base_url` | путь в адресе контекста | | `http_host` | хост, под который собираются URL | -| `site_url` | полный URL контекста: схема, хост и путь | +| `site_url` | полный адрес контекста: схема, хост и путь | | `site_start` | ресурс, который открывается в контексте | | `cultureKey`, `locale` | язык и локаль запроса | -Настройки сессии настраивают cookie сессии контекста и сохраняют значения ядра, если контекст их не переопределяет: +Эти настройки задают cookie сессии у контекста. Значения ядра сохраняются, если контекст их не переопределяет: | Настройка | Значение по умолчанию | | --- | --- | -| `session_name` | пусто — PHP оставляет своё значение | +| `session_name` | пусто: PHP оставляет своё значение | | `session_cookie_path` | `MODX_BASE_URL` или настройка `base_url`, если она задана | | `session_cookie_domain` | пусто | | `session_cookie_secure` | `false` | | `session_cookie_httponly` | `true` | | `session_cookie_samesite` | пусто | -| `session_cookie_lifetime` | `0` | +| `session_cookie_lifetime` | `604800` (7 суток). Контекст может записать `0`, и тогда cookie живёт до закрытия браузера | ## Доступ к контексту -Доступ к контексту выдаётся группам пользователей на вкладке **Contexts** панели доступа: иконка замка в меню пользователя → **Access Control Lists** → группа пользователей → **Access Permissions** → **Contexts**. +Доступ выдаётся группе пользователей. Откройте иконку замка в меню пользователя → **Контроль доступа** → группа пользователей → **Права доступа** → **Контексты**. -Политика на контексте определяет, какая из пяти областей доступа действует: Context, Resource Group, Element Category, Media Source и Namespace. Политика без области покрывает сам контекст. +В панели доступа у группы пользователей пять вкладок: **Контексты**, **Группы ресурсов**, **Категории элементов**, **Источники файлов** и **Пространства имён**. Политика вкладку не выбирает. Шаблон политики должен относиться к той же группе, что и вкладка. ## Чтение настроек контекста -Настройку текущего контекста читают как любую другую настройку — уровень, с которого она пришла, читателю не виден: +Настройку текущего контекста читают как любую другую. Вызов не показывает, с какого уровня взято значение: ``` php [[++my_context_setting]] @@ -75,7 +82,7 @@ description: "Контексты в MODX: как они переопределя $setting = $modx->getOption('my_context_setting'); ``` -Настройку конкретного контекста читают у этого контекста: +Для конкретного контекста: ``` php $setting = $modx->context->getOption('my_context_setting'); @@ -86,90 +93,67 @@ $setting = $modx->getContext('web')->getOption('my_context_setting'); 1. параметр `cultureKey` запроса 2. `cultureKey` сессии -3. `cultureKey` контекста -4. системная настройка `cultureKey` +3. настройка пользователя `cultureKey` +4. `cultureKey` контекста +5. системная настройка `cultureKey` -Код допускает в `cultureKey` только символы `A-Z`, `a-z`, `0-9`, `_` и `-`. +Если все источники пустые или значение не проходит проверку символов, язык равен `en`. Допустимы `A-Z`, `a-z`, `0-9`, `_` и `-`. В менеджере после этого берётся `manager_language`. ## Выбор контекста во время запроса -Запрос начинается в контексте, который называет гейтвей. Сменить контекст могут два механизма: +Запрос начинается в контексте, который выбирает шлюз. Сменить контекст могут два механизма: -- файл гейтвея `config.context.php` рядом с `index.php` — файл возвращает ключ контекста, в котором начинается запрос. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host); +- файл шлюза `config.context.php` рядом с `index.php`. Файл возвращает ключ контекста, в котором начинается запрос. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host); - плагин на событие `OnHandleRequest`, который вызывает `switchContext()`. См. [Плагин шлюза](building-sites/contexts/gateway-plugin). -Метод, который переключает контекст: - ``` php if ($modx->switchContext('domain2')) { // запрос продолжается в контексте "domain2" } ``` -`switchContext($contextKey, $reload = false)` возвращает `false`, когда контекст не загрузился, поэтому результат стоит проверять. +`switchContext($contextKey, $reload = false)` возвращает `false`, когда контекст не загрузился и когда ключ уже текущий. Во втором случае контекст заново не загружается. Проверяйте результат: на запросе, который уже в `domain2`, пример выше уходит в ветку неудачи. -Переключение контекста **не** подгружает свой session handler — его задаёт гейтвей: см. [Плагин шлюза](building-sites/contexts/gateway-plugin). +Переключение контекста во время запроса не подгружает свой обработчик сессии и не меняет язык, локаль и cookie сессии. Они берутся из контекста, с которого стартовал `index.php`. Домену со своим языком или cookie нужен свой каталог с `config.context.php`. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host). ## События | Событие | Когда вызывается | | --- | --- | -| `OnContextInit` | контекст загружен: на каждом запросе и при каждом `switchContext()` | +| `OnContextInit` | контекст загружен. Успешный `switchContext()` в другой контекст его загружает. Вызов для уже текущего контекста не загружает | | `OnContextBeforeSave` | перед сохранением контекста | | `OnContextSave` | после сохранения контекста | -| `OnContextUpdate` | контекст обновлён в менеджере | | `OnContextBeforeRemove` | перед удалением контекста | | `OnContextRemove` | после удаления контекста | | `OnContextFormPrerender` | до отрисовки формы контекста | | `OnContextFormRender` | после отрисовки формы контекста | -События MODX 2, которые часто встречаются в старых материалах — `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` и `OnBeforeRequest` — в MODX 3 не существуют. +События MODX 2, которые часто называют в старых материалах, в MODX 3 не существуют: `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` и `OnBeforeRequest`. ## Системные настройки | Настройка | Значение по умолчанию | Что делает | | --- | --- | --- | -| `default_context` | `web` | контекст, в котором создаются новые ресурсы | -| `access_context_enabled` | `true` | проверяет доступ к контексту на каждом запросе; отключение игнорирует все правила доступа к контекстам | +| `default_context` | `web` | контекст в форме создания, если ресурс создаётся не внутри ветки другого контекста. Ветка дерева задаёт свой контекст | +| `access_context_enabled` | `true` | проверяет доступ к контексту на каждом запросе. Отключение игнорирует все правила доступа к контекстам | | `allow_forward_across_contexts` | `false` | разрешает символьной ссылке и `sendForward()` доходить до ресурса в другом контексте | | `cache_context_settings` | `true` | кэширует настройки контекстов | | `use_context_resource_table` | `true` | ведёт таблицу ресурсов, принадлежащих нескольким контекстам | -| `context_tree_sort` | `true` | сортирует контексты в дереве ресурсов по названию | +| `context_tree_sort` | `true` | включает сортировку контекстов в дереве ресурсов. Поле задаёт `context_tree_sortby` | | `context_tree_sortby` | `rank` | поле, по которому сортируются контексты дерева | | `context_tree_sortdir` | `ASC` | направление сортировки | -## Процессоры - -Процессоры контекстов и требуемое право для каждого из них: - -| Процессор | Право | -| --- | --- | -| `Context/Create` | `new_context` | -| `Context/Duplicate` | `new_context` | -| `Context/Get` | `view_context` | -| `Context/GetList` | `view_context` | -| `Context/Update` | `edit_context` | -| `Context/UpdateFromGrid` | `edit_context` | -| `Context/Remove` | `delete_context` | -| `Context/Setting/Create` | `settings` | -| `Context/Setting/Get` | `settings` | -| `Context/Setting/GetList` | `settings` | -| `Context/Setting/Remove` | `settings` | -| `Context/Setting/Update` | политика `save` контекста | - -`Context/Duplicate` копирует настройки, правила доступа и источники медиа контекста, а с `duplicateResources=1` — ещё и его ресурсы. - ## Источники медиа контекста -Источник медиа элемента можно задать для отдельного контекста. Элемент берёт источник своего контекста и сохраняет источник элемента по умолчанию, если у контекста источника нет. +Источник медиа элемента можно задать для одного контекста. Элемент берёт источник своего контекста. Если у контекста источника нет, элемент сохраняет свой источник по умолчанию. ## Один ресурс в нескольких контекстах -Обычно ресурс принадлежит одному контексту. Когда включена настройка `use_context_resource_table`, таблица `context_resource` хранит ресурсы, принадлежащие нескольким контекстам, и такой ресурс находится в каждом из указанных. +Обычно ресурс принадлежит одному контексту. Когда включена настройка `use_context_resource_table`, таблица `context_resource` хранит ресурсы, принадлежащие нескольким контекстам. Такой ресурс находится в каждом из указанных контекстов. ## Смотрите также 1. [Использование виртуальных хостов](building-sites/contexts/virtual-host) 2. [Плагин шлюза](building-sites/contexts/gateway-plugin) 3. [Системные настройки](building-sites/settings) -4. [ACL](building-sites/client-proofing/security/policies/acls) +4. [ACL (Список контроля доступа)](building-sites/client-proofing/security/policies/acls) diff --git a/ru/building-sites/contexts/gateway-plugin.md b/ru/building-sites/contexts/gateway-plugin.md index 9c8bb770c..8a15cd9d9 100644 --- a/ru/building-sites/contexts/gateway-plugin.md +++ b/ru/building-sites/contexts/gateway-plugin.md @@ -4,16 +4,16 @@ translation: "building-sites/contexts/gateway-plugin" description: "Несколько доменов с одной установки MODX: плагин, который переключает контекст по хосту, и подход со своим виртуальным хостом и каталогом каждому домену." --- -Одна установка может обслуживать несколько доменов, и различает их контекст запроса. Делают это двумя подходами: +Одна установка может обслуживать несколько доменов. Их различает контекст запроса. Делают это двумя подходами: -- **Один виртуальный хост, несколько доменов.** Каждый домен указывает на один и тот же виртуальный хост, а плагин на `OnHandleRequest` читает хост и переключает контекст. Именно этот подход описан на странице. -- **Свой виртуальный хост и свой каталог каждому домену.** У каждого домена свой виртуальный хост и свой каталог гейтвея со своим `config.context.php`. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host). +- **Один виртуальный хост, несколько доменов.** Каждый домен указывает на один и тот же виртуальный хост. Плагин на `OnHandleRequest` читает хост и переключает контекст. Этот подход описан на странице. +- **Свой виртуальный хост и свой каталог каждому домену.** У каждого домена свой виртуальный хост и свой каталог шлюза со своим `config.context.php`. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host). Первому подходу нужен только плагин. ## Переключение контекста по хосту -Событие `OnHandleRequest` вызывается в начале каждого запроса — и на фронтенде, и в менеджере. Плагин на него читает хост и переключает контекст: +Событие `OnHandleRequest` вызывается в начале каждого запроса, и на фронтенде, и в менеджере. ``` php switchContext('domain2')) { @@ -42,9 +42,11 @@ if (!$modx->switchContext('domain2')) { } ``` +На запросе, который уже в `domain2`, эта проверка тоже не проходит: контекст не переключался. + ## Обработчик сессии -Переключение контекста во время выполнения не подгружает свой session handler: его задаёт гейтвей, и он действует на весь запрос. Контексту с собственным session handler нужен гейтвей своего каталога: см. [Использование виртуальных хостов](building-sites/contexts/virtual-host). +Переключение контекста во время запроса не подгружает свой обработчик сессии. Оно не меняет язык, локаль и cookie сессии. Они берутся из контекста, с которого стартовал `index.php`. Домену со своим языком или cookie нужен свой каталог с `config.context.php`. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host). ## Смотрите также diff --git a/ru/building-sites/contexts/virtual-host.md b/ru/building-sites/contexts/virtual-host.md index 455d03ea6..f57c1f269 100644 --- a/ru/building-sites/contexts/virtual-host.md +++ b/ru/building-sites/contexts/virtual-host.md @@ -4,23 +4,21 @@ translation: "building-sites/contexts/virtual-host" description: "Свой виртуальный хост и свой каталог каждому домену на одной установке MODX: контекст и его настройки, каталог гейтвея со своим config.context.php и виртуальный хост веб-сервера." --- -MODX 3 не сопоставляет хост с контекстом сам. Гейтвей, который начинает запрос, выбирает его контекст, поэтому второму домену нужен второй гейтвей. +MODX 3 не сопоставляет хост с контекстом сам. Шлюз, который начинает запрос, выбирает его контекст, поэтому второму домену нужен второй шлюз. -Здесь описан подход, где у каждого домена свой виртуальный хост и свой каталог на одной машине. Когда несколько доменов указывают на один виртуальный хост, контекст выбирает плагин — см. [Плагин шлюза](building-sites/contexts/gateway-plugin). - -Пример ниже строит такой гейтвей для контекста `dev` на хосте `dev.example.com`. +У каждого домена здесь свой виртуальный хост и свой каталог на одной машине. Когда несколько доменов указывают на один виртуальный хост, контекст выбирает плагин. См. [Плагин шлюза](building-sites/contexts/gateway-plugin). ## Создание контекста -Создайте контекст в менеджере: **Admin** → **Contexts** → **Create**. **Context Key** — это `dev`: именно ключ называет гейтвей, а имя свободное. Ключи `mgr`, `web` и `root` зарезервированы ядром. +Создайте контекст в менеджере: **Админ** → **Контексты** → **Создать**. **Ключ контекста** — `dev`. Ключи `mgr`, `web` и `root` зарезервированы. Ключ начинается с буквы. Дальше допустимы буквы, цифры, дефис, точка и слэш. Подчёркивание отклоняется. -Затем создайте ресурсы домена в ветке контекста. Дерево выглядит так: +Затем создайте ресурсы домена в ветке этого контекста. Дерево выглядит так: ![](subctx1.png) ## Настройки контекста -Четыре настройки на вкладке **Context Settings** контекста определяют, как собираются URL домена: +Четыре настройки на вкладке **Настройки контекста** определяют, как собираются URL домена: | Настройка | Значение | | --- | --- | @@ -29,11 +27,11 @@ MODX 3 не сопоставляет хост с контекстом сам. Г | `site_start` | ID ресурса, который открывает домен | | `site_url` | `http://dev.example.com/` — схема, хост и путь, с косой чертой в конце | -Любую другую настройку здесь тоже можно переопределить — например, `cultureKey` для языка домена. Смена настройки сбрасывает кэш контекста, поэтому очищать кэш вручную не нужно. +Здесь можно переопределить и любую другую настройку. `cultureKey` задаёт язык домена. `session_handler_class` задаёт обработчик сессии этого шлюза. В значение вписывают имя класса. Смена настройки сбрасывает кэш контекста. Очищать кэш вручную не нужно. -## Каталог гейтвея +## Каталог шлюза -Гейтвей — это отдельный каталог с четырьмя файлами: +Шлюз — отдельный каталог с четырьмя файлами: | Файл | Что в нём | | --- | --- | @@ -53,13 +51,13 @@ MODX 3 не сопоставляет хост с контекстом сам. Г return 'dev'; ``` -2. В `config.core.php` — абсолютный путь к ядру установки, установщик пишет его именно так: +2. В `config.core.php` записан абсолютный путь к ядру установки. Так его пишет установщик: ``` php define('MODX_CORE_PATH', '/home/example.com/public_html/core/'); ``` -3. В `.htaccess` нужна одна правка — `RewriteBase` должен указывать на каталог гейтвея: +3. В `.htaccess` нужна одна правка. `RewriteBase` должен указывать на каталог шлюза: ``` RewriteBase /dev/ @@ -67,18 +65,16 @@ MODX 3 не сопоставляет хост с контекстом сам. Г ## Виртуальный хост -Веб-серверу нужен собственный хост на этот каталог. Для Apache 2.4: +Веб-серверу нужен свой хост на этот каталог. Для Apache 2.4: ``` apache ServerName dev.example.com DocumentRoot /home/example.com/public_html/dev - ErrorLog logs/dev-error_log - CustomLog logs/dev-access_log ``` -Перезапустите веб-сервер и откройте `http://dev.example.com/` — ответит ресурс, названный в `site_start`. +Перезапустите веб-сервер и откройте `http://dev.example.com/`. Ответит ресурс, названный в `site_start`. ## Ссылки между контекстами @@ -88,13 +84,13 @@ MODX 3 не сопоставляет хост с контекстом сам. Г [[~135:context=`web`]] ``` -URL получается абсолютным, потому что ресурс лежит в другом контексте. Ссылка без контекста остаётся в контексте запроса и относительная: +URL абсолютный, когда названный контекст не текущий. Ссылка без `context` остаётся относительной, если ресурс принадлежит текущему контексту. Если ресурс принадлежит другому контексту, ссылка становится абсолютным URL контекста, который записан у ресурса: ``` [[~135]] ``` -То же и в PHP: +То же в PHP: ``` php $url = $modx->makeUrl(135, 'web');