diff --git a/administrator/components/com_templates/src/Controller/TemplateController.php b/administrator/components/com_templates/src/Controller/TemplateController.php index b11b224eb7b44..e1b477e3e6e8a 100644 --- a/administrator/components/com_templates/src/Controller/TemplateController.php +++ b/administrator/components/com_templates/src/Controller/TemplateController.php @@ -11,6 +11,7 @@ \defined('_JEXEC') or die; +use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Client\ClientHelper; use Joomla\CMS\Filesystem\Path; @@ -136,6 +137,124 @@ public function publish() $this->setRedirect(Route::_($url, false)); } + /** + * Method for soft forking a template. + * + * @return boolean true on success, false otherwise + * + * @since __DEPLOY_VERSION__ + */ + public function inherit() + { + // Check for request forgeries + $this->checkToken(); + + $app = $this->app; + $this->input->set('installtype', 'folder'); + $newName = $this->input->get('new_name'); + $newNameRaw = $this->input->get('new_name', null, 'string'); + $templateID = $this->input->getInt('id', 0); + $defaultStyleId = $this->input->getInt('defaultStyleId', 0); + $file = $this->input->get('file'); + + // Access check. + if (!$this->allowEdit()) + { + $app->enqueueMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); + + return false; + } + + $this->setRedirect('index.php?option=com_templates&view=template&id=' . $templateID . '&defaultStyleId=' . $defaultStyleId. 'file=' . $file); + + /* @var \Joomla\Component\Templates\Administrator\Model\TemplateModel $model */ + $model = $this->getModel('Template', 'Administrator'); + $model->setState('new_name', $newName); + $model->setState('defaultStyleId', $defaultStyleId); + $model->setState('tmp_prefix', uniqid('template_copy_')); + $model->setState('to_path', $app->get('tmp_path') . '/' . $model->getState('tmp_prefix')); + + // Process only if we have a new name entered + if (strlen($newName) > 0) + { + if (!$this->app->getIdentity()->authorise('core.create', 'com_templates')) + { + // User is not authorised to delete + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_CREATE_NOT_PERMITTED'), 'error'); + + return false; + } + + // Set FTP credentials, if given + ClientHelper::setCredentialsFromRequest('ftp'); + + // Check that new name is valid + if (($newNameRaw !== null) && ($newName !== $newNameRaw)) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_TEMPLATE_NAME'), 'error'); + + return false; + } + + // Check that new name doesn't already exist + if (!$model->checkNewName()) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_DUPLICATE_TEMPLATE_NAME'), 'error'); + + return false; + } + + // Check that from name does exist and get the folder name + $fromName = $model->getFromName(); + + if (!$fromName) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error'); + + return false; + } + + // Call model's copy method + if (!$model->inherit()) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_COPY'), 'error'); + + return false; + } + + $template = $model->getTemplateWithStyle(); + + if ($template && $template->parent === 1) + { + $client = ApplicationHelper::getClientInfo($template->client_id); + + // Call installation model + $this->input->set('install_directory', $app->get('tmp_path') . '/' . $model->getState('tmp_prefix')); + + /** @var \Joomla\Component\Installer\Administrator\Model\InstallModel $installModel */ + $installModel = $this->app->bootComponent('com_installer') + ->getMVCFactory()->createModel('Install', 'Administrator'); + $this->app->getLanguage()->load('com_installer'); + + if (!$installModel->install()) + { + $this->setMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_INSTALL'), 'error'); + + return false; + } + + $this->setMessage(Text::sprintf('COM_TEMPLATES_COPY_SUCCESS', $newName)); + $model->cleanup(); + + return true; + } + + return false; + } + + return false; + } + /** * Method for copying the template. * diff --git a/administrator/components/com_templates/src/Model/TemplateModel.php b/administrator/components/com_templates/src/Model/TemplateModel.php index 02df31c05767a..5565d414138b4 100644 --- a/administrator/components/com_templates/src/Model/TemplateModel.php +++ b/administrator/components/com_templates/src/Model/TemplateModel.php @@ -623,6 +623,60 @@ protected function populateState() $this->setState('params', $params); } + /** + * Method to get the template information. + * + * @return mixed Object if successful, false if not and internal error is set. + * + * @since 1.6 + */ + public function &getTemplateWithStyle() + { + $pk = (int) $this->getState('extension.id'); + $db = $this->getDbo(); + $app = Factory::getApplication(); + + // Get the template information. + $query = $db->getQuery(true) + ->select($db->quoteName(['id', 'parent', 'inherits', 'e.extension_id', 'e.client_id', 'e.element', 'e.name', 'e.manifest_cache'])) + ->from($db->quoteName('#__template_styles', 's')) + ->where([ + $db->quoteName('id') . ' = ' . $db->quote($this->getState('defaultStyleId')) + ]) + ->join( + 'LEFT', + $db->quoteName('#__extensions', 'e'), + $db->quoteName('e.extension_id') . ' = :pk' + . ' AND ' . $db->quoteName('e.type') . ' = ' . $db->quote('template') + ) + ->bind(':pk', $pk, ParameterType::INTEGER); + $db->setQuery($query); + + try + { + $result = $db->loadObject(); + } + catch (\RuntimeException $e) + { + $app->enqueueMessage($e->getMessage(), 'warning'); + $this->template = false; + + return false; + } + + if (empty($result)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_EXTENSION_RECORD_NOT_FOUND'), 'error'); + $this->template = false; + } + else + { + $this->template = $result; + } + + return $this->template; + } + /** * Method to get the template information. * @@ -706,6 +760,98 @@ public function getFromName() return $this->getTemplate()->element; } + /** + * Method to soft fork a template + * + * @return boolean true if name is not used, false otherwise + * + * @since __DEPLOY_VERSION__ + */ + public function inherit() + { + $app = Factory::getApplication(); + $template = $this->getTemplateWithStyle(); + + if ($template->parent === 0) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_INHERIT'), 'error'); + + return false; + } + + if ($template = $this->getTemplate()) + { + $client = ApplicationHelper::getClientInfo($template->client_id); + $fromPath = Path::clean($client->path . '/templates/' . $template->element . '/'); + $newName = $this->getState('new_name'); + $defaultStyleId = $this->getState('defaultStyleId'); + $toPath = $this->getState('to_path'); + + // Delete new folder if it exists + if (Folder::exists($toPath)) + { + if (!Folder::delete($toPath)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_WRITE'), 'error'); + + return false; + } + } + else + { + if (!Folder::create($toPath)) + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_WRITE'), 'error'); + + return false; + } + } + + // If there is a valid xml file soft fork it + if (!is_file($fromPath . 'templateDetails.xml')) + { + return false; + } + + // Edit XML file + if (File::exists($fromPath . 'templateDetails.xml')) + { + $manifest = simplexml_load_file($fromPath . 'templateDetails.xml'); + $contents = file_get_contents($fromPath . 'templateDetails.xml'); + $pattern[] = '#\s*' . $manifest->name . '\s*#i'; + $replace[] = '' . $newName . ''; + $pattern[] = '##s'; + $replace[] = '' . $defaultStyleId . ''; + $pattern[] = '#(.*)<\/files>#s'; + $replace[] = 'templateDetails.xmltemplate_preview.pngtemplate_thumbnail.png'; + $contents = preg_replace($pattern, $replace, $contents); + File::write($toPath . '/templateDetails.xml', $contents); + } + + // Copy over the template thumbs + // @todo watermark the images with a `child` string or something + foreach (['template_preview.png', 'template_thumbnail.png'] as $path) + { + if (is_file($fromPath . $path)) + { + if (!File::copy($fromPath . $path, $toPath . '/' . $path)) { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_COULD_NOT_WRITE'), 'error'); + + return false; + } + } + } + + return true; + } + else + { + $app->enqueueMessage(Text::_('COM_TEMPLATES_ERROR_INVALID_FROM_NAME'), 'error'); + + return false; + } + } + /** * Method to check if new template name already exists * @@ -838,7 +984,7 @@ protected function fixTemplateName() { $contents = file_get_contents($xmlFile); $pattern[] = '#\s*' . $manifest->name . '\s*#i'; - $replace[] = '' . $newName . ''; + $replace[] = '' . $newName . '' . $oldName . ''; $pattern[] = '##'; $replace[] = ''; $pattern[] = '##'; @@ -1253,18 +1399,16 @@ public function createOverride($override) $return = $this->createTemplateOverride($override, $htmlPath); } - if ($return) - { - $app->enqueueMessage(Text::_('COM_TEMPLATES_OVERRIDE_CREATED') . str_replace(JPATH_ROOT, '', $htmlPath)); - - return true; - } - else + if (!$return) { $app->enqueueMessage(Text::_('COM_TEMPLATES_OVERRIDE_FAILED'), 'error'); return false; } + + $app->enqueueMessage(Text::_('COM_TEMPLATES_OVERRIDE_CREATED') . str_replace(JPATH_ROOT, '', $htmlPath)); + + return true; } } @@ -1285,6 +1429,9 @@ public function createTemplateOverride($overridePath, $htmlPath) return $return; } + // The template provided overrides + $templateBaseHtml = preg_replace('/' . $this->template->element . '\/html\//', $this->template->element . '/base_html/', $htmlPath); + // Get list of template folders $folders = Folder::folders($overridePath, null, true, true); @@ -1301,6 +1448,12 @@ public function createTemplateOverride($overridePath, $htmlPath) } } + // Check if there is a base_html override + if (is_dir($templateBaseHtml)) + { + $overridePath = $templateBaseHtml; + } + // Get list of template files (Only get *.php file for template file) $files = Folder::files($overridePath, '.php', true, true); diff --git a/administrator/components/com_templates/src/Model/TemplatesModel.php b/administrator/components/com_templates/src/Model/TemplatesModel.php index 2986f71318e15..6f0dcf40f34e5 100644 --- a/administrator/components/com_templates/src/Model/TemplatesModel.php +++ b/administrator/components/com_templates/src/Model/TemplatesModel.php @@ -72,16 +72,41 @@ public function getItems() $client = ApplicationHelper::getClientInfo($item->client_id); $item->xmldata = TemplatesHelper::parseXMLTemplateFile($client->path, $item->element); $num = $this->updated($item->extension_id); + $defaultStyleId = (int) $this->getDefaultStyleId($item->element, $item->client_id); if ($num) { $item->updated = $num; } + + if ($defaultStyleId) + { + $item->defaultStyleId = $defaultStyleId; + } } return $items; } + public function getDefaultStyleId($element, $client) + { + $db = Factory::getDbo(); + + // Select the required fields from the table + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__template_styles')) + ->where($db->quoteName('client_id') . ' = :clientid') + ->where($db->quoteName('template') . ' = :element') + ->bind(':clientid', $client, ParameterType::INTEGER) + ->bind(':element', $element, ParameterType::INTEGER); + + // Reset the query. + $db->setQuery($query); + + // Load the results as a list of stdClass objects. + return $db->loadResult(); + } /** * Check if template extension have any updated override. * diff --git a/administrator/components/com_templates/src/View/Template/HtmlView.php b/administrator/components/com_templates/src/View/Template/HtmlView.php index 0810948c0db0f..d33a14760e5df 100644 --- a/administrator/components/com_templates/src/View/Template/HtmlView.php +++ b/administrator/components/com_templates/src/View/Template/HtmlView.php @@ -258,6 +258,7 @@ protected function addToolbar() // Add a copy template button elseif ($this->type === 'home') { + ToolbarHelper::modal('forkModal', 'fas fa-copy', 'COM_TEMPLATES_BUTTON_SOFT_FORK_TEMPLATE'); ToolbarHelper::modal('copyModal', 'fas fa-copy', 'COM_TEMPLATES_BUTTON_COPY_TEMPLATE'); } } diff --git a/administrator/components/com_templates/tmpl/template/default.php b/administrator/components/com_templates/tmpl/template/default.php index 2675452f76907..172334f76d875 100644 --- a/administrator/components/com_templates/tmpl/template/default.php +++ b/administrator/components/com_templates/tmpl/template/default.php @@ -94,7 +94,7 @@
type == 'home') : ?> -
+

