MODX рдХреНрд░рд╛рдВрддрд┐ рдореЗрдВ рдПрдХ рдирдпрд╛ рдЯреИрдЧ рдЬреЛрдбрд╝реЗрдВ

рдпрд╣ рд╡рд┐рд╖рдп MODX рдХреНрд░рд╛рдВрддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд▓рдЧрдЗрди рдмрдирд╛рдиреЗ рдореЗрдВ рдореЗрд░реЗ рдЕрдиреБрднрд╡ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЗрд╕ CMS рдореЗрдВ рдПрдХ рдирдпрд╛ рдЯреИрдЧ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдореБрдЭреЗ рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рдирд╛ рд╣реИ рдХрд┐ рдПрдХ рдбреЗрд╡рд▓рдкрд░ рдЕрдкрдиреА рд╕рд╛рдЗрдЯ рдХреА рд╕рд╛рдордЧреНрд░реА рд╕рд╛рдордЧреНрд░реА рдореЗрдВ рдпрд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдФрд░ рд╡рд┐рдЦрдВрдбреВ рдореЗрдВ рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, [[* рдкреЗрдЬреЗрдЯрд┐рдЯреЗрд▓]] рдЯреИрдЧ MODX рдкрд╛рд░реНрд╕рд░ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЙрд╕ рдкреГрд╖реНрда рдХрд╛ рд╢реАрд░реНрд╖рдХ рд▓реМрдЯрд╛рдПрдЧрд╛ рдЬрд┐рд╕ рдкрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдерд┐рдд рд╣реИред

рдЯреИрдЧ рдХреА рд╡реНрдпрд╛рдкрдХ рд╕реВрдЪреА рдХреЗ рдмреАрдЪ, рдореБрдЭреЗ рдПрдХ рдФрд░ рдЪреАрдЬрд╝ рдХреА рдХрдореА рдереА - рдХрд┐рд╕реА рднреА рдЪрдпрдирд┐рдд рд╕рдВрд╕рд╛рдзрди рдХреЗ рдХреНрд╖реЗрддреНрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ MODX рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ getResourceField рд╕реНрдирд┐рдкреЗрдЯ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдФрд░ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЕрд╕реБрд╡рд┐рдзрд╛ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рд╕рдорд╛рдзрд╛рди рд╕реАрдПрдордПрд╕ рдХреА рдореВрд▓ рдбрд┐рд▓реАрд╡рд░реА рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рдореЗрдВ рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдПрдХ рдирд╛рдо рдмрд╣реБрдд рд▓рдВрдмрд╛ рд╣реИ, рдЗрд╕ рддрдереНрдп рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЖрдкрдХреЛ рдЖрд░рдЯреАрдПрдлрдПрдо рдХреЛ рдЦреБрд▓рд╛ рд░рдЦрдирд╛ рд╣реИ рддрд╛рдХрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдирд╛рдореЛрдВ рдХреЛ рднреНрд░рдорд┐рдд рди рдХрд░реЗрдВред рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдлрд╛рд╕реНрдЯрдлрд┐рд▓реНрдб рдкреНрд▓рдЧрдЗрди рд▓рд┐рдЦрд╛, рдЬрд┐рд╕ рдкрд░ рдмрд╛рдж рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреАред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдпрд╣ рддрдп рдХрд░рдирд╛ рдерд╛ рдХрд┐ рдЖрдк рдХрд┐рди рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдкреНрд▓рдЧрдЗрди рдХреЛ рд▓рдЯрдХрд╛ рджреЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ MODX рд╕рд┐рд╕реНрдЯрдо рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣рд╛рдВ рдкреНрд▓рдЧрдЗрди рдРрдб-рдСрди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдХреБрдЫ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдИрд╡реЗрдВрдЯ рдкрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рд╕рд┐рд╕реНрдЯрдо рдИрд╡реЗрдВрдЯ рдХреА рдмрдбрд╝реА рд╕реВрдЪреА рд╕реЗ, рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдХреЗрд╡рд▓ OnParseDocument рдИрд╡реЗрдВрдЯ рдЙрдкрдпреБрдХреНрдд рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ modParser рдХреНрд▓рд╛рд╕ (рдлрд╝рд╛рдЗрд▓ рдХреЛрд░ / рдореЙрдбрд▓ / modx / modparser.class.php) рдХреЗ processElementTags () рд╡рд┐рдзрд┐ рдореЗрдВ MODX рдкрд╛рд░реНрд╕рд░ рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрд╕рдХреЗ рдмрд╛рдж, рдХреЛрдИ рднреА рдШрдЯрдирд╛ рд╣рдорд╛рд░реЗ рдЯреИрдЧ рдХреЗ рд╕рд╛рде рд╕рд╛рдордЧреНрд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕рднреА рдЧреИрд░-рдореМрдЬреВрдж рдХреЗ рд░реВрдк рдореЗрдВ рдХрдЯ рдЬрд╛рдПрдВрдЧреЗред
рдкреНрд▓рдЧрдЗрди рдХрд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕рдВрд╕реНрдХрд░рдг рдмрд╣реБрдд рд╕рд░рд▓ рдерд╛:

