diff --git a/en/building-sites/contexts.md b/en/building-sites/contexts.md
index 19a1642bd..d4f9f69eb 100644
--- a/en/building-sites/contexts.md
+++ b/en/building-sites/contexts.md
@@ -1,56 +1,158 @@
---
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, and how access to them is granted."
---
- 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 has 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. The **key** is the value passed to `initialize()` and `switchContext()`. The **name** is a label in 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".
+Open **Admin** (the gear in the top menu) → **Contexts**. **Create** opens a form:
+
+| Field | Required | Meaning |
+| --- | --- | --- |
+| **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. 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 gets access immediately:
+
+- the **Administrator** user group receives the *Context* policy
+- the anonymous user receives the *Load Only* policy: the right `load` and nothing else
- 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 anonymous entry shows as **(anonymous)** on the context's **Access Permissions** tab. Remove that entry to take the access away.
- Note that new contexts don't automatically get "load" permission for Anonymous users in 2.2+ - you'll need to add that in manually.
+Each context is its own branch in the resource tree. Drag a resource to another context.
- When you create a new context besides the default "web" context, you may need to apply context settings to the web context as well.
+**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
- You can create settings for any defined context by clicking on **System -> Contexts**, then right-click any context and select "Update Context".
+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.
- 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 Group setting → User setting
+```
- System Setting -> Context Setting -> User Setting
+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.
-## Context Access
+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 in the context's URLs |
+| `http_host` | the host the URLs are built for |
+| `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 |
-`Security/Permissions -> Edit desired User Group -> Permissions -> Context Access`
+These settings control the context's session cookie. They keep the core values unless the context overrides them:
-## Retrieving Context Settings
+| Setting | Value by 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` | `604800` (7 days). A context can set `0`, and then the cookie lasts until the browser closes |
+
+## Context Access
- 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.
+Access is granted per user group. Open the lock icon in the user menu → **Access Control Lists** → a user group → **Access Permissions** → **Contexts**.
- In a template or Chunk:
+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
+
+Read the current context's setting like any other setting. The call does not show which level supplied the value:
``` php
[[++my_context_setting]]
```
- Programmatically in a Snippet:
-
``` php
$setting = $modx->getOption('my_context_setting');
```
+For a specific context:
+
+``` php
+$setting = $modx->context->getOption('my_context_setting');
+$setting = $modx->getContext('web')->getOption('my_context_setting');
+```
+
+The request language comes from the first source that has a value:
+
+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
+
+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 the gateway chooses. Two mechanisms change that:
+
+- 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')) {
+ // the request continues in the context "domain2"
+}
+```
+
+`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 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. 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 |
+| `OnContextBeforeRemove` | before a context is removed |
+| `OnContextRemove` | after a context is removed |
+| `OnContextFormPrerender` | before a context form is rendered |
+| `OnContextFormRender` | after a context form is rendered |
+
+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 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 context settings |
+| `use_context_resource_table` | `true` | keeps the table of resources that belong to several contexts |
+| `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 |
+
+## Media Sources of a Context
+
+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` on, the `context_resource` table stores resources that belong to several contexts. MODX finds such a resource in each listed context.
+
## 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. [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. [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 672be346a..6929df6f0 100644
--- a/en/building-sites/contexts/gateway-plugin.md
+++ b/en/building-sites/contexts/gateway-plugin.md
@@ -1,48 +1,55 @@
---
-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: the Plugin that switches the context by host, and the approach with a virtual host and a directory for every domain."
---
-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 request's context tells them apart. Two approaches do that:
+
+- **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 only the Plugin.
+
+## Switching the Context by Host
+
+`OnHandleRequest` fires at the start of every request, on the front end and in the manager.
``` 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 `return` keeps the manager in the `mgr` context.
+
+`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 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
+On a request that is already in `domain2`, that check also fails, because the context was not switched.
-``` php
-$modx->initialize('aContextNameOfYourChoice');
-```
+## The Session Handler
-Note that you could also just copy the index.php in the same directory and rename it to do this, but your rewrite rules would have to be smart enough to route requests to the appropriate context gateway, and you would need to configure the `request_controller` option in Context Settings appropriately.
+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).
-You can also still use a custom core location in either of these scenarios; this is independent of the context-driven multi-site capabilities.
+## See Also
-Checkout the [GatewayManager component](extras/gatewaymanager)
+1. [Contexts](building-sites/contexts)
+2. [Using Virtual Hosts](building-sites/contexts/virtual-host)
+3. [OnHandleRequest](extending-modx/plugins/system-events/onhandlerequest)
+4. [GatewayManager](extras/gatewaymanager)
diff --git a/en/building-sites/contexts/virtual-host.md b/en/building-sites/contexts/virtual-host.md
index aaac8b355..049b9e657 100644
--- a/en/building-sites/contexts/virtual-host.md
+++ b/en/building-sites/contexts/virtual-host.md
@@ -1,120 +1,102 @@
---
title: "Using Virtual Hosts"
-_old_id: "352"
-_old_uri: "2.x/administering-your-site/contexts/creating-a-subdomain-from-a-folder-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."
---
-This tutorial will demonstrate how to use a Context to create and manage a separate subdomain in a single Revolution install. We're going to create a subdomain at dev.modx.com (of course, not really, but you get the idea).
+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.
-## Creating the Context
+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).
-Navigate to System -> 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 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.
-Your tree should look something like this:
+Then create the domain's resources in the context's branch. The tree looks like this:

-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:
-
-- **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**
+## Context Settings
-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.
+Four settings on the context's **Context Settings** tab decide how the domain's URLs are built:
-**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.
+| 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/` — scheme, host and path, with a trailing slash |
-After creating the settings, clear your site cache.
+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.
-## Creating the Virtual Host
+## The Gateway Directory
-**cPanel Users**
-cPanel will make the necessary changes automatically when you create a new sub domain. Manually editing the Virtual Hosts is not recommended.
+The gateway is its own directory with four files:
-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:
+| File | What it holds |
+| --- | --- |
+| `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` |
-``` 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
-
-```
+The three copies point at the same core and the same database. Only the context differs between the directories.
-Some Apache installs prefer you to put the IP address of the server in the VirtualHost and NameVirtualHost parameters - this is fine; the important field is the ServerName.
+`index.php` works as it is. Set up the other three files as follows:
-Obviously, if you're creating a different subdomain than dev.modxcms.com, you'd want to change these values.
+1. `config.context.php` holds one line:
-Great! Restart your server (apachectl graceful).
+ ``` php
+ initialize('web');
+``` apache
+
+ ServerName dev.example.com
+ DocumentRoot /home/example.com/public_html/dev
+
```
-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 Contexts
-You'll only need to edit one line here (and maybe not at all). Find this line (near the top):
+A link to another context's resource 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 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:
-``` 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/contexto-2.png b/es/building-sites/contexto-2.png
deleted file mode 100644
index b46671b01..000000000
Binary files a/es/building-sites/contexto-2.png and /dev/null differ
diff --git a/es/building-sites/contextos.png b/es/building-sites/contextos.png
deleted file mode 100644
index 6cd0b9f90..000000000
Binary files a/es/building-sites/contextos.png and /dev/null differ
diff --git a/es/building-sites/contexts.md b/es/building-sites/contexts.md
index f42c44ea9..a28add79c 100644
--- a/es/building-sites/contexts.md
+++ b/es/building-sites/contexts.md
@@ -1,65 +1,159 @@
---
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 y cómo se concede el acceso."
+translation: "building-sites/contexts"
---
- 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. 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.
- 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.
+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.
- 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.
+## Crear un contexto
-## Creando un contexto
+Abra **Administrador** (el engranaje del menú superior) → **Contextos**. **Crear** abre un formulario:
- 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_).
-
- 
-
- 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).
-
- 
-
- 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".
-
+| Campo | Obligatorio | Significado |
+| --- | --- | --- |
+| **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 |
- 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).
+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.
- 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.
+Un contexto nuevo recibe acceso de inmediato:
-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.
+- 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
-## Configuraciones de contexto
+La entrada del anónimo aparece como **(anónimo)** en la pestaña **Permisos de Acceso** del contexto. Quítela para retirar ese acceso.
- 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".
+Cada contexto es una rama propia en el árbol de recursos. Arrastre un recurso a otro 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:
+**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.
- Configuración del sistema -> Configuración del contexto -> Configuración del usuario
+## Ajustes de contexto
-## Acceso al contexto
+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 grupo de usuarios → Ajuste del usuario
+```
+
+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.
+
+Ajustes que un contexto suele anular:
+
+| Ajuste | Qué cambia |
+| --- | --- |
+| `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 |
+
+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_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` | `604800` (7 días). Un contexto puede guardar `0`, y entonces la cookie dura hasta cerrar el navegador |
-Al crear un nuevo contexto, asegúrate de que los grupos de usuarios que quieras tengan acceso a él:
+## Acceso al contexto
-`Sistema -> Listas de Control de Acceso -> Actualizar Grupo de Usuarios deseado -> Permisos -> Acceso a Contextos`
+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**.
-## Recuperando configuraciones de contexto
+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.
- 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).
+## Leer los ajustes de contexto
- En una plantilla o Chunk:
+Lea el ajuste del contexto actual como cualquier otro ajuste. La llamada no muestra de qué nivel sale el valor:
``` php
[[++my_context_setting]]
```
- Programáticamente en un Snippet:
-
``` php
$setting = $modx->getOption('my_context_setting');
```
+Para un contexto concreto:
+
+``` 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:
+
+1. el parámetro `cultureKey` de la petición
+2. el `cultureKey` de la sesión
+3. el ajuste de usuario `cultureKey`
+4. el `cultureKey` del contexto
+5. el ajuste del sistema `cultureKey`
+
+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 elige la puerta de entrada.
+
+- `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')) {
+ // la petición continúa en el contexto "domain2"
+}
+```
+
+`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 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. 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 |
+| `OnContextBeforeRemove` | antes de eliminar un contexto |
+| `OnContextRemove` | después de eliminar 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 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 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` | 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` | 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 |
+
+## Fuentes de medios de un contexto
+
+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 contextos. 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](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 439ee551c..507b09853 100644
--- a/ru/building-sites/contexts.md
+++ b/ru/building-sites/contexts.md
@@ -1,55 +1,159 @@
---
title: "Контексты"
translation: "building-sites/contexts"
+description: "Контексты в MODX: как они переопределяют системные настройки, как создать контекст и как выдаётся доступ к нему."
---
-Контексты позволяют переопределять, расширять, изолировать или совместно использовать настройки MODX между доменами, поддоменами, мультисайтами, языковыми версиями, специфическими веб-приложениями и т.п.
+Контекст — именованный набор переопределений конфигурации. Запрос выполняется в этом наборе. У него свои настройки, своя ветка дерева ресурсов и свои правила доступа.
-Вы можете легко создать контекст через меню "Контексты". Контекст появится в вашем дереве ресурсов. Ресурсы можно легко перемещать из одного контекста в другой перетаскиванием.
-
-Примечание: нет принципиальных _различий_ в ресурсах, расположенных в разных контекстах, кроме того, что они теперь наследуют настройки контекста, в котором они находятся. Поэтому, если вы создаете новый контекст, вам придется переопределить настройки контекста, чтобы изменения применились.
+В поставке MODX два контекста: `web` (Website) для фронтенда и `mgr` (Manager) для менеджера. **Ключ** — значение, которое передаётся в `initialize()` и `switchContext()`. **Имя** — подпись в интерфейсе.
## Создание контекста
-Сначала перейдите на страницу "Контексты" через "Система" -> "Контексты". Затем нажмите "Создать новый". Форма попросит ввести ключ и описание. Далее нажмите правой кнопкой мыши по созданному контексту и выберите "Обновить контекст".
+Откройте **Админ** (шестерёнка в верхнем меню) → **Контексты**. Кнопка **Создать** открывает форму с четырьмя полями:
+
+| Поле | Обязательное | Значение |
+| --- | --- | --- |
+| **Ключ контекста** | да | идентификатор контекста |
+| **Название** | да | подпись в менеджере и в дереве ресурсов |
+| **Описание** | нет | свободный текст |
+| **Сортировка** | нет | порядок контекста в дереве |
+
+Ключи `mgr`, `web` и `root` зарезервированы. Ключ начинается с буквы. Дальше допустимы буквы, цифры, дефис, точка и слэш. Подчёркивание отклоняется, поэтому `domain_2` не сохранится.
+
+Новый контекст сразу получает доступ:
+
+- группа пользователей **Administrator** получает политику *Context*
+- анонимный пользователь получает политику *Load Only*: право `load` и больше ничего
-Вы перейдете в окно контекста с пустым списком настроек. Отсюда вы можете добавить контекстно-зависимые настройки, которые будут переопределять любые настройки системы. Ваш новый контекст будет полностью пустым, и вам потребуется указать все настройки, которые вы будете использовать.
+Запись анонима видна как **(аноним)** на вкладке **Права доступа** этого контекста. Удалите её там, чтобы снять этот доступ.
-Обратите внимание, что новые контексты не получают автоматически разрешение "load" для анонимных пользователей в версии 2.2+ - вам нужно добавить это вручную.
+Каждый контекст — отдельная ветка в дереве ресурсов. Перетащите ресурс, чтобы перенести его в другой контекст.
-Когда вы создаете новый контекст, помимо стандартного контекста "web", вам может потребоваться применить настройки и к контексту "web".
+**Копировать** копирует настройки, правила доступа и источники медиа. В этом окне включён флажок **Копировать ресурсы**, и вместе с ним копируются ресурсы. Снимите флажок, чтобы ресурсы остались на месте.
## Настройки контекста
-Вы можете создать настройки для любого определенного контекста, нажав **Система -> Контексты**, затем нажмите правой кнопкой мыши любой контекст и выберите "Обновить контекст".
+Настройка контекста переопределяет [системную настройку](building-sites/settings) с тем же именем. Настройка группы пользователей переопределяет настройку контекста. Настройка пользователя переопределяет настройку группы.
-Каждый контекст может иметь свои собственные настройки, которые переопределяют или расширяют [Системные настройки](building-sites/settings "Системные настройки"). Настройки контекста, в свою очередь, могут быть переопределены или расширены с помощью [Настройки пользователя](administering-your-site/security/users#Users-UsersUserSettings). Иерархия такова:
+```
+Системная настройка → Настройка контекста → Настройка группы пользователей → Настройка пользователя
+```
-Системные настройки -> Настройка контекста -> Настройка пользователя
+Правьте настройку на вкладке **Настройки контекста**: **Контексты** → правый клик по контексту → **Редактировать**. Смена настройки сбрасывает кэш этого контекста. Очищать кэш вручную не нужно.
-## Доступ к контексту
+Настройки, которые контекст обычно переопределяет:
-При создании нового контекста убедитесь, что нужные группы пользователей имеют к нему доступ:
+| Настройка | Что меняет |
+| --- | --- |
+| `base_url` | путь в адресе контекста |
+| `http_host` | хост, под который собираются URL |
+| `site_url` | полный адрес контекста: схема, хост и путь |
+| `site_start` | ресурс, который открывается в контексте |
+| `cultureKey`, `locale` | язык и локаль запроса |
-`Контроль доступа -> Изменить нужную группу пользователей -> Права доступа -> Доступ к контексту`
+Эти настройки задают 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` | `604800` (7 суток). Контекст может записать `0`, и тогда cookie живёт до закрытия браузера |
+
+## Доступ к контексту
-Получение настройки контекста ничем не отличается от получения любой другой настройки системы. Фактически, вы можете не знать, что данный параметр устанавливается на уровне системы или контекста (или на уровне пользователя).
+Доступ выдаётся группе пользователей. Откройте иконку замка в меню пользователя → **Контроль доступа** → группа пользователей → **Права доступа** → **Контексты**.
-В шаблоне или чанке:
+В панели доступа у группы пользователей пять вкладок: **Контексты**, **Группы ресурсов**, **Категории элементов**, **Источники файлов** и **Пространства имён**. Политика вкладку не выбирает. Шаблон политики должен относиться к той же группе, что и вкладка.
+
+## Чтение настроек контекста
+
+Настройку текущего контекста читают как любую другую. Вызов не показывает, с какого уровня взято значение:
``` 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');
+```
+
+Язык запроса берётся из первого источника, где есть значение:
+
+1. параметр `cultureKey` запроса
+2. `cultureKey` сессии
+3. настройка пользователя `cultureKey`
+4. `cultureKey` контекста
+5. системная настройка `cultureKey`
+
+Если все источники пустые или значение не проходит проверку символов, язык равен `en`. Допустимы `A-Z`, `a-z`, `0-9`, `_` и `-`. В менеджере после этого берётся `manager_language`.
+
+## Выбор контекста во время запроса
+
+Запрос начинается в контексте, который выбирает шлюз. Сменить контекст могут два механизма:
+
+- файл шлюза `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`, когда контекст не загрузился и когда ключ уже текущий. Во втором случае контекст заново не загружается. Проверяйте результат: на запросе, который уже в `domain2`, пример выше уходит в ветку неудачи.
+
+Переключение контекста во время запроса не подгружает свой обработчик сессии и не меняет язык, локаль и cookie сессии. Они берутся из контекста, с которого стартовал `index.php`. Домену со своим языком или cookie нужен свой каталог с `config.context.php`. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host).
+
+## События
+
+| Событие | Когда вызывается |
+| --- | --- |
+| `OnContextInit` | контекст загружен. Успешный `switchContext()` в другой контекст его загружает. Вызов для уже текущего контекста не загружает |
+| `OnContextBeforeSave` | перед сохранением контекста |
+| `OnContextSave` | после сохранения контекста |
+| `OnContextBeforeRemove` | перед удалением контекста |
+| `OnContextRemove` | после удаления контекста |
+| `OnContextFormPrerender` | до отрисовки формы контекста |
+| `OnContextFormRender` | после отрисовки формы контекста |
+
+События MODX 2, которые часто называют в старых материалах, в MODX 3 не существуют: `OnContextSwitch`, `OnSiteInit`, `OnSiteRender`, `OnManagerInit` и `OnBeforeRequest`.
+
+## Системные настройки
+
+| Настройка | Значение по умолчанию | Что делает |
+| --- | --- | --- |
+| `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` |
+| `context_tree_sortby` | `rank` | поле, по которому сортируются контексты дерева |
+| `context_tree_sortdir` | `ASC` | направление сортировки |
+
+## Источники медиа контекста
+
+Источник медиа элемента можно задать для одного контекста. Элемент берёт источник своего контекста. Если у контекста источника нет, элемент сохраняет свой источник по умолчанию.
+
+## Один ресурс в нескольких контекстах
+
+Обычно ресурс принадлежит одному контексту. Когда включена настройка `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..8a15cd9d9 100644
--- a/ru/building-sites/contexts/gateway-plugin.md
+++ b/ru/building-sites/contexts/gateway-plugin.md
@@ -1,47 +1,56 @@
---
-title: "Использование плагина GatewayManager"
+title: "Использование плагина шлюза"
translation: "building-sites/contexts/gateway-plugin"
+description: "Несколько доменов с одной установки MODX: плагин, который переключает контекст по хосту, и подход со своим виртуальным хостом и каталогом каждому домену."
---
-У вас есть выбор при совместном использовании одной базы данных и менеджера в нескольких доменах. Вы можете использовать первичный интерфейсный интерфейс (известный как «web») для обработки всех доменов, или вы можете создать уникальный файл шлюза для каждого домена, чтобы напрямую инициализировать определенный контекст. Если вы используете один шлюз, вы бы использовали плагин для переключения контекстов, зарегистрированных в событии `OnHandleRequest`, что-то вроде этого:
+Одна установка может обслуживать несколько доменов. Их различает контекст запроса. Делают это двумя подходами:
+
+- **Один виртуальный хост, несколько доменов.** Каждый домен указывает на один и тот же виртуальный хост. Плагин на `OnHandleRequest` читает хост и переключает контекст. Этот подход описан на странице.
+- **Свой виртуальный хост и свой каталог каждому домену.** У каждого домена свой виртуальный хост и свой каталог шлюза со своим `config.context.php`. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host).
+
+Первому подходу нужен только плагин.
+
+## Переключение контекста по хосту
+
+Событие `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 для правил перезаписи, измененных соответствующим образом) в другой каталог и измените строку
+Этот `return` оставляет менеджер в контексте `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.');
+}
```
-в
+На запросе, который уже в `domain2`, эта проверка тоже не проходит: контекст не переключался.
-``` php
-$modx->initialize('aContextNameOfYourChoice');
-```
+## Обработчик сессии
-Обратите внимание, что вы также можете просто скопировать `index.php` в тот же каталог и переименовать его, чтобы сделать это, но ваши правила перезаписи должны быть достаточно умными, чтобы направлять запросы в соответствующий контекстный шлюз, и вам нужно будет настроить запрос `request_controller` в контекстных настройках соответственно.
+Переключение контекста во время запроса не подгружает свой обработчик сессии. Оно не меняет язык, локаль и cookie сессии. Они берутся из контекста, с которого стартовал `index.php`. Домену со своим языком или cookie нужен свой каталог с `config.context.php`. См. [Использование виртуальных хостов](building-sites/contexts/virtual-host).
-Вы также можете использовать пользовательское расположение ядра в любом из этих сценариев; это не зависит от контекстно-управляемых многосайтовых возможностей.
+## Смотрите также
-Ознакомьтесь с компонентом [GatewayManager](extras/gatewaymanager)
+1. [Контексты](building-sites/contexts)
+2. [Использование виртуальных хостов](building-sites/contexts/virtual-host)
+3. [OnHandleRequest](extending-modx/plugins/system-events/onhandlerequest)
+4. [GatewayManager](extras/gatewaymanager)
diff --git a/ru/building-sites/contexts/virtual-host.md b/ru/building-sites/contexts/virtual-host.md
index 6d10930f4..f57c1f269 100644
--- a/ru/building-sites/contexts/virtual-host.md
+++ b/ru/building-sites/contexts/virtual-host.md
@@ -1,120 +1,103 @@
---
title: "Использование виртуальных хостов"
translation: "building-sites/contexts/virtual-host"
+description: "Свой виртуальный хост и свой каталог каждому домену на одной установке MODX: контекст и его настройки, каталог гейтвея со своим config.context.php и виртуальный хост веб-сервера."
---
-Из этого туториала вы узнаете, как использовать Контекст для создания и управления отдельным поддоменом в одной установке Revolution. Мы собираемся создать поддомен на dev.modx.com (конечно, не совсем, но вы поняли идею).
+MODX 3 не сопоставляет хост с контекстом сам. Шлюз, который начинает запрос, выбирает его контекст, поэтому второму домену нужен второй шлюз.
-## Создание контекста
+У каждого домена здесь свой виртуальный хост и свой каталог на одной машине. Когда несколько доменов указывают на один виртуальный хост, контекст выбирает плагин. См. [Плагин шлюза](building-sites/contexts/gateway-plugin).
-Перейдите в Система -> Контексты. Нажмите _Создать новый_, чтобы создать новый контекст. Дайте ему имя "dev" и нажмите _Сохранить_.
+## Создание контекста
-Затем в дереве ресурсов (слева) создайте ресурс "Dev Home". Поместите его в корень контекста «dev». Кроме того, пока вы это делаете, создайте ресурс "Dev Docs" с псевдонимом "документация". Мы будем использовать это для проверки наших контекстных ссылок.
+Создайте контекст в менеджере: **Админ** → **Контексты** → **Создать**. **Ключ контекста** — `dev`. Ключи `mgr`, `web` и `root` зарезервированы. Ключ начинается с буквы. Дальше допустимы буквы, цифры, дефис, точка и слэш. Подчёркивание отклоняется.
-Ваше дерево должно выглядеть примерно так:
+Затем создайте ресурсы домена в ветке этого контекста. Дерево выглядит так:

