File manager - Edit - /home/opticamezl/www/newok/builder-joomla.tar
Back
bootstrap.php 0000644 00000003400 15174774712 0007306 0 ustar 00 <?php namespace YOOtheme\Builder\Joomla; use Joomla\CMS\HTML\Helpers\Content; use YOOtheme\Builder; use YOOtheme\View; return [ 'routes' => [ ['post', '/page', PageController::class . '@savePage'], ['get', '/builder/pages', PageController::class . '@getPages'], ['post', '/builder/image', [BuilderController::class, 'loadImage']], ], 'actions' => [ 'onAfterRoute' => [ Listener\LoadSessionUser::class => '@handle', ], 'onLoadTemplate' => [ Listener\LoadSessionUser::class => ['@reset', 10], Listener\RenderBuilderButton::class => ['@handle', 10], ], 'onContentPrepare' => [ Listener\RenderBuilderPage::class => '@handle', ], 'onSchemaBeforeCompileHead' => [ Listener\LoadSessionUser::class => [['@handle', 10], ['@reset', -10]], ], ], 'extend' => [ View::class => function (View $view) { $view->addLoader(function ($name, $parameters, callable $next) { $content = $next($name, $parameters); return empty($parameters['prefix']) || $parameters['prefix'] !== 'page' ? Content::prepare($content) : $content; }, '*/builder/elements/layout/templates/template.php'); }, Builder::class => function (Builder $builder, $app) { $builder->addTypePath(__DIR__ . '/elements/*/element.json'); if ($childDir = $app->config->get('theme.childDir')) { $builder->addTypePath("{$childDir}/builder/*/element.json"); } }, ], 'services' => [ Listener\LoadSessionUser::class => '', Listener\RenderBuilderPage::class => '', ], ]; elements/breadcrumbs/element.json 0000644 00000007620 15174774712 0013221 0 ustar 00 { "name": "breadcrumbs", "title": "Breadcrumbs", "group": "system", "icon": "${url:images/icon.svg}", "iconSmall": "${url:images/iconSmall.svg}", "element": true, "width": 500, "defaults": { "show_home": true, "show_current": true }, "templates": { "render": "./templates/template.php" }, "fields": { "show_home": { "label": "Breadcrumbs", "description": "Show or hide the home link as first item as well as the current page as last item in the breadcrumb navigation.", "text": "Show home link", "type": "checkbox" }, "show_current": { "text": "Show current page", "type": "checkbox" }, "home_text": { "label": "Home Text", "description": "Enter the text for the home link.", "attrs": { "placeholder": "Home" }, "enable": "show_home" }, "position": "${builder.position}", "position_left": "${builder.position_left}", "position_right": "${builder.position_right}", "position_top": "${builder.position_top}", "position_bottom": "${builder.position_bottom}", "position_z_index": "${builder.position_z_index}", "blend": "${builder.blend}", "margin": "${builder.margin}", "margin_remove_top": "${builder.margin_remove_top}", "margin_remove_bottom": "${builder.margin_remove_bottom}", "text_align": "${builder.text_align}", "text_align_breakpoint": "${builder.text_align_breakpoint}", "text_align_fallback": "${builder.text_align_fallback}", "animation": "${builder.animation}", "_parallax_button": "${builder._parallax_button}", "visibility": "${builder.visibility}", "name": "${builder.name}", "status": "${builder.status}", "id": "${builder.id}", "class": "${builder.cls}", "css": { "label": "CSS", "description": "Enter your own custom CSS. The following selectors will be prefixed automatically for this element: <code>.el-element</code>", "type": "editor", "editor": "code", "mode": "css", "attrs": { "debounce": 500, "hints": [".el-element"] } } }, "fieldset": { "default": { "type": "tabs", "fields": [ { "title": "Settings", "fields": [ { "label": "Breadcrumbs", "type": "group", "divider": true, "fields": ["show_home", "show_current", "home_text"] }, { "label": "General", "type": "group", "fields": [ "position", "position_left", "position_right", "position_top", "position_bottom", "position_z_index", "blend", "margin", "margin_remove_top", "margin_remove_bottom", "text_align", "text_align_breakpoint", "text_align_fallback", "animation", "_parallax_button", "visibility" ] } ] }, "${builder.advanced}" ] } } } elements/breadcrumbs/templates/template.php 0000644 00000002213 15174774712 0015210 0 ustar 00 <?php namespace YOOtheme; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\Module\Breadcrumbs\Site\Helper\BreadcrumbsHelper; use Joomla\Registry\Registry; $rand = rand(); $marker = "<!-- breadcrumbs_{$rand} -->"; $render = function () use ($__dir, $attrs, $props) { // Get the breadcrumbs $params = new Registry([ 'showHome' => $props['show_home'], 'homeText' => Text::_($props['home_text'] ?: 'Home', 'yootheme'), ]); $items = BreadcrumbsHelper::getList($params, Factory::getApplication()); if (!$props['show_current']) { array_pop($items); } elseif ($items) { $items[count($items) - 1]->link = ''; } $props['items'] = $items; return $this->render("{$__dir}/template-breadcrumbs", compact('attrs', 'props')); }; if ($prefix === 'page') { app('dispatcher')->addListener('onLoadTemplate', function ($event) use ($render, $marker) { [$view] = $event->getArguments(); if ($output = $view->get('_output')) { $view->set('_output', str_replace($marker, $render(), $output)); } }); echo $marker; } else { echo $render(); } elements/breadcrumbs/templates/template-breadcrumbs.php 0000644 00000002467 15174774712 0017512 0 ustar 00 <?php $items = $props['items']; $el = $this->el('nav', [ 'aria-label' => 'Breadcrumb', ]); $list = $this->el('ul', [ 'class' => [ 'uk-breadcrumb uk-margin-remove-bottom', 'uk-flex-{text_align}[@{text_align_breakpoint} [uk-flex-{text_align_fallback}]]', ], 'vocab' => 'https://schema.org/', 'typeof' => 'BreadcrumbList', ]); $li = $this->el('li', [ 'property' => 'itemListElement', 'typeof' => 'ListItem', ]); $span = $this->el('span', ['property' => 'name']); $position = 1; ?> <?php if ($items) : ?> <?= $el($props, $attrs) ?> <?= $list($props) ?> <?php foreach ($items as $key => $item) : ?> <?php if (!empty($item->link)) : ?> <?= $li() ?> <a href="<?= $item->link ?>" property="item" typeof="WebPage"><?= $span([], $item->name) ?></a> <meta property="position" content="<?= $position++ ?>"> <?php elseif ($key !== array_key_last($items)) : ?> <li class="uk-disabled"> <span><?= $item->name ?></span> <?php else : ?> <?= $li() ?> <?= $span([], ['aria-current' => 'page'], $item->name) ?> <meta property="position" content="<?= $position++ ?>"> <?php endif ?> <?= $li->end() ?> <?php endforeach ?> <?= $list->end() ?> <?= $el->end() ?> <?php endif ?> elements/breadcrumbs/images/iconSmall.svg 0000644 00000000461 15174774712 0014600 0 ustar 00 <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <polygon fill="none" stroke="#444" points="5.5 13.5 0.5 13.5 0.5 6.5 5.5 6.5 8.5 10 5.5 13.5" /> <polygon fill="none" stroke="#444" points="15.5 13.5 8.5 13.5 11.5 10 8.5 6.5 15.5 6.5 18.5 10 15.5 13.5" /> </svg> elements/breadcrumbs/images/icon.svg 0000644 00000000454 15174774712 0013611 0 ustar 00 <svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"> <polygon fill="none" stroke="#444" stroke-width="2" points="7 20 1 20 1 10 7 10 12 15 7 20" /> <polygon fill="none" stroke="#444" stroke-width="2" points="23 20 13 20 18 15 13 10 23 10 28 15 23 20" /> </svg> elements/search/templates/template.php 0000644 00000005006 15174774712 0014167 0 ustar 00 <?php namespace YOOtheme; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use Joomla\Component\Finder\Site\Helper\RouteHelper; use Joomla\Module\Finder\Site\Helper\FinderHelper; $el = $this->el('div'); // Form $form = $this->el('form', [ 'role' => 'search', 'class' => [ 'uk-search', 'uk-search-default {@!search_style}', 'uk-search-{search_style}', 'uk-width-1-1', ], ]); // Search $search = $this->el('input', [ 'type' => 'search', 'placeholder' => Text::_('TPL_YOOTHEME_SEARCH'), 'class' => [ 'uk-search-input', 'uk-form-{search_size} {@!search_style}', ], 'required' => true, 'aria-label' => Text::_('TPL_YOOTHEME_SEARCH'), ]); // Icon $icon = $props['search_icon'] ? $this->el($props['search_icon'] == 'right' ? 'button' : 'span', [ 'uk-search-icon' => true, 'class' => [ 'uk-search-icon-flip {@search_icon: right}', ], ]) : null; if ($icon && $icon->name === 'button') { $icon->attr('type', 'submit'); } /** @var Config $config */ $config = app(Config::class); $input = Factory::getApplication()->input; if ($config('~theme.search_module') === 'mod_finder') { $route = Route::_(RouteHelper::getSearchRoute($config('~theme.com_finder_filter'))); $form->attr([ 'action' => $route, 'method' => 'get', ]); $search->attr([ 'name' => 'q', 'value' => $input->getCmd('option') === 'com_finder' ? urldecode(Factory::getApplication()->input->getString('q', '')) : '', ]); // With form method GET, we need to add hidden fields for the query parameters. $hidden = FinderHelper::getGetFields($route); } else { $form->attr([ 'action' => Route::_('index.php'), 'method' => 'post', ]); $search->attr([ 'name' => 'searchword', 'value' => $input->getCmd('option') === 'com_search' ? urldecode(Factory::getApplication()->input->getString('searchword', '')) : '', 'minlength' => '3', ]); $hidden = '<input type="hidden" name="task" value="search"><input type="hidden" name="option" value="com_search">'; } ?> <?= $el($props, $attrs) ?> <?= $form($props) ?> <?php if ($props['search_icon'] == 'left') : ?> <?= $icon($props, '') ?> <?php endif ?> <?= $search($props) ?> <?= $hidden ?> <?php if ($props['search_icon'] == 'right') : ?> <?= $icon($props, '') ?> <?php endif ?> <?= $form->end() ?> <?= $el->end() ?> elements/search/images/iconSmall.svg 0000644 00000000364 15174774713 0013557 0 ustar 00 <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <circle fill="none" stroke="#444" cx="8.23" cy="8.23" r="6.12" /> <line fill="none" stroke="#444" x1="17.59" y1="17.59" x2="12.56" y2="12.56" /> </svg> elements/search/images/icon.svg 0000644 00000000430 15174774713 0012560 0 ustar 00 <svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"> <circle fill="none" stroke="#444" stroke-width="2" cx="12.96" cy="13.08" r="8.58" /> <line fill="none" stroke="#444" stroke-width="2" x1="25.87" y1="25.99" x2="19.03" y2="19.15" /> </svg> elements/search/element.json 0000644 00000011173 15174774713 0012174 0 ustar 00 { "name": "search", "title": "Search", "group": "system", "icon": "${url:images/icon.svg}", "iconSmall": "${url:images/iconSmall.svg}", "element": true, "width": 500, "templates": { "render": "./templates/template.php" }, "fields": { "search_style": { "label": "Style", "description": "Set the search input style.", "type": "select", "options": { "Default": "", "Medium": "medium", "Large": "large" } }, "search_size": { "label": "Size", "description": "Set the search input size.", "type": "select", "options": { "Small": "small", "Default": "", "Large": "large" }, "enable": "!search_style" }, "search_icon": { "label": "Icon", "description": "Display a search icon on the left or right. The icon on the right can be clicked to submit the search.", "type": "select", "options": { "None": "", "Left (Not Clickable)": "left", "Right (Clickable)": "right" } }, "position": "${builder.position}", "position_left": "${builder.position_left}", "position_right": "${builder.position_right}", "position_top": "${builder.position_top}", "position_bottom": "${builder.position_bottom}", "position_z_index": "${builder.position_z_index}", "blend": "${builder.blend}", "margin": "${builder.margin}", "margin_remove_top": "${builder.margin_remove_top}", "margin_remove_bottom": "${builder.margin_remove_bottom}", "maxwidth": "${builder.maxwidth}", "maxwidth_breakpoint": "${builder.maxwidth_breakpoint}", "block_align": "${builder.block_align}", "block_align_breakpoint": "${builder.block_align_breakpoint}", "block_align_fallback": "${builder.block_align_fallback}", "animation": "${builder.animation}", "_parallax_button": "${builder._parallax_button}", "visibility": "${builder.visibility}", "name": "${builder.name}", "status": "${builder.status}", "id": "${builder.id}", "class": "${builder.cls}", "attributes": "${builder.attrs}", "css": { "label": "CSS", "description": "Enter your own custom CSS. The following selectors will be prefixed automatically for this element: <code>.el-element</code>", "type": "editor", "editor": "code", "mode": "css", "attrs": { "debounce": 500, "hints": [".el-element"] } }, "transform": "${builder.transform}" }, "fieldset": { "default": { "type": "tabs", "fields": [ { "title": "Settings", "fields": [ { "label": "Input", "type": "group", "divider": true, "fields": ["search_style", "search_size", "search_icon"] }, { "label": "General", "type": "group", "fields": [ "position", "position_left", "position_right", "position_top", "position_bottom", "position_z_index", "blend", "margin", "margin_remove_top", "margin_remove_bottom", "maxwidth", "maxwidth_breakpoint", "block_align", "block_align_breakpoint", "block_align_fallback", "text_align", "text_align_breakpoint", "text_align_fallback", "animation", "_parallax_button", "visibility" ] } ] }, "${builder.advanced}" ] } } } elements/module_position/templates/template.php 0000644 00000000104 15174774713 0016126 0 ustar 00 <?php $el = $this->el('div'); echo $el($props, $attrs, $content); elements/module_position/element.json 0000644 00000015476 15174774713 0014152 0 ustar 00 { "@import": "./element.php", "name": "module_position", "title": "Module Position", "group": "system", "icon": "${url:images/icon.svg}", "iconSmall": "${url:images/iconSmall.svg}", "element": true, "defaults": { "layout": "stack", "breakpoint": "m" }, "templates": { "render": "./templates/template.php" }, "fields": { "content": { "type": "select-position", "label": "Position", "description": "Select a Joomla module position that will render all published modules. It's recommended to use the builder-1 to -6 positions, which are not rendered elsewhere by the theme." }, "layout": { "type": "select", "label": "Layout", "description": "Select whether the modules should be aligned side by side or stacked above each other.", "default": "sidebar", "options": { "Stacked": "stack", "Grid": "grid" } }, "column_gap": { "label": "Column Gap", "description": "Set the size of the gap between the grid columns.", "type": "select", "options": { "Small": "small", "Medium": "medium", "Default": "", "Large": "large", "None": "collapse" } }, "row_gap": { "label": "Row Gap", "description": "Set the size of the gap between the grid rows.", "type": "select", "options": { "Small": "small", "Medium": "medium", "Default": "", "Large": "large", "None": "collapse" } }, "divider": { "label": "Divider", "description": "Show a divider between grid columns.", "type": "checkbox", "text": "Show dividers", "enable": "column_gap != 'collapse' && row_gap != 'collapse'" }, "breakpoint": { "type": "select", "label": "Breakpoint", "description": "Set the breakpoint from which grid items will stack.", "options": { "Small (Phone Landscape)": "s", "Medium (Tablet Landscape)": "m", "Large (Desktop)": "l", "X-Large (Large Screens)": "xl" } }, "vertical_align": { "type": "checkbox", "label": "Vertical Alignment", "description": "Vertically center grid items.", "text": "Center" }, "match": { "type": "checkbox", "label": "Match Height", "description": "Match the height of all modules which are styled as a card.", "text": "Match height" }, "position": "${builder.position}", "position_left": "${builder.position_left}", "position_right": "${builder.position_right}", "position_top": "${builder.position_top}", "position_bottom": "${builder.position_bottom}", "position_z_index": "${builder.position_z_index}", "blend": "${builder.blend}", "margin": "${builder.margin}", "margin_remove_top": "${builder.margin_remove_top}", "margin_remove_bottom": "${builder.margin_remove_bottom}", "maxwidth": "${builder.maxwidth}", "maxwidth_breakpoint": "${builder.maxwidth_breakpoint}", "block_align": "${builder.block_align}", "block_align_breakpoint": "${builder.block_align_breakpoint}", "block_align_fallback": "${builder.block_align_fallback}", "text_align": "${builder.text_align_justify}", "text_align_breakpoint": "${builder.text_align_breakpoint}", "text_align_fallback": "${builder.text_align_justify_fallback}", "animation": "${builder.animation}", "_parallax_button": "${builder._parallax_button}", "visibility": "${builder.visibility}", "name": "${builder.name}", "status": "${builder.status}", "id": "${builder.id}", "class": "${builder.cls}", "attributes": "${builder.attrs}", "css": { "label": "CSS", "description": "Enter your own custom CSS. The following selectors will be prefixed automatically for this element: <code>.el-element</code>", "type": "editor", "editor": "code", "mode": "css", "attrs": { "debounce": 500, "hints": [".el-element"] } }, "transform": "${builder.transform}" }, "fieldset": { "default": { "type": "tabs", "fields": [ { "title": "Content", "fields": ["content"] }, { "title": "Settings", "fields": [ { "label": "Grid", "type": "group", "divider": true, "fields": [ "layout", "column_gap", "row_gap", "divider", "breakpoint", "vertical_align", "match" ] }, { "label": "General", "type": "group", "fields": [ "position", "position_left", "position_right", "position_top", "position_bottom", "position_z_index", "blend", "margin", "margin_remove_top", "margin_remove_bottom", "maxwidth", "maxwidth_breakpoint", "block_align", "block_align_breakpoint", "block_align_fallback", "text_align", "text_align_breakpoint", "text_align_fallback", "animation", "_parallax_button", "visibility" ] } ] }, "${builder.advanced}" ] } } } elements/module_position/images/iconSmall.svg 0000644 00000001124 15174774713 0015516 0 ustar 00 <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <polyline fill="none" stroke="#444" points="1.5 15 1.5 18.5 5 18.5" /> <polyline fill="none" stroke="#444" points="16.5 13 16.5 18.5 13 18.5" /> <polyline fill="none" stroke="#444" points="1.5 7 1.5 3.5 6 3.5" /> <line fill="none" stroke="#444" x1="1.5" y1="9" x2="1.5" y2="13" /> <line fill="none" stroke="#444" x1="7" y1="18.5" x2="11" y2="18.5" /> <polygon fill="#444" points="19 1 19 9 17.66 9 17.66 3.5 14.45 8.2 11.35 3.5 11.35 9 10 9 10 1 11.35 1 14.45 5.7 17.55 1 19 1" /> </svg> elements/module_position/images/icon.svg 0000644 00000001175 15174774713 0014533 0 ustar 00 <svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"> <polyline fill="none" stroke="#444" stroke-width="2" points="3 22 3 27 8 27" /> <polyline fill="none" stroke="#444" stroke-width="2" points="25 19 25 27 20 27" /> <polyline fill="none" stroke="#444" stroke-width="2" points="3 10 3 5 9 5" /> <line fill="none" stroke="#444" stroke-width="2" x1="3" y1="13" x2="3" y2="19" /> <line fill="none" stroke="#444" stroke-width="2" x1="11" y1="27" x2="17" y2="27" /> <polygon fill="#444" points="28 1 28 13 26 13 26 4.7 21.5 11.8 17 4.7 17 13 15 13 15 1 17 1 21.5 8.1 26 1 28 1" /> </svg> elements/module_position/element.php 0000644 00000001652 15174774713 0013757 0 ustar 00 <?php use Joomla\CMS\Document\HtmlDocument; use Joomla\CMS\Factory; return [ 'transforms' => [ 'render' => function ($node) { /** @var HtmlDocument $document */ $document = Factory::getApplication()->getDocument(); $renderer = $document->loadRenderer('modules'); $position = $node->props['content'] ?? ''; // render module position if ($position && $document->countModules($position)) { $node->content = $renderer->render($position, [ 'style' => 'grid' . ($node->props['layout'] === 'stack' ? '-stack' : ''), 'position' => $node->props, // pass grid settings to templates/position.php ]); } // return false, if no module position content was found if (empty($node->content)) { return false; } }, ], ]; elements/module/element.php 0000644 00000003111 15174774713 0012023 0 ustar 00 <?php namespace YOOtheme; use Joomla\CMS\Document\HtmlDocument; use Joomla\CMS\Document\Renderer\Html\ModuleRenderer; use Joomla\CMS\Factory; use Joomla\CMS\Helper\ModuleHelper; return [ 'transforms' => [ 'render' => function ($node) { if (empty($node->props['module'])) { return false; } $module = ModuleHelper::getModuleById((string) $node->props['module']); $config = app(Config::class); $index = "~theme.modules.{$module->id}"; $props = $config->get($index, ['class' => []]); $node->attrs['class'] = array_merge($node->attrs['class'], $props['class']); $node->props = Arr::merge($props, $node->props); // override module config with props $config->set($index, $node->props); // make sure module gets re-rendered in Joomla 4+ unset($module->contentRendered); /** @var HtmlDocument $document */ $document = Factory::getApplication()->getDocument(); /** @var ModuleRenderer $renderer */ $renderer = $document->loadRenderer('module'); // render module content $node->module = (object) [ 'title' => $module->title, 'content' => $renderer->render($module), ]; // reset module config $config->set($index, $props); // return false, if no module content was found if (empty($node->module->content)) { return false; } }, ], ]; elements/module/images/iconSmall.svg 0000644 00000000476 15174774713 0013603 0 ustar 00 <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <polyline fill="none" stroke="#444" points="16.5 13 16.5 18.5 1.5 18.5 1.5 3.5 6 3.5" /> <polygon fill="#444" points="19 1 19 9 17.66 9 17.66 3.5 14.45 8.2 11.35 3.5 11.35 9 10 9 10 1 11.35 1 14.45 5.7 17.55 1 19 1" /> </svg> elements/module/images/icon.svg 0000644 00000000460 15174774713 0012603 0 ustar 00 <svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"> <polygon fill="#444" points="28 1 28 13 26 13 26 4.7 21.5 11.8 17 4.7 17 13 15 13 15 1 17 1 21.5 8.1 26 1 28 1" /> <polyline fill="none" stroke="#444" stroke-width="2" points="25 19 25 27 3 27 3 5 9 5" /> </svg> elements/module/templates/template.php 0000644 00000002111 15174774713 0014202 0 ustar 00 <?php $el = $this->el('div', [ 'class' => [ 'uk-panel {@!style}', 'uk-card uk-card-body uk-{style}', 'tm-child-list [tm-child-list-{list_style}] [uk-link-{link_style}] {@is_list}', ], ]); // Title $title = $this->el($props['title_tag'] ?: 'h3', [ 'class' => [ 'el-title', 'uk-[text-{@title_style: meta|lead}]{title_style}', 'uk-heading-{title_decoration}', 'uk-font-{title_font_family}', 'uk-card-title {@style} {@!title_style}', 'uk-text-{!title_color: |background}', ], ]); ?> <?= $el($props, $attrs) ?> <?php if ($props['showtitle']) : ?> <?= $title($props) ?> <?php if ($props['title_color'] == 'background') : ?> <span class="uk-text-background"><?= $module->title ?></span> <?php elseif ($props['title_decoration'] == 'line') : ?> <span><?= $module->title ?></span> <?php else: ?> <?= $module->title ?> <?php endif ?> <?= $title->end() ?> <?php endif ?> <?= $module->content ?> <?= $el->end() ?> elements/module/element.json 0000644 00000031257 15174774713 0012221 0 ustar 00 { "@import": "./element.php", "name": "module", "title": "Module", "group": "system", "icon": "${url:images/icon.svg}", "iconSmall": "${url:images/iconSmall.svg}", "element": true, "width": 500, "defaults": { "menu_style": "default", "menu_image_margin": true, "menu_image_align": "center" }, "updates": "./updates.php", "templates": { "render": "./templates/template.php" }, "fields": { "module": { "type": "select-module", "label": "Module", "description": "Any Joomla module can be displayed in your custom layout." }, "_edit_button": { "type": "button", "text": "Edit Module", "attrs": { "class": "uk-margin-medium-top uk-display-block" }, "event": "openEditModule", "enable": "module && yootheme.customizer.module.canCreate" }, "style": { "type": "select", "label": "Style", "description": "Select a panel style.", "options": { "None": "", "Card Default": "card-default", "Card Primary": "card-primary", "Card Secondary": "card-secondary", "Card Hover": "card-hover" } }, "title_style": { "type": "select", "label": "Style", "description": "Title styles differ in font-size but may also come with a predefined color, size and font.", "options": { "None": "", "Heading 3X-Large": "heading-3xlarge", "Heading 2X-Large": "heading-2xlarge", "Heading X-Large": "heading-xlarge", "Heading Large": "heading-large", "Heading Medium": "heading-medium", "Heading Small": "heading-small", "Heading H1": "h1", "Heading H2": "h2", "Heading H3": "h3", "Heading H4": "h4", "Heading H5": "h5", "Heading H6": "h6", "Text Meta": "meta", "Text Lead": "lead" } }, "title_decoration": { "type": "select", "label": "Decoration", "description": "Decorate the title with a divider, bullet or a line that is vertically centered to the heading.", "options": { "None": "", "Divider": "divider", "Bullet": "bullet", "Line": "line" } }, "title_font_family": { "label": "Font Family", "description": "Select an alternative font family. Mind that not all styles have different font families.", "type": "select", "options": { "None": "", "Default": "default", "Primary": "primary", "Secondary": "secondary", "Tertiary": "tertiary" } }, "title_color": { "type": "select", "label": "Color", "description": "Select the text color. If the background option is selected, styles that don't apply a background image use the primary color instead.", "options": { "None": "", "Muted": "muted", "Primary": "primary", "Success": "success", "Warning": "warning", "Danger": "danger", "Background": "background" } }, "list_style": { "label": "List Style", "description": "Select the list style.", "type": "select", "options": { "None": "", "Divider": "divider" }, "show": "$match(type, 'articles_(archive|categories|latest|popular)|tags_(popular|similar)')" }, "link_style": { "label": "Link Style", "description": "Select the link style.", "type": "select", "options": { "None": "", "Muted": "muted" }, "show": "$match(type, 'articles_(archive|categories|latest|popular)|tags_(popular|similar)')" }, "menu_type": { "label": "Type", "description": "Select the menu type.", "type": "select", "default": "nav", "options": { "Nav": "nav", "Subnav": "subnav", "Iconnav": "iconnav" }, "show": "$match(type, 'menu')" }, "menu_divider": { "label": "Divider", "description": "Show optional dividers between nav or subnav items.", "type": "checkbox", "text": "Show dividers", "show": "$match(type, 'menu')" }, "menu_style": { "label": "Style", "description": "Select the nav style.", "type": "select", "options": { "Default": "default", "Primary": "primary", "Secondary": "secondary" }, "show": "$match(type, 'menu')" }, "menu_size": { "label": "Primary Size", "description": "Select the primary nav size.", "type": "select", "options": { "Default": "", "Medium": "medium", "Large": "large", "X-Large": "xlarge" }, "show": "$match(type, 'menu')", "enable": "menu_style == 'primary'" }, "menu_image_width": { "attrs": { "placeholder": "auto" }, "show": "$match(type, 'menu')" }, "menu_image_height": { "attrs": { "placeholder": "auto" }, "show": "$match(type, 'menu')" }, "menu_image_svg_inline": { "label": "Inline SVG", "description": "Inject SVG images into the markup so they adopt the text color automatically.", "type": "checkbox", "text": "Make SVG stylable with CSS", "show": "$match(type, 'menu')" }, "menu_icon_width": { "label": "Icon Width", "description": "Set the icon width.", "show": "$match(type, 'menu')" }, "menu_image_margin": { "label": "Image and Title", "type": "checkbox", "text": "Add margin between", "show": "$match(type, 'menu')" }, "menu_image_align": { "label": "Image Align", "type": "select", "options": { "Top": "top", "Center": "center" }, "show": "$match(type, 'menu')" }, "position": "${builder.position}", "position_left": "${builder.position_left}", "position_right": "${builder.position_right}", "position_top": "${builder.position_top}", "position_bottom": "${builder.position_bottom}", "position_z_index": "${builder.position_z_index}", "blend": "${builder.blend}", "margin": "${builder.margin}", "margin_remove_top": "${builder.margin_remove_top}", "margin_remove_bottom": "${builder.margin_remove_bottom}", "maxwidth": "${builder.maxwidth}", "maxwidth_breakpoint": "${builder.maxwidth_breakpoint}", "block_align": "${builder.block_align}", "block_align_breakpoint": "${builder.block_align_breakpoint}", "block_align_fallback": "${builder.block_align_fallback}", "text_align": "${builder.text_align_justify}", "text_align_breakpoint": "${builder.text_align_breakpoint}", "text_align_fallback": "${builder.text_align_justify_fallback}", "animation": "${builder.animation}", "_parallax_button": "${builder._parallax_button}", "visibility": "${builder.visibility}", "name": "${builder.name}", "status": "${builder.status}", "id": "${builder.id}", "class": "${builder.cls}", "attributes": "${builder.attrs}", "css": { "label": "CSS", "description": "Enter your own custom CSS. The following selectors will be prefixed automatically for this element: <code>.el-element</code>, <code>.el-title</code>", "type": "editor", "editor": "code", "mode": "css", "attrs": { "debounce": 500 } }, "transform": "${builder.transform}" }, "fieldset": { "default": { "type": "tabs", "fields": [ { "title": "Content", "fields": ["module", "_edit_button"] }, { "title": "Settings", "fields": [ { "label": "Panel", "type": "group", "divider": true, "fields": ["style"] }, { "label": "Title", "type": "group", "divider": true, "fields": [ "title_style", "title_decoration", "title_font_family", "title_color" ] }, { "label": "List", "type": "group", "divider": true, "fields": [ "list_style", "link_style" ], "show": "$match(type, 'articles_(archive|categories|latest|popular)|tags_(popular|similar)')" }, { "label": "Menu", "type": "group", "divider": true, "fields": [ "menu_type", "menu_divider", "menu_style", "menu_size", { "label": "Image Width/Height", "description": "Setting just one value preserves the original proportions. The image will be resized and cropped automatically, and where possible, high resolution images will be auto-generated.", "type": "grid", "width": "1-2", "fields": ["menu_image_width", "menu_image_height"] }, "menu_image_svg_inline", "menu_icon_width", "menu_image_margin", "menu_image_align" ], "show": "$match(type, 'menu')" }, { "label": "General", "type": "group", "fields": [ "position", "position_left", "position_right", "position_top", "position_bottom", "position_z_index", "blend", "margin", "margin_remove_top", "margin_remove_bottom", "maxwidth", "maxwidth_breakpoint", "block_align", "block_align_breakpoint", "block_align_fallback", "text_align", "text_align_breakpoint", "text_align_fallback", "animation", "_parallax_button", "visibility" ] } ] }, "${builder.advanced}" ] } } } elements/module/updates.php 0000644 00000000240 15174774713 0012037 0 ustar 00 <?php namespace YOOtheme; return [ '3.0.0-beta.1.5' => function ($node) { Arr::updateKeys($node->props, ['menu_style' => 'menu_type']); }, ]; config/customizer.json 0000644 00000114607 15174774713 0011141 0 ustar 00 { "sections": { "builder-pages": { "title": "Pages", "heading": false, "priority": 19 } }, "panels": { "builder": { "help": { "Builder": [ { "title": "Using the Page Builder", "src": "https://www.youtube-nocookie.com/watch?v=gPGmv-O1f-I&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:27", "documentation": "support/yootheme-pro/joomla/page-builder#page-builder", "support": "support/search?tags=125&q=builder" }, { "title": "Understanding the Layout Structure", "src": "https://www.youtube-nocookie.com/watch?v=ahP4rEXBnIM&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:57", "documentation": "support/yootheme-pro/joomla/page-builder#layout-structure", "support": "support/search?tags=125&q=layout%20structure" }, { "title": "Managing Sections, Rows and Elements", "src": "https://www.youtube-nocookie.com/watch?v=WBju-Frb0Vg&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:04", "documentation": "support/yootheme-pro/joomla/page-builder#actions", "support": "support/search?tags=125&q=builder%20action" }, { "title": "Using the Element Finder", "src": "https://www.youtube-nocookie.com/watch?v=GisyKeSWtsU&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:43", "documentation": "support/yootheme-pro/joomla/page-builder#element-finder", "support": "support/search?tags=125&q=builder%20element%20finder" }, { "title": "Ordering Sections, Rows and Elements", "src": "https://www.youtube-nocookie.com/watch?v=oWBCd3QBPrU&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:23", "documentation": "support/yootheme-pro/joomla/page-builder#ordering", "support": "support/search?tags=125&q=builder%20ordering" }, { "title": "Understanding Status Icons", "src": "https://www.youtube-nocookie.com/watch?v=cWPuhs4KrtQ&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "3:22", "documentation": "support/yootheme-pro/joomla/page-builder#status-icons", "support": "support/search?tags=125&q=builder%20status%20icon" }, { "title": "Working with Multiple Authors", "src": "https://www.youtube-nocookie.com/watch?v=vv3IWfviGzc&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:38", "documentation": "support/yootheme-pro/joomla/page-builder#multi-author-workflow", "support": "support/search?tags=125&q=overwriting%20layout" }, { "title": "Collapsing Layouts", "src": "https://www.youtube-nocookie.com/watch?v=UT6PODf7p3o&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:44", "documentation": "support/yootheme-pro/joomla/collapsing-layouts", "support": "support/search?tags=125&q=collapsing" }, { "title": "Learning Layout Techniques", "src": "https://www.youtube-nocookie.com/watch?v=z4kw04hhJdo&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:09", "documentation": "support/yootheme-pro/joomla/element-library#layout-techniques", "support": "support/search?tags=125&q=layout%20techniques" } ], "Images and Links": [ { "title": "Using Images", "src": "https://www.youtube-nocookie.com/watch?v=NHpFpn4UiUM&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "4:37", "documentation": "support/yootheme-pro/joomla/files-and-images#images", "support": "support/search?tags=125&q=image%20field" }, { "title": "Using Links", "src": "https://www.youtube-nocookie.com/watch?v=EUNGRsyT1ak&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:40", "documentation": "support/yootheme-pro/joomla/files-and-images#links", "support": "support/search?tags=125&q=link%20field" }, { "title": "Using the Media Manager", "src": "https://www.youtube-nocookie.com/watch?v=2Sgp4BBMTc8&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:32", "documentation": "support/yootheme-pro/joomla/files-and-images#media-manager", "support": "support/search?tags=125&q=media%20manager" }, { "title": "Using the Unsplash Library", "src": "https://www.youtube-nocookie.com/watch?v=6piYezAI4dU&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:50", "documentation": "support/yootheme-pro/joomla/files-and-images#unsplash-library", "support": "support/search?tags=125&q=unsplash" } ], "Layout Library": [ { "title": "Using Pro Layouts", "src": "https://www.youtube-nocookie.com/watch?v=OvTVcRBW99A&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU", "duration": "1:26", "documentation": "support/yootheme-pro/joomla/layout-library#pro-layouts", "support": "support/search?tags=125&q=pro%20layouts" }, { "title": "Using My Layouts", "src": "https://www.youtube-nocookie.com/watch?v=qKN8RME_q60&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:27", "documentation": "support/yootheme-pro/joomla/layout-library#my-layouts", "support": "support/search?tags=125&q=my%20layouts" }, { "title": "Loading Layouts", "src": "https://www.youtube-nocookie.com/watch?v=r7wJq7E2jCU&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:30", "documentation": "support/yootheme-pro/joomla/layout-library#loading-layouts", "support": "support/search?tags=125&q=loading%20layout" } ], "Element Library": [ { "title": "Using Elements", "src": "https://www.youtube-nocookie.com/watch?v=vj0Eg-hOvoM&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:45", "documentation": "support/yootheme-pro/joomla/element-library#elements", "support": "support/search?tags=125&q=elements" }, { "title": "Using Pro Presets", "src": "https://www.youtube-nocookie.com/watch?v=wRTD3Y0bvAM&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:01", "documentation": "support/yootheme-pro/joomla/element-library#pro-presets", "support": "support/search?tags=125&q=pro%20presets" }, { "title": "Using My Presets", "src": "https://www.youtube-nocookie.com/watch?v=m3v75Sb6ruQ&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:18", "documentation": "support/yootheme-pro/joomla/element-library#my-presets", "support": "support/search?tags=125&q=my%20presets" }, { "title": "The Alert Element", "src": "https://www.youtube-nocookie.com/watch?v=yGaSNRv6FIg&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:18", "documentation": "support/yootheme-pro/joomla/basic-elements#alert-element", "support": "support/search?tags=125&q=alert%20element" }, { "title": "The Code Element", "src": "https://www.youtube-nocookie.com/watch?v=82UaWdmY-d8&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:35", "documentation": "support/yootheme-pro/joomla/basic-elements#code-element", "support": "support/search?tags=125&q=code%20element" }, { "title": "The Countdown Element", "src": "https://www.youtube-nocookie.com/watch?v=TyHQjc6hhb8&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:58", "documentation": "support/yootheme-pro/joomla/basic-elements#countdown-element", "support": "support/search?tags=125&q=countdown%20element" }, { "title": "The Divider Element", "src": "https://www.youtube-nocookie.com/watch?v=iWNJ4ljupws&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:39", "documentation": "support/yootheme-pro/joomla/basic-elements#divider-element", "support": "support/search?tags=125&q=divider%20element" }, { "title": "The Headline Element", "src": "https://www.youtube-nocookie.com/watch?v=vEcEB0I433o&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:18", "documentation": "support/yootheme-pro/joomla/basic-elements#headline-element", "support": "support/search?tags=125&q=headline%20element" }, { "title": "The Icon Element", "src": "https://www.youtube-nocookie.com/watch?v=SXO8OTCK8so&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:01", "documentation": "support/yootheme-pro/joomla/basic-elements#icon-element", "support": "support/search?tags=125&q=icon%20element" }, { "title": "The Image Element", "src": "https://www.youtube-nocookie.com/watch?v=_mcjMQPN2tQ&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:37", "documentation": "support/yootheme-pro/joomla/basic-elements#image-element", "support": "support/search?tags=125&q=image%20element" }, { "title": "The Newsletter Element", "src": "https://www.youtube-nocookie.com/watch?v=FUPzn8pZAtM&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:20", "documentation": "support/yootheme-pro/joomla/basic-elements#newsletter-element", "support": "support/search?tags=125&q=newsletter%20element" }, { "title": "The Overlay Element", "src": "https://www.youtube-nocookie.com/watch?v=CaskgXO23yw&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "5:41", "documentation": "support/yootheme-pro/joomla/basic-elements#overlay-element", "support": "support/search?tags=125&q=overlay%20element" }, { "title": "The Panel Element", "src": "https://www.youtube-nocookie.com/watch?v=LrTd3WpeCac&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "3:35", "documentation": "support/yootheme-pro/joomla/basic-elements#panel-element", "support": "support/search?tags=125&q=panel%20element" }, { "title": "The Quotation Element", "src": "https://www.youtube-nocookie.com/watch?v=qTIZHbYQje8&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:52", "documentation": "support/yootheme-pro/joomla/basic-elements#quotation-element", "support": "support/search?tags=125&q=quotation%20element" }, { "title": "The Sublayout Element", "src": "https://www.youtube-nocookie.com/watch?v=BXCv59Wp9Z4&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:53", "documentation": "support/yootheme-pro/joomla/basic-elements#sublayout-element", "support": "support/search?tags=125&q=sublayout%20element" }, { "title": "The Text Element", "src": "https://www.youtube-nocookie.com/watch?v=IkJgm2c4w5E&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:17", "documentation": "support/yootheme-pro/joomla/basic-elements#text-element", "support": "support/search?tags=125&q=text%20element" }, { "title": "The Totop Element", "src": "https://www.youtube-nocookie.com/watch?v=3sQUAwbasI4&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:33", "documentation": "support/yootheme-pro/joomla/basic-elements#totop-element", "support": "support/search?tags=125&q=totop%20element" }, { "title": "The Video Element", "src": "https://www.youtube-nocookie.com/watch?v=GhnVRXG7les&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:30", "documentation": "support/yootheme-pro/joomla/basic-elements#video-element", "support": "support/search?tags=125&q=video%20element" }, { "title": "The Accordion Element", "src": "https://www.youtube-nocookie.com/watch?v=sbqNaJVA49g&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:03", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#accordion-element", "support": "support/search?tags=125&q=accordion%20element" }, { "title": "The Button Element", "src": "https://www.youtube-nocookie.com/watch?v=5f0GyiDTXdM&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:01", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#button-element", "support": "support/search?tags=125&q=button%20element" }, { "title": "The Description List Element", "src": "https://www.youtube-nocookie.com/watch?v=1QdPBTcgOTc&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:34", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#description-list-element", "support": "support/search?tags=125&q=description-list%20element" }, { "title": "The Gallery Element", "src": "https://www.youtube-nocookie.com/watch?v=QrY8WGLIk5Y&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "5:15", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#gallery-element", "support": "support/search?tags=125&q=gallery%20element" }, { "title": "The Grid Element", "src": "https://www.youtube-nocookie.com/watch?v=5viHNXg8TT8&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "5:10", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#grid-element", "support": "support/search?tags=125&q=grid%20element" }, { "title": "The List Element", "src": "https://www.youtube-nocookie.com/watch?v=2EdPTQyAj4U&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:26", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#list-element", "support": "support/search?tags=125&q=list%20element" }, { "title": "The Map Element", "src": "https://www.youtube-nocookie.com/watch?v=ihAyS7Ln9RA&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "5:00", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#map-element", "support": "support/search?tags=125&q=map%20element" }, { "title": "The Nav Element", "src": "https://www.youtube-nocookie.com/watch?v=b7ZsXD-Ki_U&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:32", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#nav-element", "support": "support/search?tags=125&q=nav%20element" }, { "title": "The Overlay Slider Element", "src": "https://www.youtube-nocookie.com/watch?v=svfBwp0z7ww&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "4:16", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#overlay-slider-element", "support": "support/search?tags=125&q=overlay-slider%20element" }, { "title": "The Panel Slider Element", "src": "https://www.youtube-nocookie.com/watch?v=B5bFBrK_nMY&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "4:24", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#panel-slider-element", "support": "support/search?tags=125&q=panel-slider%20element" }, { "title": "The Popover Element", "src": "https://www.youtube-nocookie.com/watch?v=3q2uvJhqEcs&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "3:19", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#popover-element", "support": "support/search?tags=125&q=popover%20element" }, { "title": "The Slideshow Element", "src": "https://www.youtube-nocookie.com/watch?v=jEDBLkGfIjU&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "6:20", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#slideshow-element", "support": "support/search?tags=125&q=slideshow%20element" }, { "title": "The Social Element", "src": "https://www.youtube-nocookie.com/watch?v=0U5rHTknT7A&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:32", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#social-element", "support": "support/search?tags=125&q=social%20element" }, { "title": "The Subnav Element", "src": "https://www.youtube-nocookie.com/watch?v=llyT8HFaXhM&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:33", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#subnav-element", "support": "support/search?tags=125&q=subnav%20element" }, { "title": "The Switcher Element", "src": "https://www.youtube-nocookie.com/watch?v=fqtWROEKM_o&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "3:58", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#switcher-element", "support": "support/search?tags=125&q=switcher%20element" }, { "title": "The Table Element", "src": "https://www.youtube-nocookie.com/watch?v=0KGSGKEItPo&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "3:01", "documentation": "support/yootheme-pro/joomla/multiple-items-elements#table-element", "support": "support/search?tags=125&q=table%20element" }, { "title": "The Breadcrumbs Element", "src": "https://www.youtube-nocookie.com/watch?v=EBaGuYvm14Q&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:48", "documentation": "support/yootheme-pro/joomla/system-elements#breadcrumbs-element", "support": "support/search?tags=125&q=breadcrumbs%20element" }, { "title": "The Module Element", "src": "https://www.youtube-nocookie.com/watch?v=kIwXpttCD8g&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:48", "documentation": "support/yootheme-pro/joomla/system-elements#module-element", "support": "support/search?tags=125&q=module%20element" }, { "title": "The Position Element", "src": "https://www.youtube-nocookie.com/watch?v=_LUvr_31n44&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:40", "documentation": "support/yootheme-pro/joomla/system-elements#position-element", "support": "support/search?tags=125&q=position%20element" }, { "title": "The Search Element", "src": "https://www.youtube-nocookie.com/watch?v=1BqIOOabndQ&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:46", "documentation": "support/yootheme-pro/joomla/system-elements#search-element", "support": "support/search?tags=125&q=search%20element" }, { "title": "The Pagination Element", "src": "https://www.youtube-nocookie.com/watch?v=pehfrOcnVLA&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:37", "documentation": "support/yootheme-pro/joomla/system-elements#pagination-element", "support": "support/search?tags=125&q=pagination%20element" } ], "Sections": [ { "title": "Section Style", "src": "https://www.youtube-nocookie.com/watch?v=QDPcpg6p61U&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:53", "documentation": "support/yootheme-pro/joomla/sections#background", "support": "support/search?tags=125&q=section%20style" }, { "title": "Section Image and Video", "src": "https://www.youtube-nocookie.com/watch?v=w_b7cyPxkvE&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "3:16", "documentation": "support/yootheme-pro/joomla/sections#image-and-video", "support": "support/search?tags=125&q=section%20image" }, { "title": "Section Width", "src": "https://www.youtube-nocookie.com/watch?v=845DEeI453c&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:33", "documentation": "support/yootheme-pro/joomla/sections#width", "support": "support/search?tags=125&q=section%20width" }, { "title": "Section Height", "src": "https://www.youtube-nocookie.com/watch?v=ebsJftwWOH4&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:19", "documentation": "support/yootheme-pro/joomla/sections#height", "support": "support/search?tags=125&q=section%20height" }, { "title": "Section Padding", "src": "https://www.youtube-nocookie.com/watch?v=p3Vy1yiFL9w&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:50", "documentation": "support/yootheme-pro/joomla/sections#padding", "support": "support/search?tags=125&q=section%20padding" }, { "title": "Sticky Effect", "src": "https://www.youtube-nocookie.com/watch?v=GlOi6Xb56_E&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:48", "documentation": "support/yootheme-pro/joomla/sections#sticky", "support": "support/search?tags=125&q=section%20sticky" }, { "title": "Transparent Header", "src": "https://www.youtube-nocookie.com/watch?v=fhDFf7YBPdsw&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:53", "documentation": "support/yootheme-pro/joomla/sections#transparent-header", "support": "support/search?tags=125&q=transparent%20header" }, { "title": "Section Animation", "src": "https://www.youtube-nocookie.com/watch?v=d4RgsgId7Og&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:34", "documentation": "support/yootheme-pro/joomla/sections#animation", "support": "support/search?tags=125&q=section%20animation" }, { "title": "Section Title", "src": "https://www.youtube-nocookie.com/watch?v=RRN1lJ2Lx14w&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:01", "documentation": "support/yootheme-pro/joomla/sections#title", "support": "support/search?tags=125&q=section%20title" } ], "Dynamic Content": [ { "title": "Using Content Sources", "src": "https://www.youtube-nocookie.com/watch?v=snuMovT0gj8&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:43", "documentation": "support/yootheme-pro/joomla/dynamic-content#content-sources", "support": "support/search?tags=125&q=source" }, { "title": "Using Page Sources", "src": "https://www.youtube-nocookie.com/watch?v=OPc6CPFhHh8&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:14", "documentation": "support/yootheme-pro/joomla/dynamic-content#page-sources", "support": "support/search?tags=125&q=page%20source" }, { "title": "Using Custom Sources", "src": "https://www.youtube-nocookie.com/watch?v=bHfKP1rDFyc&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "5:46", "documentation": "support/yootheme-pro/joomla/dynamic-content#custom-sources", "support": "support/search?tags=125&q=custom%20source" }, { "title": "Using External Sources", "src": "https://www.youtube-nocookie.com/watch?v=bCgewm7_PUU&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:16", "documentation": "support/yootheme-pro/joomla/dynamic-content#external-sources", "support": "support/search?tags=125&q=external%20source" }, { "title": "Using Site Sources", "src": "https://www.youtube-nocookie.com/watch?v=_43JH-gvs0s&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:01", "documentation": "support/yootheme-pro/joomla/dynamic-content#site-sources", "support": "support/search?tags=125&q=site%20source" }, { "title": "Using Parent Sources", "src": "https://www.youtube-nocookie.com/watch?v=AMeWesuA0H4&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "3:54", "documentation": "support/yootheme-pro/joomla/dynamic-content#parent-sources", "support": "support/search?tags=125&q=parent%20source" }, { "title": "Using Dynamic Multiplication", "src": "https://www.youtube-nocookie.com/watch?v=O-kuq1l8uhk&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "6:49", "documentation": "support/yootheme-pro/joomla/dynamic-content#multiplication", "support": "support/search?tags=125&q=multiplication" }, { "title": "Setting the Source Order and Direction", "src": "https://www.youtube-nocookie.com/watch?v=Jk7MCXm7uQI&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:02", "documentation": "support/yootheme-pro/joomla/dynamic-content#order-and-direction", "support": "support/search?tags=125&q=source%20order" }, { "title": "Using Related Sources", "src": "https://www.youtube-nocookie.com/watch?v=ziozc_tfqyg&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "7:44", "documentation": "support/yootheme-pro/joomla/dynamic-content#related-sources", "support": "support/search?tags=125&q=related%20source" }, { "title": "Mapping Fields", "src": "https://www.youtube-nocookie.com/watch?v=I9HnYh8GruY&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:22", "documentation": "support/yootheme-pro/joomla/dynamic-content#field-mapping", "support": "support/search?tags=125&q=field" }, { "title": "Using Content Fields", "src": "https://www.youtube-nocookie.com/watch?v=rhR3hkQ0LL0&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "2:09", "documentation": "support/yootheme-pro/joomla/dynamic-content#content-fields", "support": "support/search?tags=125&q=field" }, { "title": "Using Custom Fields", "src": "https://www.youtube-nocookie.com/watch?v=E2QsGRHWAnc&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:32", "documentation": "support/yootheme-pro/joomla/dynamic-content#custom-fields", "support": "support/search?tags=125&q=custom%20fields" }, { "title": "Using Dynamic Conditions", "src": "https://www.youtube-nocookie.com/watch?v=_ydI40op2fA&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:23", "documentation": "support/yootheme-pro/joomla/dynamic-content#dynamic-conditions", "support": "support/search?tags=125&q=dynamic%20conditions" } ], "Dynamic Content Field Options": [ { "title": "Using the Before and After Field Options", "src": "https://www.youtube-nocookie.com/watch?v=O2GIOZGim5k&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:40", "documentation": "support/yootheme-pro/joomla/dynamic-content#before-and-after", "support": "support/search?tags=125&q=field%20Before%20After" }, { "title": "Using the Search and Replace Field Options", "src": "https://www.youtube-nocookie.com/watch?v=_SzEJ8596m0&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "1:25", "documentation": "support/yootheme-pro/joomla/dynamic-content#search-and-replace", "support": "support/search?tags=125&q=field%20Search%20Replace" }, { "title": "Using the Content Length Field Option", "src": "https://www.youtube-nocookie.com/watch?v=sKiqXDhKPp4&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:23", "documentation": "support/yootheme-pro/joomla/dynamic-content#content-length", "support": "support/search?tags=125&q=field%20length" }, { "title": "Using the Date Format Field Option", "src": "https://www.youtube-nocookie.com/watch?v=ChJ6WxkOEtI&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:31", "documentation": "support/yootheme-pro/joomla/dynamic-content#date-format", "support": "support/search?tags=125&q=field%20date" }, { "title": "Using the Teaser Field Options", "src": "https://www.youtube-nocookie.com/watch?v=MM6a8GEf6J8&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:25", "documentation": "support/yootheme-pro/joomla/dynamic-content#teaser-field", "support": "support/search?tags=125&q=field%20teaser" }, { "title": "Using the Meta Field Options", "src": "https://www.youtube-nocookie.com/watch?v=43das8dQiIk&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:58", "documentation": "support/yootheme-pro/joomla/dynamic-content#meta-field", "support": "support/search?tags=125&q=field%20meta" }, { "title": "Using the Tags Field Options", "src": "https://www.youtube-nocookie.com/watch?v=IrUqG2AfkfI&list=PLrqT0WH0HPdPfykSwhMt6Jl2_RgJ6ixU-", "duration": "0:32", "documentation": "support/yootheme-pro/joomla/dynamic-content#tags-field", "support": "support/search?tags=125&q=field%20tags" } ] } } } } src/Listener/RenderBuilderPage.php 0000644 00000005266 15174774713 0013205 0 ustar 00 <?php namespace YOOtheme\Builder\Joomla\Listener; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use Joomla\CMS\Uri\Uri; use YOOtheme\Builder; use YOOtheme\Builder\Joomla\ArticleHelper; use YOOtheme\Config; class RenderBuilderPage { public bool $first = true; public Config $config; public Builder $builder; public CMSApplication $joomla; public function __construct(Config $config, Builder $builder, CMSApplication $joomla) { $this->config = $config; $this->builder = $builder; $this->joomla = $joomla; } public function handle($event): void { $context = $event->getArgument('context'); $article = $event->getArgument('subject'); $params = $event->getArgument('params'); if ( !$this->first || !ArticleHelper::isArticleView() || $context !== 'com_content.article' ) { return; } // Make sure this is executed only once $this->first = false; $content = ArticleHelper::matchContent($article->fulltext); if ($params->get('access-edit') && $this->config->get('app.isCustomizer')) { if ($page = $this->config->get('req.customizer.page')) { $content = !empty($page['content']) ? json_encode($page['content']) : null; } $this->config->add('customizer.page', [ 'id' => $article->id, 'title' => $article->title, 'content' => $content ? $this->builder->load($content) : $content, 'preview' => !empty($page), 'collision' => ArticleHelper::getCollision($article), ]); } if ($content) { /** * Redirect to login page if access-view is false. */ if (!$params->get('access-view')) { $this->joomla->enqueueMessage(Text::_('JERROR_ALERTNOAUTHOR'), 'notice'); $this->joomla->redirect( Route::_( 'index.php?option=com_users&view=login&return=' . base64_encode(Uri::getInstance()), ), 403, ); } // Render builder output $article->text = $this->builder->render($content, [ 'prefix' => 'page', 'article' => $article, 'template' => 'com_content.article', ]) ?? ''; // Used to determine active builder layout in html/helpers.php $this->config->set('app.isBuilder', true); } } } src/Listener/LoadSessionUser.php 0000644 00000003060 15174774713 0012732 0 ustar 00 <?php namespace YOOtheme\Builder\Joomla\Listener; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Factory; use Joomla\CMS\Session\Session; use Joomla\CMS\User\User; use YOOtheme\Builder\Joomla\ArticleHelper; use YOOtheme\Config; class LoadSessionUser { public ?User $user = null; public Config $config; public Session $session; public CMSApplication $joomla; public function __construct(Config $config, Session $session, CMSApplication $joomla) { $this->joomla = $joomla; $this->config = $config; $this->session = $session; } public function handle(): void { if ( ArticleHelper::isArticleView() && $this->config->get('req.customizer.admin') && ($user_id = $this->config->get('req.customizer.user_id')) ) { $this->user = Factory::getUser(); $this->setCurrentUser(Factory::getUser($user_id)); } } public function reset(): void { if ($this->user) { $this->setCurrentUser($this->user); } } protected function setCurrentUser($user) { // If user with given id can't be found, Joomla will throw exception if (!isset($user->id)) { return; } $this->session->set('user', $user); if (method_exists($this->joomla, 'loadIdentity')) { $this->joomla->loadIdentity($user); // Set the flag indicating that MFA is already checked. $this->session->set('com_users.mfa_checked', 1); } } } src/Listener/RenderBuilderButton.php 0000644 00000002601 15174774713 0013572 0 ustar 00 <?php namespace YOOtheme\Builder\Joomla\Listener; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use Joomla\CMS\Uri\Uri; use Joomla\Component\Content\Site\Helper\RouteHelper; use YOOtheme\Config; class RenderBuilderButton { public Config $config; public function __construct(Config $config) { $this->config = $config; } public function handle($event): void { if (!$this->config->get('app.isBuilder')) { return; } [$view] = $event->getArguments(); $layout = $view->getLayout(); $context = $view->get('context'); if ($context !== 'com_content.article' || $layout !== 'default') { return; } $article = $view->get('item'); $content = $article->text; if ($article->params->get('access-edit') && !$this->config->get('app.isCustomizer')) { $url = Route::_( RouteHelper::getFormRoute($article->id) . '&return=' . base64_encode(Uri::getInstance()), ); $content .= "<a style=\"position: fixed!important\" class=\"uk-position-medium uk-position-bottom-right uk-position-z-index uk-button uk-button-primary\" href=\"{$url}\">" . Text::_('JACTION_EDIT') . '</a>'; } $view->set('_output', $content); } } src/BuilderController.php 0000644 00000010203 15174774713 0011512 0 ustar 00 <?php namespace YOOtheme\Builder\Joomla; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Filesystem\File; use Joomla\CMS\Helper\MediaHelper; use Joomla\CMS\Http\HttpFactory; use YOOtheme\Config; use YOOtheme\Http\Request; use YOOtheme\Http\Response; use YOOtheme\Http\Uri; use YOOtheme\Path; class BuilderController { /** * @param Request $request * @param Response $response * @param CMSApplication $joomla * @param Config $config * * @return Response * @throws \Exception * */ public static function loadImage( Request $request, Response $response, CMSApplication $joomla, Config $config ) { $src = $request->getParam('src'); $md5 = $request->getParam('md5'); $http = HttpFactory::getHttp(); $params = ComponentHelper::getParams('com_media'); $uri = new Uri($src); $file = basename($uri->getPath()); if ($uri->getHost() === 'images.unsplash.com') { $file .= ".{$uri->getQueryParam('fm', 'jpg')}"; } if (version_compare(JVERSION, '4.0', '>')) { $path = Path::join($config('app.uploadDir'), $config('~theme.media_folder')); } else { $path = Path::join( JPATH_ROOT, $params->get('image_path'), $config('~theme.media_folder'), ); } if (!class_exists(File::class)) { class_alias(\Joomla\Filesystem\File::class, File::class); } $file = File::makeSafe($file); $dest = Path::join($path, $file); try { $request->abortIf( !str_starts_with($dest, $config('app.uploadDir')), 400, 'Invalid path.', ); // file already exists? while ($iterate = @md5_file($dest)) { if ($iterate === $md5 || is_null($md5)) { return $response->withJson(Path::relative(JPATH_ROOT, $dest)); } $file = preg_replace_callback( '/(?:-(\d{2}))?(\.[^.]+)?$/', fn($match) => sprintf('-%02d%s', intval($match[1]) + 1, $match[2] ?? ''), $file, 1, ); $dest = Path::join($path, $file); } // create file File::write($dest, ''); // download file $tmp = Path::join($path, uniqid()); $res = $http->get($src); $request ->abortIf($res->code != 200, $res->code, 'Download failed.') ->abortIf(!File::write($tmp, $res->body), 500, 'Error writing file.'); // allow .svg + mp4 files $params->set('upload_extensions', "{$params->get('upload_extensions')},svg,mp4"); // raise upload_maxsize $params->set('upload_maxsize', 30 * 1024 * 1024); // add mp4 mime type $params->set('upload_mime', "{$params->get('upload_mime')},video/mp4"); // ignore MIME-type check for .svg files $params->set( 'ignore_extensions', $params->get('ignore_extensions') ? "{$params->get('ignore_extensions')},svg" : 'svg', ); if ( !(new MediaHelper())->canUpload([ 'name' => $file, 'tmp_name' => $tmp, 'size' => filesize($tmp), ]) ) { File::delete($tmp); $queue = $joomla->getMessageQueue(); $message = count($queue) ? "{$file}: {$queue[0]['message']}" : ''; $request->abort(500, $message); } // move file $request->abortIf(!File::move($tmp, $dest), 500, 'Error writing file.'); return $response->withJson(Path::relative(JPATH_ROOT, $dest)); } catch (\Exception $e) { // delete incomplete file File::delete($dest); throw $e; } } } src/PageController.php 0000644 00000014107 15174774713 0011007 0 ustar 00 <?php namespace YOOtheme\Builder\Joomla; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Categories\Categories; use Joomla\CMS\MVC\Model\BaseDatabaseModel; use Joomla\CMS\User\User; use Joomla\Component\Content\Administrator\Extension\ContentComponent; use Joomla\Component\Content\Administrator\Model\ArticleModel; use Joomla\Component\Content\Administrator\Model\ArticlesModel; use Joomla\Database\DatabaseDriver; use YOOtheme\Builder; use YOOtheme\Config; use YOOtheme\Http\Request; use YOOtheme\Http\Response; use YOOtheme\Theme\Joomla\Listener\LoadArticleForm; class PageController { protected Config $config; protected CMSApplication $joomla; protected DatabaseDriver $db; public function __construct(Config $config, CMSApplication $joomla, DatabaseDriver $db) { $this->db = $db; $this->joomla = $joomla; $this->config = $config; } public function getPages(Request $request, Response $response, LoadArticleForm $article) { $home = $this->getHome(); $categories = Categories::getInstance('content'); $uncategorized = intval($this->config->get('~theme.page_category')); /** @var ArticlesModel $articles */ $articles = $this->getModel('articles'); $articles->setState('list.start', 0); $articles->setState('list.limit', 50); if ($language = $request->getQueryParam('lang')) { $articles->setState('filter.language', $language); } if ($search = $request->getQueryParam('search')) { $articles->setState('filter.search', $search); } elseif ($uncategorized) { $articles->setState('filter.category_id', $uncategorized); } else { return $response->withJson([]); } $items = []; foreach ($articles->getItems() as $item) { $category = $categories->get($item->catid); $root = array_key_first($category->getPath()); $type = $root !== $item->catid ? $categories->get($root) : $category; $status = [-2 => 'trashed', 0 => 'unpublished', 1 => 'published', 2 => 'archived']; $items[] = [ 'id' => $item->id, 'title' => $item->title, 'status' => $status[$item->state] ?? '', 'language' => $item->language, 'url' => $article->getRoute($item), 'home' => $item->id === $home, 'type' => [ 'id' => $type->slug, 'title' => $type->title, 'page' => $type->id === $uncategorized, ], 'category' => [ 'id' => $item->catid, 'title' => $item->category_title, ], ]; } return $response->withJson($items); } public function savePage(Request $request, Response $response, Builder $builder, User $user) { $request ->abortIf(!($page = $request->getParam('page')), 400) ->abortIf(!($page = base64_decode($page)), 400) ->abortIf(!($page = json_decode($page)), 400); /** @var ArticleModel $model */ $model = $this->getModel('article'); $article = $model->getItem($page->id); \Closure::bind( fn() => $this->preprocessData('com_content.article', $article), $model, $model, )(); $data = ['introtext' => '', 'fulltext' => ''] + (array) $article; if (version_compare(JVERSION, '4.0', '<')) { unset($data['featured']); } if ($page->content) { $content = json_encode($page->content); $fulltext = json_encode($builder->withParams(['context' => 'save'])->load($content)); $introtext = $builder ->withParams(['context' => 'content']) ->render($content, ['prefix' => 'page']); $data['fulltext'] = "<!-- {$fulltext} -->"; $data['introtext'] = $introtext; } $request->abortIf(!$this->allowEdit($user, $article), 403, 'Insufficient User Rights.'); $collision = ArticleHelper::getCollision($article); if ( !$request->getParam('overwrite') && $collision['contentHash'] !== $page->collision->contentHash ) { return $response->withJson(['hasCollision' => true, 'collision' => $collision]); } if ($tags = $article->tags->tags) { $data['tags'] = explode(',', $tags); } else { // Joomla 3 (can be removed with 4+) unset($data['tags']); } $model->save($data); // reload article after save $article = $model->getItem($page->id); return $response->withJson([ 'id' => $page->id, 'collision' => ArticleHelper::getCollision($article), ]); } protected function allowEdit(User $user, $article) { $asset = "com_content.article.{$article->id}"; return $user->authorise('core.edit', $asset) || ($user->authorise('core.edit.own', $asset) && $user->get('id') == $article->created_by); } protected function getModel($name) { if (version_compare(JVERSION, '4.0', '<')) { BaseDatabaseModel::addIncludePath( JPATH_ADMINISTRATOR . '/components/com_content/models', 'ContentModel', ); return BaseDatabaseModel::getInstance($name, 'ContentModel', [ 'ignore_request' => true, ]); } /** @var ContentComponent $component */ $component = $this->joomla->bootComponent('com_content'); return $component ->getMVCFactory() ->createModel($name, 'administrator', ['ignore_request' => true]); } protected function getHome() { $home = $this->joomla->getMenu('site')->getDefault(); $view = $home->query['view'] ?? ''; $option = $home->query['option'] ?? ''; return $view === 'article' && $option === 'com_content' ? intval($home->query['id']) : null; } } src/ArticleHelper.php 0000644 00000001625 15174774713 0010613 0 ustar 00 <?php namespace YOOtheme\Builder\Joomla; use Joomla\CMS\Factory; class ArticleHelper { public const PATTERN = '/^<!--\s?(\{.*})\s?-->/'; public static function matchContent($content) { return str_contains((string) $content, '<!--') && preg_match(static::PATTERN, $content, $matches) ? $matches[1] : null; } public static function getCollision($article) { $user = Factory::getUser($article->modified_by); return [ 'contentHash' => md5($article->fulltext . $article->introtext), 'modifiedBy' => $user->username ?: '', ]; } public static function isArticleView() { $input = Factory::getApplication()->input; return $input->getCmd('option') === 'com_content' && $input->getCmd('view') === 'article' && $input->getCmd('task', '') === ''; } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.23 | Generation time: 0 |
proxy
|
phpinfo
|
Settings