$content = $modx->documentOutput; $pattern = '@\[\[#(\d+)\.(.+?)\]\]@si'; if (preg_match($pattern, $content, $matches) > 0) { $tag = $matches[0]; $resource_id = $matches[1]; $resource_field = explode('.', $matches[2]); $resource = $modx->getObject('modResource', $resource_id); if (count($resource_field) == 1) { $value = $resource->get($resource_field[0]); } else { if ($resource_field[0] == 'tv' && isset($resource_field[1])) { $value = $resource->getTVValue($resource_field[1]); } elseif (in_array($resource_field[0], array('properties', 'property', 'prop'))) { $value = $resource->getProperty($resource_field[2], $resource_field[1]); } else { $value = ''; } } $modx->documentOutput = str_replace($tag, $value, $content); } 

рдХрд╛рд░реНрдп рдкреНрд░рдкрддреНрд░ [[# 10.pagetitle]], [[# 10.tv.MyTV]] рдХреЗ рдЯреИрдЧ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдерд╛ред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рд╣реЛ рдЧрдИ рдереА, рд▓реЗрдХрд┐рди рдЦреЗрддреЛрдВ рдореЗрдВ I / O рдлрд╝рд┐рд▓реНрдЯрд░ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рдерд╛ред
рдЗрд╕рд▓рд┐рдП, рдореБрдЭреЗ рдпрд╣ рд╕рдордЭрдиреЗ рдореЗрдВ рдмреЗрд╣рддрд░ рдерд╛ рдХрд┐ рдЯреИрдЧ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╕рдордп рдкрд╛рд░реНрд╕рд░ рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИред рдФрд░ рд╡рд╣ рдирд┐рдореНрди рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред
рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рднреА рдЯреИрдЧ рдПрдХрддреНрд░ рдХрд░рддрд╛ рд╣реИ
 public function collectElementTags($origContent, array &$matches, $prefix= '[[', $suffix= ']]') 

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЯреИрдЧ 2 рддрддреНрд╡реЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЗ рд░реВрдк рдореЗрдВ рд▓реМрдЯрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ - рдПрдХ рдмрд╛рд╣рд░реА рдЯреИрдЧ рдФрд░ рдПрдХ рдЖрдВрддрд░рд┐рдХред рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдирдП рдЯреИрдЧ рдореЗрдВ рдПрдХ рдЯреИрдЧ рдХреА рд╕рднреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдЗрд╕реЗ рднреА рд▓реМрдЯрд╛ рджреЗрдЧрд╛ред рдЗрд╕рдХреЗ рдмрд╛рдж, $ tagMap рд╕рд░рдгреА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдлрд╝реЙрд░реНрдо рдЯреИрдЧ => рд╕рдВрд╕рд╛рдзрд┐рдд рдЯреИрдЧ рдХреЗ str_replace рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреА рд╕реВрдЪреА рд╣реЛрддреА рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдЯреИрдЧ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╕рдордп, рдкрд╛рд░реНрд╕рд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ
 public function processTag($tag, $processUncacheable = true) 

рдЬрд┐рд╕рдореЗрдВ рдЯреИрдЧ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: рдПрдХ рдЯреЛрдХрди (рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреИрдЧ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдкреНрд░рддреАрдХ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП * рд╕рдВрд╕рд╛рдзрди рдлрд╝реАрд▓реНрдб рдХреЗ рд▓рд┐рдП рдпрд╛ ~ рд▓рд┐рдВрдХ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдПрдХ рдкрд╛рдЙрдВрдб рд╕рд╛рдЗрди #), рдПрдХ рдирд╛рдо (рдпрд╛ рдЯреИрдЧ рдХрд╛ рдирд┐рдХрд╛рдп, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреЗрдЬреЗрдЯрд╛рдЗрд▓ [рдореЗрдВ] [* рдкреЗрдЬреЗрдЯреАрдЯрд▓]]), рдлрд┐рд▓реНрдЯрд░ (: ucase, рдЖрджрд┐) рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ (рдФрд░ рд╕реНрдирд┐рдкреЗрдЯ рдЯреИрдЧ рдпрд╛ рдЕрдиреНрдп рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░)ред рдЯреЛрдХрди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЯреИрдЧ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕ рд╡рд┐рд╢реЗрд╖ рдЯреИрдЧ рд╡рд░реНрдЧ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпреЗ рд╕рднреА рдЕрдореВрд░реНрдд рдореЛрджрдЧ рд╡рд░реНрдЧ рдХреЗ рд╡рдВрд╢рдЬ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдПрдХ рдирдпрд╛ рдЯреИрдЧ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдирдпрд╛ рд╡рд░реНрдЧ modResourceFieldTag рдмрдирд╛рдПрдВред рд╕рднреА рдЯреИрдЧ рдХрдХреНрд╖рд╛рдУрдВ рдиреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛ () рдФрд░ getContent () рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рдпрд╛ рд╣реИред рдЙрд╕реА рд╕рдордп, рд╣рдорд╛рд░рд╛ рдирдпрд╛ рдЯреИрдЧ рд░рд┐рд╕реЛрд░реНрд╕ рдлреАрд▓реНрдб рдЯреИрдЧ рд╕реЗ рдХрд╛рдлреА рдорд┐рд▓рддрд╛-рдЬреБрд▓рддрд╛ рд╣реИ, рдФрд░ рдореИрдВрдиреЗ рдЗрд╕рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ () рд╡рд┐рдзрд┐ рдХреЛ рдЫреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ modFieldTag рдХреНрд▓рд╛рд╕ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ред рдпрд╣рд╛рдБ рдХреНрдпрд╛ рд╣реБрдЖ:

 class modResourceFieldTag extends modFieldTag { /** * Overrides modTag::__construct to set the Field Tag token * {@inheritdoc} */ function __construct(modX & $modx) { parent :: __construct($modx); $this->setToken('#'); } /** * Get the raw source content of the field. * * {@inheritdoc} */ public function getContent(array $options = array()) { if (!$this->isCacheable() || !is_string($this->_content) || $this->_content === '') { if (isset($options['content']) && !empty($options['content'])) { $this->_content = $options['content']; } else { $tag = explode('.', $this->get('name')); $tagLength = count($tag); // for processing tags in resource_id place ([[#[[+id]].pagetitle]]) $tags = array(); if ($collected= $this->modx->parser->collectElementTags($tag[0], $tags)) { $tag[0] = $this->modx->parser->processTag($tags[0], $this->modx->parser->isProcessingUncacheable()); } if (is_numeric($tag[0])) { $resource = $this->modx->getObject('modResource', $tag[0]); if ($resource) { if ($tagLength == 2) { if ($tag[1] == 'content') { $this->_content = $resource->getContent($options); } else { $this->_content = $resource->get($tag[1]); } } else { if (($tag[1] == 'tv') && ($tagLength == 3)) { $this->_content = $resource->getTVValue($tag[2]); } elseif (in_array($tag[1], array('properties', 'property', 'prop')) && ($tagLength == 4)) { $this->_content = $resource->getProperty($tag[3], $tag[2]); } else { $this->_content = ''; } } } else { $this->_content = ''; } } } } return $this->_content; } } 

рдорд╛рдорд▓реЗ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрдм рдЯреИрдЧ рдХреЛ рд╕рдВрд╕рд╛рдзрди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП рдкреНрд▓реЗрд╕рд╣реЛрд▓реНрдбрд░ рдХреЗ рд╕рд╛рде рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, [[[[[рдЖрдИрдбреА]]ред рдкрдЧреЗрдЯрд┐рдЯреЗрд▓]), рд╣рдо рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдЯреИрдЧ рдХреЗ рдЗрд╕ рднрд╛рдЧ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
 $tags = array(); if ($collected= $this->modx->parser->collectElementTags($tag[0], $tags)) { $tag[0] = $this->modx->parser->processTag($tags[0], $this->modx->parser->isProcessingUncacheable()); } 

рдлрд╝рд┐рд▓реНрдЯрд░ рдЬрд┐рдиреНрд╣реЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдореЗрдВ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдЗрд╡реЗрдВрдЯ рдХреЗ рдмрд╛рдж рдкрд╛рд░реНрд╕рд░ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЕрдм рдпрд╣ рдЯреИрдЧ рдбреЗрдЯрд╛ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдлрд╛рд╕реНрдЯрдлрд┐рд▓реНрдб рдкреНрд▓рдЧрдЗрди рдореЗрдВ:
 switch ($modx->event->name) { case 'OnParseDocument': $content = $modx->documentOutput; $tags= array (); if ($collected= $modx->parser->collectElementTags($content, $tags, '[[', ']]', array('#'))) { $tagMap= array (); foreach ($tags as $tag) { $token = substr($tag[1], 0, 1); if ($token == '#') { include_once $modx->getOption('core_path') . 'components/fastfield/model/fastfield/fastfield.php'; $tagParts= xPDO :: escSplit('?', $tag[1], '`', 2); $tagName= substr(trim($tagParts[0]), 1); $tagPropString= null; if (isset ($tagParts[1])) { $tagPropString= trim($tagParts[1]); } $element= new modResourceFieldTag($modx); $element->set('name', $tagName); $element->setTag(''); $element->setCacheable(false); $tagMap[$tag[0]] = $element->process($tagPropString); } } $modx->parser->mergeTagOutput($tagMap, $content); $modx->documentOutput = $content; } break; } 


рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдкрд╛рдардХреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЯреИрдЧ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЧрд╛рдЗрдб рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред рдХреЛрдб рд╕рд╣реА рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЗрд╕ рдЕрджреНрднреБрдд рд╕реАрдПрдордПрд╕ / рд╕реАрдПрдордПрдл рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдХреЗ рдкреНрд░рдпреЛрдЧ рдХреА рддреИрдпрд╛рд░реА рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдкреНрд▓рдЧрдЗрди рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб GitHub рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ ред

Source: https://habr.com/ru/post/In161843/


All Articles