@@ -379,6 +379,22 @@
+ +
+ 'forkModal', + 'params' => array( + 'title' => Text::_('COM_TEMPLATES_TEMPLATE_FORK'), + 'footer' => $this->loadTemplate('modal_copy_footer') + ), + 'body' => $this->loadTemplate('modal_copy_body') + ) + ); ?> + +
+ type != 'home') : ?> - items as $i => $item) : ?> + items as $i => $item) : ?> element, $item->client_id); ?> element, $item->client_id); ?> - + name)); ?>
preview) : ?> diff --git a/administrator/language/en-GB/com_templates.ini b/administrator/language/en-GB/com_templates.ini index c5fc3bc9c30eb..25e53fb3e1bab 100644 --- a/administrator/language/en-GB/com_templates.ini +++ b/administrator/language/en-GB/com_templates.ini @@ -23,6 +23,7 @@ COM_TEMPLATES_BUTTON_PREVIEW="Template Preview" COM_TEMPLATES_BUTTON_RENAME="Rename" COM_TEMPLATES_BUTTON_RENAME_FILE="Rename File" COM_TEMPLATES_BUTTON_RESIZE="Resize" +COM_TEMPLATES_BUTTON_SOFT_FORK_TEMPLATE="Create Child" COM_TEMPLATES_BUTTON_UPLOAD="Upload" COM_TEMPLATES_CHECK_FILE_OWNERSHIP="Check file ownership" COM_TEMPLATES_CLICK_TO_ENLARGE="Select to enlarge." @@ -43,6 +44,7 @@ COM_TEMPLATES_ERR_XML="Template XML data not available" COM_TEMPLATES_ERROR_CANNOT_DELETE_LAST_STYLE="Can't delete the last style of a template. To uninstall/delete a template go to: System-> Manage-> Extensions-> Select template to be deleted-> Select 'Uninstall'." COM_TEMPLATES_ERROR_CANNOT_UNSET_DEFAULT_STYLE="Can't unset default style." COM_TEMPLATES_ERROR_COULD_NOT_COPY="Unable to copy template files to temporary folder." +COM_TEMPLATES_ERROR_COULD_NOT_INHERIT="You cannot inherit from this template as it does not support this functionality." COM_TEMPLATES_ERROR_COULD_NOT_INSTALL="Unable to install new template from temporary folder." COM_TEMPLATES_ERROR_COULD_NOT_WRITE="Unable to delete temporary folder." COM_TEMPLATES_ERROR_CREATE_NOT_PERMITTED="Unable to create temporary folder." diff --git a/build/build-modules-js/compilecss.es6.js b/build/build-modules-js/compilecss.es6.js index 2c15e022ef003..8d9fae68e0c3e 100644 --- a/build/build-modules-js/compilecss.es6.js +++ b/build/build-modules-js/compilecss.es6.js @@ -41,11 +41,6 @@ module.exports.compile = (options, path) => { } } else { files = [ - `${RootPath}/templates/cassiopeia/scss/offline.scss`, - `${RootPath}/templates/cassiopeia/scss/template.scss`, - `${RootPath}/templates/cassiopeia/scss/template-rtl.scss`, - `${RootPath}/templates/cassiopeia/scss/system/searchtools/searchtools.scss`, - `${RootPath}/templates/cassiopeia/scss/vendor/choicesjs/choices.scss`, `${RootPath}/administrator/templates/atum/scss/template.scss`, `${RootPath}/administrator/templates/atum/scss/template-rtl.scss`, `${RootPath}/administrator/templates/atum/scss/system/searchtools/searchtools.scss`, diff --git a/templates/cassiopeia/images/logo.svg b/build/media_source/templates/site/cassiopeia/images/logo.svg similarity index 100% rename from templates/cassiopeia/images/logo.svg rename to build/media_source/templates/site/cassiopeia/images/logo.svg diff --git a/templates/cassiopeia/images/select-bg-active-rtl.svg b/build/media_source/templates/site/cassiopeia/images/select-bg-active-rtl.svg similarity index 100% rename from templates/cassiopeia/images/select-bg-active-rtl.svg rename to build/media_source/templates/site/cassiopeia/images/select-bg-active-rtl.svg diff --git a/templates/cassiopeia/images/select-bg-active.svg b/build/media_source/templates/site/cassiopeia/images/select-bg-active.svg similarity index 100% rename from templates/cassiopeia/images/select-bg-active.svg rename to build/media_source/templates/site/cassiopeia/images/select-bg-active.svg diff --git a/templates/cassiopeia/images/select-bg-rtl.svg b/build/media_source/templates/site/cassiopeia/images/select-bg-rtl.svg similarity index 100% rename from templates/cassiopeia/images/select-bg-rtl.svg rename to build/media_source/templates/site/cassiopeia/images/select-bg-rtl.svg diff --git a/templates/cassiopeia/images/select-bg.svg b/build/media_source/templates/site/cassiopeia/images/select-bg.svg similarity index 100% rename from templates/cassiopeia/images/select-bg.svg rename to build/media_source/templates/site/cassiopeia/images/select-bg.svg diff --git a/templates/cassiopeia/images/system/rating_star.png b/build/media_source/templates/site/cassiopeia/images/system/rating_star.png similarity index 100% rename from templates/cassiopeia/images/system/rating_star.png rename to build/media_source/templates/site/cassiopeia/images/system/rating_star.png diff --git a/templates/cassiopeia/images/system/rating_star_blank.png b/build/media_source/templates/site/cassiopeia/images/system/rating_star_blank.png similarity index 100% rename from templates/cassiopeia/images/system/rating_star_blank.png rename to build/media_source/templates/site/cassiopeia/images/system/rating_star_blank.png diff --git a/templates/cassiopeia/images/system/sort_asc.png b/build/media_source/templates/site/cassiopeia/images/system/sort_asc.png similarity index 100% rename from templates/cassiopeia/images/system/sort_asc.png rename to build/media_source/templates/site/cassiopeia/images/system/sort_asc.png diff --git a/templates/cassiopeia/images/system/sort_desc.png b/build/media_source/templates/site/cassiopeia/images/system/sort_desc.png similarity index 100% rename from templates/cassiopeia/images/system/sort_desc.png rename to build/media_source/templates/site/cassiopeia/images/system/sort_desc.png diff --git a/templates/cassiopeia/js/template.js b/build/media_source/templates/site/cassiopeia/js/template.es5.js similarity index 100% rename from templates/cassiopeia/js/template.js rename to build/media_source/templates/site/cassiopeia/js/template.es5.js diff --git a/templates/cassiopeia/scss/_mixin.scss b/build/media_source/templates/site/cassiopeia/scss/_mixin.scss similarity index 100% rename from templates/cassiopeia/scss/_mixin.scss rename to build/media_source/templates/site/cassiopeia/scss/_mixin.scss diff --git a/templates/cassiopeia/scss/_variables.scss b/build/media_source/templates/site/cassiopeia/scss/_variables.scss similarity index 95% rename from templates/cassiopeia/scss/_variables.scss rename to build/media_source/templates/site/cassiopeia/scss/_variables.scss index 59dd8af4d8761..a0e7250be2d7e 100644 --- a/templates/cassiopeia/scss/_variables.scss +++ b/build/media_source/templates/site/cassiopeia/scss/_variables.scss @@ -1,4 +1,4 @@ -@import "../../../media/vendor/bootstrap/scss/functions"; +@import "../../../../../../media/vendor/bootstrap/scss/functions"; // Global $cassiopeia-template-color-dark: #112856 !default; @@ -87,7 +87,7 @@ $h4-font-size: 1rem; $h5-font-size: .9286rem; $h6-font-size: .8571rem; $font-size-sm: .8rem; -$fa-font-path: "../../../media/vendor/fontawesome-free/webfonts"; +$fa-font-path: "../../../../vendor/fontawesome-free/webfonts"; // Border Radius $border-radius: .25rem !default; @@ -142,8 +142,8 @@ $custom-select-indicator-padding: 3rem; $custom-select-bg-size: 116rem; $custom-select-indicator: url(../images/select-bg.svg); $custom-select-indicator-rtl: url(../images/select-bg-rtl.svg); -$custom-select-indicator-active: url(../../../images/select-bg.svg); -$custom-select-indicator-active-rtl: url(../../../images/select-bg-rtl.svg); +$custom-select-indicator-active: url(../images/select-bg.svg); +$custom-select-indicator-active-rtl: url(../images/select-bg-rtl.svg); $custom-select-background: $custom-select-indicator no-repeat right center / $custom-select-bg-size; // Used so we can have multiple background elements (e.g., arrow and feedback icon) $custom-select-background-rtl: $custom-select-indicator-rtl no-repeat left center / $custom-select-bg-size; // Used so we can have multiple background elements (e.g., arrow and feedback icon) $custom-select-bg-size-sm: 75rem; diff --git a/templates/cassiopeia/scss/blocks/_alerts.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_alerts.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_alerts.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_alerts.scss diff --git a/templates/cassiopeia/scss/blocks/_banner.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_banner.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_banner.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_banner.scss diff --git a/templates/cassiopeia/scss/blocks/_css-grid.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_css-grid.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_css-grid.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_css-grid.scss diff --git a/templates/cassiopeia/scss/blocks/_demo-styling.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_demo-styling.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_demo-styling.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_demo-styling.scss diff --git a/templates/cassiopeia/scss/blocks/_footer.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_footer.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_footer.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_footer.scss diff --git a/templates/cassiopeia/scss/blocks/_form.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_form.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_form.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_form.scss diff --git a/templates/cassiopeia/scss/blocks/_frontend-edit.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_frontend-edit.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_frontend-edit.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_frontend-edit.scss diff --git a/templates/cassiopeia/scss/blocks/_global.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_global.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_global.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_global.scss diff --git a/templates/cassiopeia/scss/blocks/_header.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_header.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_header.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_header.scss diff --git a/templates/cassiopeia/scss/blocks/_icons.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_icons.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_icons.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_icons.scss diff --git a/templates/cassiopeia/scss/blocks/_iframe.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_iframe.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_iframe.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_iframe.scss diff --git a/templates/cassiopeia/scss/blocks/_layout.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_layout.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_layout.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_layout.scss diff --git a/templates/cassiopeia/scss/blocks/_modals.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_modals.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_modals.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_modals.scss diff --git a/templates/cassiopeia/scss/blocks/_modifiers.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_modifiers.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_modifiers.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_modifiers.scss diff --git a/templates/cassiopeia/scss/blocks/_utilities.scss b/build/media_source/templates/site/cassiopeia/scss/blocks/_utilities.scss similarity index 100% rename from templates/cassiopeia/scss/blocks/_utilities.scss rename to build/media_source/templates/site/cassiopeia/scss/blocks/_utilities.scss diff --git a/templates/cassiopeia/scss/offline.scss b/build/media_source/templates/site/cassiopeia/scss/offline.scss similarity index 100% rename from templates/cassiopeia/scss/offline.scss rename to build/media_source/templates/site/cassiopeia/scss/offline.scss diff --git a/templates/cassiopeia/scss/system/searchtools/searchtools.scss b/build/media_source/templates/site/cassiopeia/scss/system/searchtools/searchtools.scss similarity index 100% rename from templates/cassiopeia/scss/system/searchtools/searchtools.scss rename to build/media_source/templates/site/cassiopeia/scss/system/searchtools/searchtools.scss diff --git a/templates/cassiopeia/scss/template-rtl.scss b/build/media_source/templates/site/cassiopeia/scss/template-rtl.scss similarity index 100% rename from templates/cassiopeia/scss/template-rtl.scss rename to build/media_source/templates/site/cassiopeia/scss/template-rtl.scss diff --git a/templates/cassiopeia/scss/template.scss b/build/media_source/templates/site/cassiopeia/scss/template.scss similarity index 70% rename from templates/cassiopeia/scss/template.scss rename to build/media_source/templates/site/cassiopeia/scss/template.scss index 79425c2089ded..a09e5919e3fba 100644 --- a/templates/cassiopeia/scss/template.scss +++ b/build/media_source/templates/site/cassiopeia/scss/template.scss @@ -1,5 +1,5 @@ // Bootstrap functions -@import "../../../media/vendor/bootstrap/scss/functions"; +@import "../../../../../../media/vendor/bootstrap/scss/functions"; // Variables @@ -9,22 +9,22 @@ @import "mixin"; // Bootstrap -@import "../../../media/vendor/bootstrap/scss/variables"; -@import "../../../media/vendor/bootstrap/scss/bootstrap"; +@import "../../../../../../media/vendor/bootstrap/scss/variables"; +@import "../../../../../../media/vendor/bootstrap/scss/bootstrap"; // "Font Awesome 5 Free" -@import "../../../media/vendor/fontawesome-free/scss/fontawesome"; -@import "../../../media/vendor/fontawesome-free/scss/solid"; -@import "../../../media/vendor/fontawesome-free/scss/brands"; +@import "../../../../../../media/vendor/fontawesome-free/scss/fontawesome"; +@import "../../../../../../media/vendor/fontawesome-free/scss/solid"; +@import "../../../../../../media/vendor/fontawesome-free/scss/brands"; // B/C for Icomoon -@import "../../../build/media_source/system/scss/icomoon"; +@import "../../../../system/scss/icomoon"; // Alert -@import "../../../build/media_source/system/scss/jalert"; +@import "../../../../system/scss/jalert"; // jQuery Minicolors -@import "../../../build/media_source/system/scss/jquery-minicolors"; +@import "../../../../system/scss/jquery-minicolors"; // Blocks @import "blocks/global"; // Leave this first diff --git a/templates/cassiopeia/scss/vendor/_awesomplete.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/_awesomplete.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/_awesomplete.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/_awesomplete.scss diff --git a/templates/cassiopeia/scss/vendor/_chosen.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/_chosen.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/_chosen.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/_chosen.scss diff --git a/templates/cassiopeia/scss/vendor/_dragula.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/_dragula.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/_dragula.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/_dragula.scss diff --git a/templates/cassiopeia/scss/vendor/_minicolors.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/_minicolors.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/_minicolors.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/_minicolors.scss diff --git a/templates/cassiopeia/scss/vendor/_tinymce.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/_tinymce.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/_tinymce.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/_tinymce.scss diff --git a/templates/cassiopeia/scss/vendor/bootstrap/_buttons.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_buttons.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/bootstrap/_buttons.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_buttons.scss diff --git a/templates/cassiopeia/scss/vendor/bootstrap/_card.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_card.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/bootstrap/_card.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_card.scss diff --git a/templates/cassiopeia/scss/vendor/bootstrap/_collapse.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_collapse.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/bootstrap/_collapse.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_collapse.scss diff --git a/templates/cassiopeia/scss/vendor/bootstrap/_custom-forms.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_custom-forms.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/bootstrap/_custom-forms.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_custom-forms.scss diff --git a/templates/cassiopeia/scss/vendor/bootstrap/_dropdown.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_dropdown.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/bootstrap/_dropdown.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_dropdown.scss diff --git a/templates/cassiopeia/scss/vendor/bootstrap/_lists.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_lists.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/bootstrap/_lists.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_lists.scss diff --git a/templates/cassiopeia/scss/vendor/bootstrap/_modal.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_modal.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/bootstrap/_modal.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_modal.scss diff --git a/templates/cassiopeia/scss/vendor/bootstrap/_nav.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_nav.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/bootstrap/_nav.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_nav.scss diff --git a/templates/cassiopeia/scss/vendor/bootstrap/_pagination.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_pagination.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/bootstrap/_pagination.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_pagination.scss diff --git a/templates/cassiopeia/scss/vendor/bootstrap/_table.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_table.scss similarity index 100% rename from templates/cassiopeia/scss/vendor/bootstrap/_table.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/bootstrap/_table.scss diff --git a/templates/cassiopeia/scss/vendor/choicesjs/choices.scss b/build/media_source/templates/site/cassiopeia/scss/vendor/choicesjs/choices.scss similarity index 88% rename from templates/cassiopeia/scss/vendor/choicesjs/choices.scss rename to build/media_source/templates/site/cassiopeia/scss/vendor/choicesjs/choices.scss index 999a0fae209c1..3710b50878f99 100644 --- a/templates/cassiopeia/scss/vendor/choicesjs/choices.scss +++ b/build/media_source/templates/site/cassiopeia/scss/vendor/choicesjs/choices.scss @@ -1,4 +1,4 @@ -@import "../../../../../media/vendor/bootstrap/scss/functions"; +@import "../../../../../../../../media/vendor/bootstrap/scss/functions"; // Cassiopea Variables @import "../../variables"; @@ -6,11 +6,11 @@ // Mixins @import "../../mixin"; -@import "../../../../../media/vendor/bootstrap/scss/variables"; -@import "../../../../../media/vendor/bootstrap/scss/mixins"; +@import "../../../../../../../../media/vendor/bootstrap/scss/variables"; +@import "../../../../../../../../media/vendor/bootstrap/scss/mixins"; // choices.js -@import "../../../../../node_modules/choices.js/src/styles/choices"; +@import "../../../../../../../../node_modules/choices.js/src/styles/choices"; // Fix position diff --git a/installation/sql/mysql/base.sql b/installation/sql/mysql/base.sql index c3f69d898295a..51b6fe704e545 100644 --- a/installation/sql/mysql/base.sql +++ b/installation/sql/mysql/base.sql @@ -782,6 +782,8 @@ CREATE TABLE IF NOT EXISTS `#__template_styles` ( `client_id` tinyint(1) unsigned NOT NULL DEFAULT 0, `home` char(7) NOT NULL DEFAULT '0', `title` varchar(255) NOT NULL DEFAULT '', + `parent` tinyint(1) DEFAULT '0' NOT NULL, + `inherits` int(10) DEFAULT '0' NOT NULL, `params` text NOT NULL, PRIMARY KEY (`id`), KEY `idx_template` (`template`), @@ -793,9 +795,9 @@ CREATE TABLE IF NOT EXISTS `#__template_styles` ( -- Dumping data for table `#__template_styles` -- -INSERT INTO `#__template_styles` (`id`, `template`, `client_id`, `home`, `title`, `params`) VALUES -(10, 'atum', 1, '1', 'atum - Default', ''), -(11, 'cassiopeia', 0, '1', 'cassiopeia - Default', '{"logoFile":"","fluidContainer":"0","sidebarLeftWidth":"3","sidebarRightWidth":"3"}'); +INSERT INTO `#__template_styles` (`id`, `template`, `client_id`, `home`, `title`, `parent`, `inherits`, `params`) VALUES +(10, 'atum', 1, '1', 'atum - Default', '0', '0', ''), +(11, 'cassiopeia', 0, '1', 'cassiopeia - Default', '1', '0', '{"logoFile":"","fluidContainer":"0","sidebarLeftWidth":"3","sidebarRightWidth":"3"}'); -- -------------------------------------------------------- diff --git a/installation/sql/postgresql/base.sql b/installation/sql/postgresql/base.sql index aaf8ee57f0507..061c93dc8e16b 100644 --- a/installation/sql/postgresql/base.sql +++ b/installation/sql/postgresql/base.sql @@ -798,6 +798,8 @@ CREATE TABLE IF NOT EXISTS "#__template_styles" ( "client_id" smallint DEFAULT 0 NOT NULL, "home" varchar(7) DEFAULT '0' NOT NULL, "title" varchar(255) DEFAULT '' NOT NULL, + "parent" tinyint(1) DEFAULT '0' NOT NULL, + "inherits" int(10) DEFAULT '0' NOT NULL, "params" text NOT NULL, PRIMARY KEY ("id") ); @@ -809,9 +811,9 @@ CREATE INDEX "#__template_styles_idx_client_id_home" ON "#__template_styles" ("c -- Dumping data for table `#__template_styles` -- -INSERT INTO "#__template_styles" ("id", "template", "client_id", "home", "title", "params") VALUES -(10, 'atum', 1, '1', 'atum - Default', ''), -(11, 'cassiopeia', 0, '1', 'cassiopeia - Default', '{"logoFile":"","fluidContainer":"0","sidebarLeftWidth":"3","sidebarRightWidth":"3"}'); +INSERT INTO "#__template_styles" ("id", "template", "client_id", "home", "title", "parent", "inherits", "params") VALUES +(10, 'atum', 1, '1', 'atum - Default', '0', '0', ''), +(11, 'cassiopeia', 0, '1', 'cassiopeia - Default', '1', '0', '{"logoFile":"","fluidContainer":"0","sidebarLeftWidth":"3","sidebarRightWidth":"3"}'); SELECT setval('#__template_styles_id_seq', 12, false); diff --git a/installation/src/Application/InstallationApplication.php b/installation/src/Application/InstallationApplication.php index 71f8b746fbe13..018674bb2e7ae 100644 --- a/installation/src/Application/InstallationApplication.php +++ b/installation/src/Application/InstallationApplication.php @@ -405,6 +405,8 @@ public function getTemplate($params = false) $template = new \stdClass; $template->template = 'template'; $template->params = new Registry; + $template->parent = false; + $template->inherits = null; return $template; } @@ -412,6 +414,21 @@ public function getTemplate($params = false) return 'template'; } + /** + * Gets the name of the current template. + * + * @param boolean $params True to return the template parameters + * @param string $name The name of the template + * + * @return string The name of the template. + * + * @since __DEPLOY_VERSION__ + */ + public function getTemplateByName($params = false, $name = '') + { + return $this->getTemplate($params); + } + /** * Initialise the application. * diff --git a/installation/template/index.php b/installation/template/index.php index 37b14ea9b8824..effd90fdfacea 100644 --- a/installation/template/index.php +++ b/installation/template/index.php @@ -8,6 +8,7 @@ defined('_JEXEC') or die; +use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Router\Route; use Joomla\CMS\Uri\Uri; @@ -67,7 +68,7 @@