Давно не писал что-нибудь заумное, чтоб после прочтения у Вас голова заболела, поэтому решил написать! Может будет трудно осилить, но Вы приблизитесь к опытному уровню разработок в modx. В этой статье я не буду разжевывать всё в подробностях, но она будет очень большая, охватывающая многие аспекты программирования в среде для разработки modx, поэтому Вам придётся набраться терпения, но это будет того стоить, так как некоторые решения Вы не найдётё в интернете.
То что я буду Вам пытаться сейчас объяснить вызовет у Вас головную боль, но поверьте эта боль - меньшее зло, по сравнению с той, которая бы у Вас проявилась, если бы Вы вручную - методом проб, всё бы это пытались создать. Для начала давайте вспомним, что отменили в последней версии MODx - 2.1.
Часто разработчику необходимо получать данные не прибегая к перезагрузке страницы, то есть через ajax. Так как с системами управления это достаточно сложно реализовать начинающим пользователям и разработчикам этих систем, поэтому мы начнём с правильного подключения MODx API во внешних скриптах.
Для начала нужно определится с подключением к MODX API. Данный код нужен для защиты.
| 1. | if (!defined('MODX_API_MODE')) { |
| 2. | define('MODX_API_MODE', false); |
| 3. | } |
| 4. |
Далее следует указать стоит ли кэшировать данные MODX, - по умолчанию данные кэшируются, что мы собственно и видим.
| 1. | $modx_cache_disabled= false; |
| 2. |
После этого нам нужно подключить основной класс для работы с API MODX и конфигурационный файл:
| 1. | /* подключаем настройки и определим базовый путь для MODX*/ |
| 2. | @include('config.core.php'); |
| 3. | if (!defined('MODX_CORE_PATH')) define('MODX_CORE_PATH', $_SEVER['DOCUMENT_ROOT'].'/core/'); |
| 4. | |
| 5. | /* подключаем класс modX */ |
| 6. | if (!@include_once (MODX_CORE_PATH . "model/modx/modx.class.php")) { |
| 7. | $errorMessage = 'Site temporarily unavailable'; |
| 8. | @include(MODX_CORE_PATH . 'error/unavailable.include.php'); |
| 9. | header('HTTP/1.1 503 Service Unavailable'); |
| 10. | echo "<html><title>Error 503: Site temporarily unavailable</title><body><h1>Error 503</h1><p>{$errorMessage}</p></body></html>"; |
| 11. | exit(); |
| 12. | } |
| 13. | |
| 14. | /* вывод данных из буфера */ |
| 15. | ob_start(); |
| 16. | |
| 17. | /* Создаём экземпляр класса modX */ |
| 18. | if (empty($options) || !is_array($options)) $options = array(); |
| 19. | $modx= new modX('', $options); |
| 20. | if (!is_object($modx) || !($modx instanceof modX)) { |
| 21. | @ob_end_flush(); |
| 22. | $errorMessage = '<a href="setup/">MODx not installed. Install now?</a>'; |
| 23. | @include(MODX_CORE_PATH . 'error/unavailable.include.php'); |
| 24. | header('HTTP/1.1 503 Service Unavailable'); |
| 25. | echo "<html><title>Error 503: Site temporarily unavailable</title><body><h1>Error 503</h1><p>{$errorMessage}</p></body></html>"; |
| 26. | exit(); |
| 27. | } |
| 28. |
В моих скриптах я использую заголовок для указания правильной кодировки. Правильнее этот заголовок разместить выше предыдущих скрипов, но в связи с тем что мои скрипы, как правило, не выводят ошибок до этого заголовка, то и сообщение о его неправильно размещении Вы так же не должны получить.
| 1. | header('Content-Type: text/html; charset=utf-8'); |
| 2. |
Я советую использовать нижеуказанный код для записи всех действий в журнал MODX.
| 1. | $modx->setLogLevel(modX::LOG_LEVEL_ERROR); |
| 2. | $modx->setLogTarget('FILE'); |
| 3. |
Задайте уровень обработки ошибок.
| 1. | $modx->setDebug(E_ALL & ~E_NOTICE); |
| 2. |
Здесь нужно быть по внимательнее, выбрав правильный контекст, изначально он такой. Если Вам нужен другой контекст, - измените соответственно строку 'web'.
| 1. | $modx->initialize('web'); |
| 2. |
Сейчас мы подобрались к основному выводу содержимого статей вашего сайта. В следующем листинге мы получаем объект - ресурс с "ID" равным 3. Если у Вас пока одна страница "HOME", то Вам необходимо изменить его на 1, иначе ничего не будет выведено. Сейчас я не буду объяснять подробное назначения массива, но заранее отмечу что в MODX можно выбирать статьи одновременно по нескольким параметрам, а так же несколько ресурсов в одни массив, но пока давайте выведем содержимое одной статьи по её ID.
| 1. | $holder = $modx->getObject('modResource',array('id' => 3)); |
| 2. |
Теперь, когда у нас есть объект, мы можем получить его данные, давайте получим содержимое статьи.
| 1. | echo $holder->get('content'); |
| 2. |
Рабочий вариант полностью.
| 1. | <?php |
| 2. | /* |
| 3. | * MODx Revolution |
| 4. | * |
| 5. | * Copyright 2006-2010 by the MODx Team. |
| 6. | * All rights reserved. |
| 7. | * |
| 8. | * This program is free software; you can redistribute it and/or modify it under |
| 9. | * the terms of the GNU General Public License as published by the Free Software |
| 10. | * Foundation; either version 2 of the License, or (at your option) any later |
| 11. | * version. |
| 12. | * |
| 13. | * This program is distributed in the hope that it will be useful, but WITHOUT |
| 14. | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 15. | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
| 16. | * details. |
| 17. | * |
| 18. | * You should have received a copy of the GNU General Public License along with |
| 19. | * this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
| 20. | * Place, Suite 330, Boston, MA 02111-1307 USA |
| 21. | * |
| 22. | */ |
| 23. | $mtime= microtime(); |
| 24. | $mtime= explode(" ", $mtime); |
| 25. | $mtime= $mtime[1] + $mtime[0]; |
| 26. | $tstart= $mtime; |
| 27. | |
| 28. | error_reporting(E_ALL & ~E_NOTICE); |
| 29. | |
| 30. | /** |
| 31. | * @deprecated 2.0.0 |
| 32. | * For backward compatibility with MODx 0.9.x |
| 33. | */ |
| 34. | define("IN_PARSER_MODE", "true"); |
| 35. | /** |
| 36. | * @deprecated 2.0.0 |
| 37. | * For backward compatibility with MODx 0.9.x |
| 38. | */ |
| 39. | define("IN_MANAGER_MODE", false); |
| 40. | |
| 41. | /* define this as true in another entry file, then include this file to simply access the API |
| 42. | * without executing the MODx request handler */ |
| 43. | if (!defined('MODX_API_MODE')) { |
| 44. | define('MODX_API_MODE', false); |
| 45. | } |
| 46. | |
| 47. | /* this can be used to disable caching in MODx absolutely */ |
| 48. | $modx_cache_disabled= false; |
| 49. | |
| 50. | /* include custom core config and define core path */ |
| 51. | @include('config.core.php'); |
| 52. | if (!defined('MODX_CORE_PATH')) define('MODX_CORE_PATH', $_SEVER['DOCUMENT_ROOT'].'/core/'); |
| 53. | |
| 54. | /* include the modX class */ |
| 55. | if (!@include_once (MODX_CORE_PATH . "model/modx/modx.class.php")) { |
| 56. | $errorMessage = 'Site temporarily unavailable'; |
| 57. | @include(MODX_CORE_PATH . 'error/unavailable.include.php'); |
| 58. | header('HTTP/1.1 503 Service Unavailable'); |
| 59. | echo "<html><title>Error 503: Site temporarily unavailable</title><body><h1>Error 503</h1><p>{$errorMessage}</p></body></html>"; |
| 60. | exit(); |
| 61. | } |
| 62. | |
| 63. | /* start output buffering */ |
| 64. | ob_start(); |
| 65. | |
| 66. | /* Create an instance of the modX class */ |
| 67. | if (empty($options) || !is_array($options)) $options = array(); |
| 68. | $modx= new modX('', $options); |
| 69. | if (!is_object($modx) || !($modx instanceof modX)) { |
| 70. | @ob_end_flush(); |
| 71. | $errorMessage = '<a href="setup/">MODx not installed. Install now?</a>'; |
| 72. | @include(MODX_CORE_PATH . 'error/unavailable.include.php'); |
| 73. | header('HTTP/1.1 503 Service Unavailable'); |
| 74. | echo "<html><title>Error 503: Site temporarily unavailable</title><body><h1>Error 503</h1><p>{$errorMessage}</p></body></html>"; |
| 75. | exit(); |
| 76. | } |
| 77. | header('Content-Type: text/html; charset=utf-8'); |
| 78. | /* Set the actual start time */ |
| 79. | $modx->startTime= $tstart; |
| 80. | |
| 81. | /* Set additional logging options including level and target: */ |
| 82. | $modx->setLogLevel(modX::LOG_LEVEL_ERROR); |
| 83. | $modx->setLogTarget('FILE'); |
| 84. | |
| 85. | /* Set debugging mode (i.e. error_reporting): */ |
| 86. | $modx->setDebug(E_ALL & ~E_NOTICE); |
| 87. | |
| 88. | /* Initialize the default 'web' context */ |
| 89. | $modx->initialize('web'); |
| 90. | |
| 91. | //выбираем ресурсы по заданному условию |
| 92. | |
| 93. | $holder = $modx->getObject('modResource',array('id' => 3)); |
| 94. | |
| 95. | |
| 96. | echo $holder->get('content'); |
| 97. | |
| 98. | |
| 99. | |
| 100. | |
| 101. | |
| 102. | ?> |
| 103. |
Если нужно вывести одновременно несколько статей, например, зная их название и краткое описание, то нужно использовать метод getCollection и заменить всё в предыдущем листинге начиная с 93 строки следующим кодом:
| 1. | $documents = $modx->getCollection('modResource',array( |
| 2. | 'id' => 1, |
| 3. | 'id' => 2, |
| 4. | 'id' => 3 |
| 5. | )); |
| 6. | |
| 7. | if (!empty($documents)) { |
| 8. | foreach ($documents as $document) { |
| 9. | |
| 10. | $content = $document->get('content'); |
| 11. | |
| 12. | if (!empty($content)) { |
| 13. | |
| 14. | $modx->resource =& $document; |
| 15. | |
| 16. | // get the max iterations tags are processed before processing is terminated |
| 17. | $maxIterations= (integer) $modx->getOption('parser_max_iterations', null, 10); |
| 18. | |
| 19. | // parse all cacheable tags first |
| 20. | $modx->getParser()->processElementTags('', $content, true, false, '[[', ']]', array(), $maxIterations); |
| 21. | |
| 22. | // parse all non-cacheable and remove unprocessed tags |
| 23. | $modx->getParser()->processElementTags('', $content, true, true, '[[', ']]', array(), $maxIterations); |
| 24. | |
| 25. | echo $content. '< br/>'; |
| 26. | } |
| 27. | } |
| 28. | } |
| 29. |
В итоге будут получены первые три статьи, при этом все переменные, TV будут распарены, а сниппеты выполнены - это основное отличие от предыдущего листинга, в котором содержимое выводится в том виде, в котором Вы его видите в админ. Панели, - при редактировании в редакторе(content).
Используя этот шаблон php скрипта плюс небольшое дополнение на jQuery, например $.load или $.post или $.ajax Вы сможете создавать динамичные ресурсы внутри системы MODX.
Как-то у меня возникла необходимость получать имя активного пользователя, для того чтобы заполнить его данным таблицу SQL, я выбрал следующее решение.
| 1. | require_once 'manager/config.core.php'; |
| 2. | require_once MODX_CORE_PATH.'config/'.MODX_CONFIG_KEY.'.inc.php'; |
| 3. | require_once MODX_CORE_PATH.'model/modx/modx.class.php'; |
| 4. | $modx = new modX(); |
| 5. | $modx->initialize('web'); |
| 6. | define('LOGINMODX',$modx->getLoginUserName()); |
| 7. | |
| 8. | ..... |
| 9. | |
| 10. | $query = 'SELECT * FROM modx_mail_papers WHERE chernovik = 1 AND username="'.LOGINMODX.'"'; |
| 11. | ..... |
| 12. | $result = $this->mMysqli->query($query) or die (mysqli_error($this->mMysqli)); |
| 13. | ..... |
| 14. |
Другой раз у меня возникла необходимость отправки данных на email, который должен был быть указан пользователем и может постоянно изменяться. Для того, чтобы пользователю не "лазить" по скриптам, я решил создать сниппет в котором пользователь мог удобно изменить email на нужный. Для вызова сниппета мне пришлось использовать метод runsnippet. Поэтому может и Вам пригодится:
| 1. | <?php |
| 2. | require_once 'manager/config.core.php'; |
| 3. | require_once MODX_CORE_PATH.'config/'.MODX_CONFIG_KEY.'.inc.php'; |
| 4. | require_once MODX_CORE_PATH.'model/modx/modx.class.php'; |
| 5. | $modx = new modX(); |
| 6. | |
| 7. | $modx->initialize('web'); |
| 8. | |
| 9. | define('PAPERSEMAIL', $modx->runsnippet('papersemail')); |
| 10. | echo PAPERSEMAIL; |
| 11. | |
| 12. | ?> |
| 13. |
Получать данные об активном пользователе или странице внутри системы (НЕ ВО ВНЕШНЕМ СКРИПТЕ), через сниппет можно следующим образом:
| 1. | <?php |
| 2. | $currentResource = $modx->resource; |
| 3. | $currentUser = $modx->user; |
| 4. |
Получим текущий заголовок страницы(pagttitle), в сниппетах, - не забывайте вместо echo пишется return:
| 1. | <?php |
| 2. | $pagetitle = $modx->resource->get('pagetitle'); |
| 3. | return $pagetitle; |
| 4. |
Однажды столкнулся с ситуацией, когда в системе было несколько статей с одинаковыми заголовками, одни из которых были опубликованы, другие нет, для того чтобы вывести опубликованные использовал следующий код:
| 1. | $document = $modx->getObject('modResource',array( |
| 2. | 'published' => 1, |
| 3. | 'pagetitle' => 'BMW' |
| 4. | )); |
| 5. |
Получаем системные настройки MODX:
| 1. | $setting = $modx->getOption('site_start'); |
| 2. |
Получаем переменные шаблонов (TV):
| 1. | $val = $modx->resource->getTVValue('имя TV'); |
| 2. | $val = $modx->resource->getTVValue($id); // ID TV (не документа) |
| 3. |
Так как не запрещено внутри TV использовать другие TV, то для того чтобы получить TV с уже распарсенным TV, нужно использовать следующий код:
| 1. | /* Доступ к TV */ |
| 2. | $tv = $modx->getObject('modTemplateVar',array('name'=>'MyTV')); |
| 3. | |
| 4. | /* получить TV без разбора*/ |
| 5. | $rawValue = $tv->getValue($id); |
| 6. | |
| 7. | /* распарсить содержимое TV */ |
| 8. | $processedValue = $tv->renderOutput($id); |
| 9. |
Встраиваем содержимое ресурса, заголовок которого - "MyDocument", в чанк, тем самым все переменные внутри этого содержимого будут распарсены парсером MODX.
| 1. | $resource = $modx->getObject('modResource',array('pagetitle'=>'MyDocument')); |
| 2. | return $modx->getChunk('ShowResource',$resource->toArray()); |
| 3. |
Выполнить сниппет можно с указанием его настроек следующим образом:
| 1. | $modx->runsnippet($snippetName, $props); |
| 2. |
Для получения параметров сниппета, установленных по умолчанию используется следующий код:
| 1. | $snippet = $modx->getObject('modSnippet',array('name'=>'SnippetName')); |
| 2. | $properties = $snippet->getProperties(); |
| 3. | |
| 4. |
Я взял каптчу с сайта QapTcha. Для начала включите в шаблон, на странице которого будет размещаться форма регистрации js и css файлы, как указано ниже:
| 1. | <link rel="stylesheet" href="QapTcha.jquery.css" type="text/css" /> |
| 2. | <script src="http://code.jquery.com/jquery-1.5.2.min.js"></script> |
| 3. | <script type="text/javascript" src="jquery-ui.js"></script> |
| 4. | <script type="text/javascript" src="QapTcha.jquery.js"></script> |
| 5. |
После вставляем сниппет регистрации, он доступен по умолчанию и включен в состав сниппета "Login".
| 1. | [[!Register? |
| 2. | &submitVar=`registerbtn` |
| 3. | &activationResourceId=`5` |
| 4. | &activationEmailTpl=`myActivationEmailTpl` |
| 5. | &activationEmailSubject=`Спасибо за регистрацию!` |
| 6. | &submittedResourceId=`1` |
| 7. | ]] |
| 8. | <script type="text/javascript"> |
| 9. | $(function(){ |
| 10. | $('#QapTcha').QapTcha({}); |
| 11. | }); |
| 12. | </script> |
| 13. | ....... |
| 14. | здесь форма с полями для регистрации нового пользователя |
| 15. | ....... |
| 16. |
Следующий код нужно вставить в форму регистрации, - там где Вам нужно, обычно это перед кнопкой отправки формы. То есть данный код создаёт каптчу.
| 1. | <div class="clr"></div> |
| 2. | |
| 3. | <div id="QapTcha"></div> |
| 4. |
Далее заменить строку 69 сниппета "Register", находящийся в разделе сниппетов плагина "Login":
| 1. | if (!empty($_POST) && (empty($submitVar) || !empty($_POST[$submitVar]))) { |
| 2. |
следующей строкой кода:
| 1. | if (!empty($_POST) && (empty($submitVar) || !empty($_POST[$submitVar])) && !empty($_SESSION['iQaptcha'])) { |
| 2. |
В итоге на странице, где у Вас расположена форма будет находится красивая и простая каптча:
Для правильной работы каптчи нужен php, сохраняющий данные в сессию, который указан ниже:
| 1. | <?php |
| 2. | $aResponse['error'] = false; |
| 3. | $_SESSION['iQaptcha'] = false; |
| 4. | |
| 5. | if(isset($_POST['action'])) |
| 6. | { |
| 7. | if(htmlentities($_POST['action'], ENT_QUOTES, 'UTF-8') == 'qaptcha') |
| 8. | { |
| 9. | $_SESSION['iQaptcha'] = true; |
| 10. | if($_SESSION['iQaptcha']) |
| 11. | echo json_encode($aResponse); |
| 12. | else |
| 13. | { |
| 14. | $aResponse['error'] = true; |
| 15. | echo json_encode($aResponse); |
| 16. | } |
| 17. | } |
| 18. | else |
| 19. | { |
| 20. | $aResponse['error'] = true; |
| 21. | echo json_encode($aResponse); |
| 22. | } |
| 23. | } |
| 24. | else |
| 25. | { |
| 26. | $aResponse['error'] = true; |
| 27. | echo json_encode($aResponse); |
| 28. | } |
| 29. |
Теперь многое для Вас в Modx станет доступным. А если не совсем, - для этого есть комментарии или форум со специальным разделом "MODX REVOLUTION"!
6.1
Александр
Спасибо!