From feb10cdc0c3da73eb3fd1ed0ea8f343fadebdfd1 Mon Sep 17 00:00:00 2001 From: AlekVolsk Date: Sun, 29 Sep 2019 17:58:45 +0400 Subject: [PATCH] v1.3.0 --- README.md | 22 +++- README.ru.md | 22 +++- com_attrs/attrs.xml | 3 +- com_attrs/helpers/attrs.php | 75 ++++++++++--- com_attrs/language/en-GB/en-GB.com_attrs.ini | 4 + com_attrs/language/ru-RU/ru-RU.com_attrs.ini | 4 + com_attrs/layouts/default.php | 8 ++ com_attrs/models/fields/layoutscomponent.php | 108 +++++++++++++++++++ com_attrs/models/forms/item.xml | 3 +- com_attrs/sql/install.mysql.utf8.sql | 1 + com_attrs/sql/updates/mysql/1.3.0.sql | 1 + com_attrs/views/item/tmpl/edit.php | 2 + com_attrs/views/items/tmpl/default.php | 9 +- pkg_attrs.xml | 6 +- plg_system_attrs/attrs.php | 3 +- plg_system_attrs/attrs.xml | 4 +- 16 files changed, 241 insertions(+), 34 deletions(-) create mode 100644 com_attrs/layouts/default.php create mode 100644 com_attrs/models/fields/layoutscomponent.php create mode 100644 com_attrs/sql/updates/mysql/1.3.0.sql diff --git a/README.md b/README.md index 0f2bea4..a9d4423 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Attributes -![Last Update](https://img.shields.io/badge/last_update-2019.09.08-28A5F5.svg?style=for-the-badge) -![Version](https://img.shields.io/badge/VERSION-1.2.5-0366d6.svg?style=for-the-badge) +![Last Update](https://img.shields.io/badge/last_update-2019.09.29-28A5F5.svg?style=for-the-badge) +![Version](https://img.shields.io/badge/VERSION-1.3.0-0366d6.svg?style=for-the-badge) ![Joomla](https://img.shields.io/badge/joomla-3.7+-1A3867.svg?style=for-the-badge) ![Php](https://img.shields.io/badge/php-5.6+-8892BF.svg?style=for-the-badge) @@ -24,26 +24,30 @@ Attribute values are stored in the parameters of the corresponding element, the Every attribute name is prefixed with `attrs_` prefix. You can get the attribute value by the standard way described below. +For each attribute, it is possible to specify an individual output layout. Layouts are created in the /templates/{your_template}/html/layouts/com_attrs/ folder and are assigned to each attribute separately. The attribute data inside the layout is contained in the `$displayData` structure. The default layout does not contain markup. + ## Usage ### Shortcode, for use in content editor -``` -{attrs;dest;id;attrName} +```text +{attrs;dest;id;attrNameЯ[;layout]} ``` - `attrs` - reserved word - `dest` - belonging to a specific type of record, one of: system, menu, users, contacts, articles, categories, modules, plugins - `id` - ID of the corresponding entry for the specified property, specify 0 for systems - `attrName` - attribute system name +- `layout` - output layout (optional), if **0** or **false** is specified, the assigned layout will be ignored and the attribute value will be displayed without layout; format for specifying the layout: `template:layoutname`, where _template_ is the main template of the site that contains the override (specify the underscore to indicate the default template), _layoutname_ is the name of the overridden layout file, without extension; when specifying a nonexistent layout, the attribute value will not be displayed **Important**: Unpublished attributes are ignored. Images are output without markup, only the path. Arrays are displayed as a list of values separated by commas. **Example**: You have created an attribute with the name test for a material with ID = 5, to get its value, insert the following line in the editor: `{attrs;articles;5;test}`. +If you want to display the attribute indicating the override of the template created with the name mytemplate in the main protostar site template, insert the following line into the editor: `{attrs;articles;5;test;protostar:mytemplate}`. ### With helper -It is recommended because it checks the status of the attribute (published / unpublished) and it is not necessary to specify the prefix `attrs_`. Skip the third parameter to get the attribute value from the system config. +It is recommended because it checks the status of the attribute (published / unpublished) and it is not necessary to specify the prefix `attrs_`. Do not specify the third parameter or set it to zero to get the attribute value from the system configuration. ```php /* @@ -60,11 +64,19 @@ AttrsHelper::ATTR_DEST_TAGS = 'tags' */ JLoader::register('AttrsHelper', JPATH_ADMINISTRATOR . '/components/com_attrs/helpers/attrs.php'); + +// output with the layout specified in the attribute parameters $attrValue = AttrsHelper::getAttr($attrName, AttrsHelper::ATTR_DEST_ARTICLES, $article->id); + +// priority layout output +// the attribute layout will be loaded /templates/protostar/html/layouts/com_attrs/mytemplate.php +$attrValue = AttrsHelper::getAttr($attrName, AttrsHelper::ATTR_DEST_ARTICLES, $article->id, 'protostar:mytemplate'); ``` ### Without helper (not recommended) +This method does not support attribute standardization. + ```php // default $attrValue = $item->params->get("arrts_$attrName", ''); diff --git a/README.ru.md b/README.ru.md index 3f9df94..12a4247 100644 --- a/README.ru.md +++ b/README.ru.md @@ -1,7 +1,7 @@ # Атрибуты -![Last Update](https://img.shields.io/badge/last_update-2019.09.08-28A5F5.svg?style=for-the-badge) -![Version](https://img.shields.io/badge/VERSION-1.2.5-0366d6.svg?style=for-the-badge) +![Last Update](https://img.shields.io/badge/last_update-2019.09.29-28A5F5.svg?style=for-the-badge) +![Version](https://img.shields.io/badge/VERSION-1.3.0-0366d6.svg?style=for-the-badge) ![Joomla](https://img.shields.io/badge/joomla-3.7+-1A3867.svg?style=for-the-badge) ![Php](https://img.shields.io/badge/php-5.6+-8892BF.svg?style=for-the-badge) @@ -22,27 +22,31 @@ К каждому указанному системному имени атрибута добавляется префикс `attrs_`. Вы можете получить значение атрибута стандартным нижеуказанным способом. +Для каждого атрибута имеется возможность указания индивидуального макета вывода. Макеты создаются в папке /templates/{ваш_шаблон}/html/layouts/com_attrs/ и назначаются каждому атрибуту отдельно. Данные атрибута внутри макета содержатся в структуре `$displayData`. Макеты по умолчанию не содержит разметки. + ## Использование ### Шорткод, для использования в контент-редакторе -``` -{attrs;dest;id;attrName} +```text +{attrs;dest;id;attrNameЯ[;layout]} ``` - `attrs` - зарезервированное слово - `dest` - принадлежность к определённому типу записи, одно из значений: system, menu, users, contacts, articles, categories, modules, plugins - `id` - ID записи соответствующей принадлежности, указывать `0` для system - `attrName` - системное имя атрибута +- `layout` - макет вывода (необязательный параметр), при указании значения **0** или **false** назначенный макет будет проигнорирован и значение атрибута будет выведено без шаблонизации; формат указания макета: `template:layoutname`, где _template_ – основной шаблон сайта, в котором содержится переопределение (укажите нижнее подчёркивание для указания шаблона по умолчанию), _layoutname_ – имя файла переопределённого макета, без расширения; при указании несуществующего макета значение атрибута выведено не будет **Важно**: Шорткоды, ссылающиеся на неопубликованные атрибуты, игнорируются. Изображения выводятся без разметки, только путь. Массивы выводятся как список значений через запятую. **Пример**: Вы создали для материала с ID = 5 атрибут с именем test, чтобы получить его значение, вставьте в редактор следующую строку: `{attrs;articles;5;test}`. +Если вы хотите вывести значение атрибута с указанием конкретного переопределенного макета, созданного с именем mytemplate в основном шаблоне сайта protostar, вставьте в редактор следующую строку: `{attrs;articles;5;test;protostar:mytemplate}`. ### Через хелпер компонета Рекомендуемый метод, поскольку производится проверка состояния атрибута (опубликован / неопубликован) и нет необходимости указывать префикс `attrs_`. -Пропустите третий параметр, чтобы получить значение атрибута из конфигурации системы. +Не указывайте третий параметр или укажите его равным нулю, чтобы получить значение атрибута из конфигурации системы. ```php /* @@ -59,11 +63,19 @@ AttrsHelper::ATTR_DEST_TAGS = 'tags' */ JLoader::register('AttrsHelper', JPATH_ADMINISTRATOR . '/components/com_attrs/helpers/attrs.php'); + +// вывод с макетом, указанным в параметрах атрибута $attrValue = AttrsHelper::getAttr($attrName, AttrsHelper::ATTR_DEST_ARTICLES, $article->id); + +// вывод с макетом, заданным приоритетно +// будет загружен макет атрибута /templates/protostar/html/layouts/com_attrs/mytemplate.php +$attrValue = AttrsHelper::getAttr($attrName, AttrsHelper::ATTR_DEST_ARTICLES, $article->id, 'protostar:mytemplate'); ``` ### Без хелпера (не рекомендуется) +Этот метод не поддерживает шаблонизацию атрибутов. + ```php // default $attrValue = $item->params->get("arrts_$attrName", ''); diff --git a/com_attrs/attrs.xml b/com_attrs/attrs.xml index 3b1bdd0..b621f3d 100644 --- a/com_attrs/attrs.xml +++ b/com_attrs/attrs.xml @@ -1,7 +1,7 @@ COM_ATTRS - 1.2.5 + 1.3.0 September 2019 Aleksey A. Morozov alekvolsk@yandex.ru @@ -31,6 +31,7 @@ controller.php access.xml controllers + layouts helpers models sql diff --git a/com_attrs/helpers/attrs.php b/com_attrs/helpers/attrs.php index 5e9a649..b8d4e89 100644 --- a/com_attrs/helpers/attrs.php +++ b/com_attrs/helpers/attrs.php @@ -3,6 +3,8 @@ use Joomla\CMS\Factory; use Joomla\CMS\Table\Table; use Joomla\Registry\Registry; +use Joomla\CMS\Filesystem\Path; +use Joomla\CMS\Layout\FileLayout; class AttrsHelper { @@ -17,25 +19,18 @@ class AttrsHelper const ATTR_DEST_FIELDS = 'fields'; const ATTR_DEST_TAGS = 'tags'; - public static function isPublished($attrName) - { - $db = Factory::getDbo(); - $query = $db->getQuery(true) - ->select('`published`') - ->from('`#__attrs`') - ->where('`name` = ' . $db->quote(self::getSystemAttrName($attrName))); - $published = $db->setQuery($query)->loadResult(); - return (bool) $published; - } - - public static function getAttr($attrName, $attrDest, $id = 0) + public static function getAttr($attrName, $attrDest, $id = 0, $template = '') { $attrValue = ''; - if (!self::isPublished($attrName)) { + $attrParams = self::getAttrParams($attrName); + if (!isset($attrParams) || !$attrParams['published']) { return $attrValue; } - + if (!$attrParams['layout']) { + $attrParams['layout'] = '_:default'; + } + if (!$id && $attrDest !== self::ATTR_DEST_SYSTEM) { return $attrValue; } @@ -138,7 +133,30 @@ public static function getAttr($attrName, $attrDest, $id = 0) $attrValue = $params->get($attrName, ''); } - return $attrValue; + if ($template === false) { + return $attrValue; + } else { + $layoutMask = $template ? $template : $attrParams['layout']; + $fileLayout = self::getLayoutPath($layoutMask); + $layout = new FileLayout(pathinfo($fileLayout, PATHINFO_FILENAME), null, ['component' => 'com_attrs']); + $layout->addIncludePath(pathinfo($fileLayout, PATHINFO_DIRNAME)); + return $layout->render(['name' => self::getSystemAttrName($attrName), 'value' => $attrValue, 'dest' => $attrDest, 'id' => $id]); + } + } + + private static function getAttrParams($attrName) + { + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select('`published`, `layout`') + ->from('`#__attrs`') + ->where('`name` = ' . $db->quote(self::getSystemAttrName($attrName))); + try { + $row = $db->setQuery($query)->loadAssoc(); + } catch (\Exception $e) { + $row = []; + } + return $row; } private static function getSystemAttrName($attrName) @@ -153,4 +171,31 @@ private static function getParamsAttrName($attrName) } return $attrName; } + + private static function getLayoutPath($layout = 'default') + { + $template = Factory::getApplication()->getTemplate(); + $defaultLayout = $layout; + + if (strpos($layout, ':') !== false) { + $temp = explode(':', $layout); + $template = $temp[0] === '_' ? $template : $temp[0]; + $layout = $temp[1]; + $defaultLayout = $temp[1] ?: 'default'; + } + + $tPath = JPATH_THEMES . '/' . $template . '/html/layouts/com_attrs/' . $layout . '.php'; + $bPath = JPATH_ADMINISTRATOR . '/components/com_attrs/layouts/' . $defaultLayout . '.php'; + $dPath = JPATH_ADMINISTRATOR . '/components/com_attrs/layouts/default.php'; + + if (file_exists($tPath)) { + return Path::clean($tPath); + } + + if (file_exists($bPath)) { + return Path::clean($bPath); + } + + return Path::clean($dPath); + } } diff --git a/com_attrs/language/en-GB/en-GB.com_attrs.ini b/com_attrs/language/en-GB/en-GB.com_attrs.ini index bb1b863..075ee28 100644 --- a/com_attrs/language/en-GB/en-GB.com_attrs.ini +++ b/com_attrs/language/en-GB/en-GB.com_attrs.ini @@ -40,6 +40,10 @@ COM_ATTRS_VAL_MULTIPLE="multiple select" COM_ATTRS_VAL_FILTER="Data filter" COM_ATTRS_CLASS="Field class" +COM_ATTRS_LAYOUT="Template" +JOPTION_FROM_COMPONENT="---From component---" +COM_ATTRS_LAYOUTS_LAYOUT_DEFAULT="Default" + COM_ATTRS_DEST="Destination" COM_ATTRS_DEST_SYSTEM=" System" COM_ATTRS_DEST_MENU=" Menu" diff --git a/com_attrs/language/ru-RU/ru-RU.com_attrs.ini b/com_attrs/language/ru-RU/ru-RU.com_attrs.ini index 995e8bc..ce817a9 100644 --- a/com_attrs/language/ru-RU/ru-RU.com_attrs.ini +++ b/com_attrs/language/ru-RU/ru-RU.com_attrs.ini @@ -40,6 +40,10 @@ COM_ATTRS_VAL_MULTIPLE="Множественный выбор" COM_ATTRS_VAL_FILTER="Фильтр данных" COM_ATTRS_CLASS="Класс поля" +COM_ATTRS_LAYOUT="Шаблон" +JOPTION_FROM_COMPONENT="---Из компонента---" +COM_ATTRS_LAYOUTS_LAYOUT_DEFAULT="По умолчанию" + COM_ATTRS_DEST="Принадлежность" COM_ATTRS_DEST_SYSTEM=" Система" COM_ATTRS_DEST_MENU=" Меню" diff --git a/com_attrs/layouts/default.php b/com_attrs/layouts/default.php new file mode 100644 index 0000000..9dd3375 --- /dev/null +++ b/com_attrs/layouts/default.php @@ -0,0 +1,8 @@ +form->getName())[0]; + + $component = preg_replace('#\W#', '', $component); + $client = ApplicationHelper::getClientInfo(0); + $client_administrator = ApplicationHelper::getClientInfo(1); + + $lang = Factory::getLanguage(); + $lang->load($component . '.sys', $client_administrator->path, null, false, true) || $lang->load($component . '.sys', $client_administrator->path . '/components/' . $component, null, false, true); + + $db = Factory::getDbo(); + $query = $db->getQuery(true); + + $query + ->select('element, name') + ->from('#__extensions as e') + ->where('e.client_id = 0') + ->where('e.type = ' . $db->quote('template')) + ->where('e.enabled = 1'); + + $db->setQuery($query); + $templates = $db->loadObjectList('element'); + + $component_path = Path::clean($client_administrator->path . '/components/' . $component . '/layouts'); + + $component_layouts = []; + + $groups = []; + + if (is_dir($component_path) && ($component_layouts = Folder::files($component_path, '^[^_]*\.php$'))) { + $groups['_'] = []; + $groups['_']['id'] = $this->id . '__'; + $groups['_']['text'] = Text::sprintf('JOPTION_FROM_COMPONENT'); + $groups['_']['items'] = []; + + foreach ($component_layouts as $file) { + $value = basename($file, '.php'); + $text = $lang->hasKey($key = strtoupper($component . '_LAYOUTS_LAYOUT_' . $value)) ? Text::_($key) : $value; + $groups['_']['items'][] = HTMLHelper::_('select.option', '_:' . $value, $text); + } + } + + if ($templates) { + foreach ($templates as $template) { + $lang->load('tpl_' . $template->element . '.sys', $client->path, null, false, true) || $lang->load('tpl_' . $template->element . '.sys', $client->path . '/templates/' . $template->element, null, false, true); + + $template_path = Path::clean($client->path . '/templates/' . $template->element . '/html/layouts/' . $component); + + if (is_dir($template_path) && ($files = Folder::files($template_path, '^[^_]*\.php$'))) { + foreach ($files as $i => $file) { + if (in_array($file, $component_layouts)) { + unset($files[$i]); + } + } + + if (count($files)) { + $groups[$template->element] = []; + $groups[$template->element]['id'] = $this->id . '_' . $template->element; + $groups[$template->element]['text'] = Text::sprintf('JOPTION_FROM_TEMPLATE', $template->name); + $groups[$template->element]['items'] = []; + + foreach ($files as $file) { + $value = basename($file, '.php'); + $text = $lang->hasKey($key = strtoupper('TPL_' . $template->element . '_' . $component . '_LAYOUTS_LAYOUT_' . $value)) ? Text::_($key) : $value; + $groups[$template->element]['items'][] = HTMLHelper::_('select.option', $template->element . ':' . $value, $text); + } + } + } + } + } + $attr = $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : ''; + $attr .= $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : ''; + + $html = []; + + $selected = [$this->value]; + + $html[] = HTMLHelper::_( + 'select.groupedlist', + $groups, + $this->name, + ['id' => $this->id, 'group.id' => 'id', 'list.attr' => $attr, 'list.select' => $selected] + ); + + return implode($html); + } +} diff --git a/com_attrs/models/forms/item.xml b/com_attrs/models/forms/item.xml index 22838fe..aee1ef3 100644 --- a/com_attrs/models/forms/item.xml +++ b/com_attrs/models/forms/item.xml @@ -1,6 +1,6 @@
-
+
@@ -22,6 +22,7 @@ + diff --git a/com_attrs/sql/install.mysql.utf8.sql b/com_attrs/sql/install.mysql.utf8.sql index 5e61582..9269d62 100644 --- a/com_attrs/sql/install.mysql.utf8.sql +++ b/com_attrs/sql/install.mysql.utf8.sql @@ -8,6 +8,7 @@ CREATE TABLE IF NOT EXISTS `#__attrs` ( `multiple` INT NOT NULL, `filter` VARCHAR(20) NOT NULL, `class` VARCHAR(50) NOT NULL, + `layout` VARCHAR(50) NOT NULL, `destsystem` TINYINT NOT NULL, `destmenu` TINYINT NOT NULL, `destusers` TINYINT NOT NULL, diff --git a/com_attrs/sql/updates/mysql/1.3.0.sql b/com_attrs/sql/updates/mysql/1.3.0.sql new file mode 100644 index 0000000..2806cd1 --- /dev/null +++ b/com_attrs/sql/updates/mysql/1.3.0.sql @@ -0,0 +1 @@ +ALTER TABLE `#__attrs` ADD `layout` VARCHAR(50) NOT NULL AFTER `class`; diff --git a/com_attrs/views/item/tmpl/edit.php b/com_attrs/views/item/tmpl/edit.php index 5ee0ccf..dcf9b45 100644 --- a/com_attrs/views/item/tmpl/edit.php +++ b/com_attrs/views/item/tmpl/edit.php @@ -66,6 +66,8 @@ form->renderField('filter'); ?> form->renderField('class'); ?> + + form->renderField('layout'); ?>
diff --git a/com_attrs/views/items/tmpl/default.php b/com_attrs/views/items/tmpl/default.php index 9859128..f8ae0ab 100644 --- a/com_attrs/views/items/tmpl/default.php +++ b/com_attrs/views/items/tmpl/default.php @@ -71,7 +71,14 @@ -
escape($item->name); ?>
+
+ escape($item->name); ?>,    + escape($item->layout); + $layout = !$layout || $layout === '_:default' ? Text::_('COM_ATTRS_LAYOUTS_LAYOUT_DEFAULT') : $layout; + echo $layout; + ?> +
diff --git a/pkg_attrs.xml b/pkg_attrs.xml index 5c969ff..90fa779 100644 --- a/pkg_attrs.xml +++ b/pkg_attrs.xml @@ -2,7 +2,7 @@ PKG_ATTRS attrs - 1.2.5 + 1.3.0 September 2019 Aleksey A. Morozov alekvolsk@yandex.ru @@ -18,8 +18,8 @@ language/ru-RU/ru-RU.pkg_attrs.sys.ini - com_attrs.zip - plg_system_attrs.zip + com_attrs + plg_system_attrs diff --git a/plg_system_attrs/attrs.php b/plg_system_attrs/attrs.php index bca7448..02a91d5 100644 --- a/plg_system_attrs/attrs.php +++ b/plg_system_attrs/attrs.php @@ -68,8 +68,9 @@ public function onContentPrepare($context, &$article, $params, $page = 0) $id = trim($matcheslist[2]); $attrName = trim($matcheslist[3]); + $template = isset($matcheslist[4]) ? (in_array(strtolower($matcheslist[4]), [0, '0', 'false'], true) ? false : $matcheslist[4]) : ''; - $output = AttrsHelper::getAttr($attrName, $type, $id); + $output = AttrsHelper::getAttr($attrName, $type, $id, $template); if (is_array($output)) { $output = implode(', ', $output); diff --git a/plg_system_attrs/attrs.xml b/plg_system_attrs/attrs.xml index 20001c7..5a38239 100644 --- a/plg_system_attrs/attrs.xml +++ b/plg_system_attrs/attrs.xml @@ -1,8 +1,8 @@ PLG_ATTRS - 1.2.4 - August 2019 + 1.3.0 + September 2019 Aleksey A. Morozov alekvolsk@yandex.ru https://alekvolsk.pw