-Оттуда идите вперед и щелкните правой кнопкой мыши на контексте «dev» в дереве и нажмите «Изменить контекст». Отсюда мы увидим вкладку Настройки контекста. Нажмите на нее, и вам нужно будет добавить несколько настроек:
-
-- **base\_url** - Установите это в "**/**" (без кавычек), так как мы указываем корень URL нашей базы.
-- **http\_host** - Установите это в **dev.modxcms.com** (или ваше имя поддомена)
-- **site\_start** - Установите это **Идентификатор вашего ресурса "Dev Home"**.
-- **site\_url** - Установите это в **** (или ваш поддомен URL). Не забывайте **_косую черту_**. Помните, что этот параметр: **scheme + _http\_host_ + base\_url**
-
-Вы можете добавить другие специфичные для контекста настройки, такие как error\_page, unauthorized\_page, cultureKey и другие, если вы того пожелаете. Все системные настройки могут быть переопределены путем установки их в контексте.
-
-**Примечание: СВЯЗЬ МЕЖДУ КОНТЕКСТАМИ**
-Если вы собираетесь **ссылаться на контекст «web» из этого контекста («dev»)**, вам нужно **добавить те же самые настройки контекста (со значениями, специфичными для web), конечно) в контексте «сети»**. Это позволяет MODX знать, куда перенаправлять URL-адреса веб-контекста.
-
-После создания настроек очистите кеш сайта.
+## Настройки контекста
-## Создание виртуального хоста
+Четыре настройки на вкладке **Настройки контекста** определяют, как собираются URL домена:
-### Пользователи cPanel
+| Настройка | Значение |
+| --- | --- |
+| `base_url` | `/` |
+| `http_host` | `dev.example.com` |
+| `site_start` | ID ресурса, который открывает домен |
+| `site_url` | `http://dev.example.com/` — схема, хост и путь, с косой чертой в конце |
-cPanel автоматически внесет необходимые изменения при создании нового субдомена. Редактирование виртуальных хостов вручную не рекомендуется.
+Здесь можно переопределить и любую другую настройку. `cultureKey` задаёт язык домена. `session_handler_class` задаёт обработчик сессии этого шлюза. В значение вписывают имя класса. Смена настройки сбрасывает кэш контекста. Очищать кэш вручную не нужно.
-Теперь нам нужно немного поработать с Apache. (Если вы не используете Apache, вы можете, по крайней мере, следовать той же идее и настроить ее на своем сервере.) Перейдите в файл Apache httpd.conf и добавьте эти строки, меняя их, где необходимо, для вашего доменного имени:
+## Каталог шлюза
-``` 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
-
-```
+Шлюз — отдельный каталог с четырьмя файлами:
-Некоторые установки Apache предпочитают указывать IP-адрес сервера в параметрах VirtualHost и NameVirtualHost - это нормально; Важное поле - имя сервера.
+| Файл | Что в нём |
+| --- | --- |
+| `index.php` | копия `index.php` из установки |
+| `config.context.php` | ключ контекста |
+| `config.core.php` | копия `config.core.php` из установки |
+| `.htaccess` | копия `.htaccess` из установки |
-Очевидно, что если вы создаете субдомен, отличный от dev.modxcms.com, вам нужно изменить эти значения.
+Три копии указывают на одно и то же ядро и на одну и ту же базу. Между каталогами различается только контекст.
-Большой! Перезагрузите свой сервер (apachectl).
+`index.php` работает как есть. Остальные три файла настраиваются так:
-## Файлы поддоменов
+1. В `config.context.php` одна строка:
-Теперь нам нужно создать реальные файлы для загрузки поддоменов. Перейдите к созданию подкаталога «dev /» в `/home/modxcms.com/public_html/` (или любом другом базовом пути, в котором находится ваш webroot).
+ ``` php
+ initialize('web');
+``` apache
+
+ ServerName dev.example.com
+ DocumentRoot /home/example.com/public_html/dev
+
```
-Измените «web» на «dev». Сохраните файл и закройте.
+Перезапустите веб-сервер и откройте `http://dev.example.com/`. Ответит ресурс, названный в `site_start`.
-#### .htaccess
+## Ссылки между контекстами
-Вам нужно будет отредактировать только одну строку здесь (и, возможно, не совсем). Найдите эту строку (в начале):
+Ссылка на ресурс другого контекста называет этот контекст:
-``` php
-RewriteBase /
+```
+[[~135:context=`web`]]
```
-Убедитесь, что установлено значение /, а не что-либо еще. Он должен соответствовать настройке контекста **base\_url**, которую вы установили ранее.
-
-#### config.core.php
-
-Здесь действительно важно убедиться, что эта строка указывает на вашу основную папку MODX:
+URL абсолютный, когда названный контекст не текущий. Ссылка без `context` остаётся относительной, если ресурс принадлежит текущему контексту. Если ресурс принадлежит другому контексту, ссылка становится абсолютным 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)