Improve theme list to allow editing properties
This commit is contained in:
parent
e479ccbda6
commit
9b8e1ce3c1
|
|
@ -1,3 +1,7 @@
|
|||
* **Build 22x** (2015-03-xx)
|
||||
- Form Tabs now support specifying a default tab using the `defaultTab` option (see Backend > Forms docs).
|
||||
- Improved the Theme management features: Edit properties, download, duplicate and delete.
|
||||
|
||||
* **Build 222** (2015-03-11)
|
||||
- Form fields can now use a simpler interface for using the Input preset converter (see Backend > Forms docs).
|
||||
- The event `cms.page.init` no longer passes the URL as the third parameter, `$controller->getRouter()->getUrl()` should be used instead.
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ $el.on('oc.triggerOn.update',function(e){e.stopPropagation()
|
|||
self.onConditionChanged()})
|
||||
self.onConditionChanged()}
|
||||
TriggerOn.prototype.onConditionChanged=function(){if(this.triggerCondition=='checked'){this.updateTarget($(this.options.trigger+':checked',this.triggerParent).length>0)}
|
||||
else if(this.triggerCondition=='value'){this.updateTarget($(this.options.trigger,this.triggerParent).val()==this.triggerConditionValue)}}
|
||||
else if(this.triggerCondition=='value'){var trigger=$(this.options.trigger+':checked',this.triggerParent);if(trigger.length){this.updateTarget(trigger.val()==this.triggerConditionValue)}else{this.updateTarget($(this.options.trigger,this.triggerParent).val()==this.triggerConditionValue)}}}
|
||||
TriggerOn.prototype.updateTarget=function(status){if(this.options.triggerAction=='show')
|
||||
this.$el.toggleClass('hide',!status).trigger('hide',[!status])
|
||||
else if(this.options.triggerAction=='hide')
|
||||
|
|
|
|||
|
|
@ -496,7 +496,7 @@ class Controller extends Extendable
|
|||
$this->suppressView = true;
|
||||
$this->execPageAction($this->action, $this->params);
|
||||
|
||||
foreach ($this->widget as $widget) {
|
||||
foreach ((array) $this->widget as $widget) {
|
||||
if (method_exists($widget, $handler)) {
|
||||
$result = call_user_func_array([$widget, $handler], $this->params);
|
||||
return ($result) ?: true;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
.theme-selector-layout .theme-thumbnail {
|
||||
width: 288px;
|
||||
background: #ecf0f1;
|
||||
border-bottom: 1px solid #e3e7e9;
|
||||
border-top: 1px solid #e3e7e9;
|
||||
}
|
||||
.theme-selector-layout .theme-thumbnail img {
|
||||
opacity: 0.6;
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
width: 240px;
|
||||
}
|
||||
.theme-selector-layout .theme-description {
|
||||
border-bottom: 1px solid #f2f3f4;
|
||||
border-top: 1px solid #f2f3f4;
|
||||
}
|
||||
.theme-selector-layout .theme-description h3,
|
||||
.theme-selector-layout .theme-description p {
|
||||
|
|
@ -39,15 +39,21 @@
|
|||
line-height: 180%;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.theme-selector-layout .theme-description .controls button i.icon-star {
|
||||
.theme-selector-layout .theme-description .controls .btn > i {
|
||||
margin-right: 5px;
|
||||
color: #f1a84e;
|
||||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.theme-selector-layout .theme-description .controls .btn > i.icon-star {
|
||||
color: #f1a84e;
|
||||
}
|
||||
.theme-selector-layout .theme-description .controls .dropdown {
|
||||
display: inline-block;
|
||||
}
|
||||
.theme-selector-layout .layout-row.active .theme-thumbnail {
|
||||
background: #bdc3c7;
|
||||
border-bottom-color: #bdc3c7;
|
||||
border-top-color: #bdc3c7;
|
||||
}
|
||||
.theme-selector-layout .layout-row.active .thumbnail-container {
|
||||
position: relative;
|
||||
|
|
@ -77,9 +83,17 @@
|
|||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.theme-selector-layout .layout-row.last .theme-description,
|
||||
.theme-selector-layout .layout-row.last .theme-thumbnail {
|
||||
border-bottom: none!important;
|
||||
.theme-selector-layout .layout-row:first-child .theme-description,
|
||||
.theme-selector-layout .layout-row.links .theme-description,
|
||||
.theme-selector-layout .layout-row:first-child .theme-thumbnail,
|
||||
.theme-selector-layout .layout-row.links .theme-thumbnail {
|
||||
border-top: none;
|
||||
}
|
||||
.theme-selector-layout .layout-row.links .theme-thumbnail {
|
||||
border-bottom: 1px solid #e3e7e9;
|
||||
}
|
||||
.theme-selector-layout .layout-row.links .theme-description {
|
||||
border-bottom: 1px solid #f2f3f4;
|
||||
}
|
||||
.theme-selector-layout .find-more-themes {
|
||||
background: #ecf0f1;
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
.theme-selector-layout .layout-cell {
|
||||
padding: 24px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.theme-selector-layout .theme-thumbnail {
|
||||
width: 288px;
|
||||
background: #ecf0f1;
|
||||
border-bottom: 1px solid #e3e7e9;
|
||||
}
|
||||
.theme-selector-layout .theme-thumbnail img {
|
||||
opacity: 0.6;
|
||||
filter: alpha(opacity=60);
|
||||
width: 240px;
|
||||
}
|
||||
.theme-selector-layout .theme-description {
|
||||
border-bottom: 1px solid #f2f3f4;
|
||||
}
|
||||
.theme-selector-layout .theme-description h3,
|
||||
.theme-selector-layout .theme-description p {
|
||||
opacity: 0.6;
|
||||
filter: alpha(opacity=60);
|
||||
}
|
||||
.theme-selector-layout .theme-description h3 {
|
||||
margin: 0 0 25px 0;
|
||||
font-size: 28px;
|
||||
color: #2b3e50;
|
||||
display: inline-block;
|
||||
}
|
||||
.theme-selector-layout .theme-description p.author {
|
||||
font-size: 13px;
|
||||
display: inline-block;
|
||||
color: #808c8d;
|
||||
}
|
||||
.theme-selector-layout .theme-description p.description {
|
||||
color: #2b3e50;
|
||||
font-size: 14px;
|
||||
line-height: 180%;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.theme-selector-layout .theme-description .controls button i.icon-star {
|
||||
margin-right: 5px;
|
||||
color: #f1a84e;
|
||||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.theme-selector-layout .layout-row.active .theme-thumbnail {
|
||||
background: #bdc3c7;
|
||||
border-bottom-color: #bdc3c7;
|
||||
}
|
||||
.theme-selector-layout .layout-row.active .thumbnail-container {
|
||||
position: relative;
|
||||
}
|
||||
.theme-selector-layout .layout-row.active .thumbnail-container:after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 14px solid transparent;
|
||||
border-bottom: 14px solid transparent;
|
||||
border-left: 15px solid #bdc3c7;
|
||||
position: absolute;
|
||||
right: -35px;
|
||||
top: 50%;
|
||||
margin-top: -14px;
|
||||
}
|
||||
.theme-selector-layout .layout-row.active .theme-description h3,
|
||||
.theme-selector-layout .layout-row:hover .theme-description h3,
|
||||
.theme-selector-layout .layout-row.active .theme-description p,
|
||||
.theme-selector-layout .layout-row:hover .theme-description p {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.theme-selector-layout .layout-row.active .theme-thumbnail img,
|
||||
.theme-selector-layout .layout-row:hover .theme-thumbnail img {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.theme-selector-layout .layout-row.last .theme-description,
|
||||
.theme-selector-layout .layout-row.last .theme-thumbnail {
|
||||
border-bottom: none!important;
|
||||
}
|
||||
.theme-selector-layout .find-more-themes {
|
||||
background: #ecf0f1;
|
||||
color: #2b3e50;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 20px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.theme-selector-layout .find-more-themes:hover {
|
||||
background: #1795f1;
|
||||
color: white;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.theme-selector-layout .layout-cell,
|
||||
.theme-selector-layout .layout-row {
|
||||
display: block!important;
|
||||
width: auto!important;
|
||||
height: auto!important;
|
||||
}
|
||||
.theme-selector-layout .theme-thumbnail img {
|
||||
width: 100%;
|
||||
}
|
||||
.theme-selector-layout .layout-row.links .theme-thumbnail {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
.theme-thumbnail {
|
||||
width: 288px;
|
||||
background: #ecf0f1;
|
||||
border-bottom: 1px solid #e3e7e9;
|
||||
border-top: 1px solid #e3e7e9;
|
||||
|
||||
img {
|
||||
.opacity(0.6);
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
}
|
||||
|
||||
.theme-description {
|
||||
border-bottom: 1px solid #f2f3f4;
|
||||
border-top: 1px solid #f2f3f4;
|
||||
|
||||
h3, p {
|
||||
.opacity(0.6);
|
||||
|
|
@ -45,11 +45,19 @@
|
|||
}
|
||||
|
||||
.controls {
|
||||
button i.icon-star {
|
||||
.btn > i {
|
||||
margin-right: 5px;
|
||||
color: #f1a84e;
|
||||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
|
||||
&.icon-star {
|
||||
color: #f1a84e;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -57,8 +65,7 @@
|
|||
.layout-row.active {
|
||||
.theme-thumbnail {
|
||||
background: #bdc3c7;
|
||||
border-bottom-color: #bdc3c7;
|
||||
|
||||
border-top-color: #bdc3c7;
|
||||
}
|
||||
|
||||
.thumbnail-container {
|
||||
|
|
@ -74,7 +81,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.layout-row {
|
||||
.layout-row {
|
||||
&.active, &:hover {
|
||||
.theme-description {
|
||||
h3, p {
|
||||
|
|
@ -89,9 +96,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.last {
|
||||
&:first-child, &.links {
|
||||
.theme-description, .theme-thumbnail {
|
||||
border-bottom: none!important;
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.links {
|
||||
.theme-thumbnail {
|
||||
border-bottom: 1px solid #e3e7e9;
|
||||
}
|
||||
.theme-description {
|
||||
border-bottom: 1px solid #f2f3f4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ use Cache;
|
|||
use Event;
|
||||
use Config;
|
||||
use DbDongle;
|
||||
use System\Models\Parameters;
|
||||
use SystemException;
|
||||
use ApplicationException;
|
||||
use System\Models\Parameters;
|
||||
use Cms\Models\ThemeData;
|
||||
use DirectoryIterator;
|
||||
|
||||
|
|
@ -89,6 +90,16 @@ class Theme
|
|||
return $this->dirName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for {{ theme.id }} twig vars
|
||||
* Returns a unique string for this theme.
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return snake_case(str_replace('/', '-', $this->getDirName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a theme with given directory name exists
|
||||
* @param string $dirName The theme directory
|
||||
|
|
@ -113,6 +124,15 @@ class Theme
|
|||
return Page::listInTheme($this, $skipCache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this theme is the chosen active theme.
|
||||
*/
|
||||
public function isActiveTheme()
|
||||
{
|
||||
$activeTheme = self::getActiveTheme();
|
||||
return $activeTheme && $activeTheme->getDirName() == $this->getDirName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the active theme.
|
||||
* By default the active theme is loaded from the cms.activeTheme parameter,
|
||||
|
|
@ -258,6 +278,28 @@ class Theme
|
|||
return array_get($this->getConfig(), $name, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to the theme.yaml file with the supplied array values.
|
||||
* @param array $values Data to write
|
||||
* @param array $overwrite If true, undefined values are removed.
|
||||
* @return void
|
||||
*/
|
||||
public function writeConfig($values = [], $overwrite = false)
|
||||
{
|
||||
if (!$overwrite) {
|
||||
$values = $values + $this->getConfig();
|
||||
}
|
||||
|
||||
$path = $this->getPath().'/theme.yaml';
|
||||
if (!File::exists($path)) {
|
||||
throw new ApplicationException('Path does not exist: '.$path);
|
||||
}
|
||||
|
||||
$contents = Yaml::render($values);
|
||||
File::put($path, $contents);
|
||||
$this->configCache = $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the theme preview image URL.
|
||||
* If the image file doesn't exist returns the placeholder image URL.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
# ===================================
|
||||
# Form Field Definitions
|
||||
# ===================================
|
||||
|
||||
tabs:
|
||||
defaultTab: Properties
|
||||
fields:
|
||||
|
||||
name:
|
||||
label: Name
|
||||
placeholder: New theme name
|
||||
span: auto
|
||||
attributes:
|
||||
default-focus: 1
|
||||
|
||||
directory_name:
|
||||
label: Directory name
|
||||
disabled: true
|
||||
span: auto
|
||||
|
||||
description:
|
||||
label: Description
|
||||
placeholder: Theme description
|
||||
type: textarea
|
||||
size: tiny
|
||||
|
||||
author:
|
||||
label: Author
|
||||
placeholder: Person or company name
|
||||
span: auto
|
||||
|
||||
homepage:
|
||||
label: Homepage
|
||||
placeholder: Website URL
|
||||
span: auto
|
||||
|
||||
code:
|
||||
label: Code
|
||||
placeholder: A unique code for this theme used for distribution
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
<?php namespace Cms\Controllers;
|
||||
|
||||
use Lang;
|
||||
use Input;
|
||||
use Yaml;
|
||||
use Config;
|
||||
use Backend;
|
||||
use Redirect;
|
||||
use BackendMenu;
|
||||
use Backend\Classes\Controller;
|
||||
use System\Classes\SettingsManager;
|
||||
use ApplicationException;
|
||||
use Cms\Models\ThemeData;
|
||||
use Backend\Classes\Controller;
|
||||
use Cms\Classes\Theme as CmsTheme;
|
||||
use System\Classes\SettingsManager;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
|
|
@ -50,13 +50,48 @@ class Themes extends Controller
|
|||
|
||||
public function index_onSetActiveTheme()
|
||||
{
|
||||
CmsTheme::setActiveTheme(Input::get('theme'));
|
||||
CmsTheme::setActiveTheme(post('theme'));
|
||||
|
||||
return [
|
||||
'#theme-list' => $this->makePartial('theme_list')
|
||||
];
|
||||
}
|
||||
|
||||
//
|
||||
// Theme properties
|
||||
//
|
||||
|
||||
public function index_onLoadThemeFieldsForm()
|
||||
{
|
||||
$theme = $this->findThemeObject();
|
||||
$this->vars['widget'] = $this->makeThemeFieldsFormWidget($theme);
|
||||
$this->vars['themeDir'] = $theme->getDirName();
|
||||
|
||||
return $this->makePartial('theme_fields_form');
|
||||
}
|
||||
|
||||
public function index_onSaveThemeFields()
|
||||
{
|
||||
$theme = $this->findThemeObject();
|
||||
$widget = $this->makeThemeFieldsFormWidget($theme);
|
||||
$theme->writeConfig($widget->getSaveData());
|
||||
|
||||
return ['#themeListItem-'.$theme->getId() => $this->makePartial('theme_list_item', ['theme' => $theme])];
|
||||
}
|
||||
|
||||
protected function makeThemeFieldsFormWidget($theme)
|
||||
{
|
||||
$widgetConfig = $this->makeConfig('~/modules/cms/classes/theme/fields.yaml');
|
||||
$widgetConfig->alias = 'form'.studly_case($theme->getDirName());
|
||||
$widgetConfig->model = $theme;
|
||||
$widgetConfig->data = $theme->getConfig();
|
||||
$widgetConfig->data['directory_name'] = $theme->getDirName();
|
||||
$widgetConfig->arrayName = 'Theme';
|
||||
|
||||
$widget = $this->makeWidget('Backend\Widgets\Form', $widgetConfig);
|
||||
return $widget;
|
||||
}
|
||||
|
||||
//
|
||||
// Theme customization
|
||||
//
|
||||
|
|
@ -88,9 +123,7 @@ class Themes extends Controller
|
|||
|
||||
protected function getThemeData($dirName)
|
||||
{
|
||||
if (!$theme = CmsTheme::load($dirName))
|
||||
throw new Exception(Lang::get('Unable to find theme with name :name', $dirName));
|
||||
|
||||
$theme = $this->findThemeObject($dirName);
|
||||
$model = ThemeData::forTheme($theme);
|
||||
return $model;
|
||||
}
|
||||
|
|
@ -101,9 +134,7 @@ class Themes extends Controller
|
|||
protected function formExtendFields($form)
|
||||
{
|
||||
$model = $form->model;
|
||||
|
||||
if (!$theme = CmsTheme::load($model->theme))
|
||||
throw new Exception(Lang::get('Unable to find theme with name :name', $this->theme));
|
||||
$theme = $this->findThemeObject($model->theme);
|
||||
|
||||
if ($fields = $theme->getConfigValue('form.fields')) {
|
||||
$form->addFields($fields);
|
||||
|
|
@ -118,4 +149,21 @@ class Themes extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
|
||||
protected function findThemeObject($name = null)
|
||||
{
|
||||
if ($name === null) {
|
||||
$name = post('theme');
|
||||
}
|
||||
|
||||
if (!$name || (!$theme = CmsTheme::load($name))) {
|
||||
throw new ApplicationException(trans('cms::lang.theme.not_found_name', ['name' => $name]));
|
||||
}
|
||||
|
||||
return $theme;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
<?= Form::ajax('onSaveThemeFields', [
|
||||
'id' => 'themeFieldsForm',
|
||||
'data-popup-load-indicator' => true
|
||||
]) ?>
|
||||
|
||||
<input type="hidden" name="theme" value="<?= $themeDir ?>" />
|
||||
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="popup">×</button>
|
||||
<h4 class="modal-title">Theme: <?= $themeDir ?></h4>
|
||||
</div>
|
||||
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<div class="modal-body">
|
||||
<?= $widget->render() ?>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary">
|
||||
Save properties
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="popup">
|
||||
<?= e(trans('backend::lang.form.cancel')) ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<div class="modal-body">
|
||||
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="popup">
|
||||
<?= e(trans('backend::lang.form.close')) ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<?php endif ?>
|
||||
|
||||
<script>
|
||||
setTimeout(
|
||||
function(){ $('#themeFieldsForm input.form-control:first').focus() },
|
||||
310
|
||||
)
|
||||
</script>
|
||||
|
||||
<?= Form::close() ?>
|
||||
|
|
@ -1,55 +1,12 @@
|
|||
<?php
|
||||
$themes = Cms\Classes\Theme::all();
|
||||
$activeTheme = Cms\Classes\Theme::getActiveTheme();
|
||||
$cnt = count($themes);
|
||||
?>
|
||||
<?php foreach ($themes as $index => $theme): ?>
|
||||
<?php
|
||||
$isLast = $index == $cnt-1;
|
||||
$isActive = $activeTheme && $activeTheme->getDirName() == $theme->getDirName();
|
||||
$author = $theme->getConfigValue('author');
|
||||
?>
|
||||
<div class="layout-row <?= $isLast ? 'last' : null ?> min-size <?= $isActive ? 'active' : null ?>">
|
||||
<div class="layout-cell min-height theme-thumbnail">
|
||||
<div class="thumbnail-container"><img src="<?= $theme->getPreviewImageUrl() ?>"/></div>
|
||||
</div>
|
||||
<div class="layout-cell min-height theme-description">
|
||||
<h3><?= e($theme->getConfigValue('name', $theme->getDirName())) ?></h3>
|
||||
<?php if (strlen($author)): ?>
|
||||
<p class="author">by <a href="<?= e($theme->getConfigValue('homepage', '#')) ?>"><?= e($author) ?></a></p>
|
||||
<?php endif ?>
|
||||
<p class="description"><?= e($theme->getConfigValue('description', 'The theme description is not provided.')) ?></p>
|
||||
<div class="controls">
|
||||
<?php if ($isActive): ?>
|
||||
<button
|
||||
type="submit"
|
||||
disabled
|
||||
class="btn btn-disabled">
|
||||
<i class="icon-star"></i>
|
||||
<?= e(trans('cms::lang.theme.active_button')) ?>
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<button
|
||||
type="submit"
|
||||
data-request="onSetActiveTheme"
|
||||
data-request-data="theme: '<?= e($theme->getDirName()) ?>'"
|
||||
data-stripe-load-indicator
|
||||
class="btn btn-primary">
|
||||
<i class="icon-check"></i>
|
||||
<?= e(trans('cms::lang.theme.activate_button')) ?>
|
||||
</button>
|
||||
<?php endif ?>
|
||||
<?php if ($theme->hasCustomData()): ?>
|
||||
<a
|
||||
href="<?= Backend::url('cms/themes/update/'.$theme->getDirName()) ?>"
|
||||
class="btn btn-default">
|
||||
<i class="icon-pencil"></i>
|
||||
<?= e(trans('cms::lang.theme.customize_button')) ?>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="themeListItem-<?= $theme->getId() ?>" class="layout-row min-size <?= $theme->isActiveTheme() ? 'active' : null ?>">
|
||||
<?= $this->makePartial('theme_list_item', ['theme' => $theme]) ?>
|
||||
</div>
|
||||
|
||||
<?php endforeach ?>
|
||||
|
||||
<div class="layout-row links">
|
||||
|
|
@ -57,6 +14,11 @@
|
|||
<!-- Spacer -->
|
||||
</div>
|
||||
<div class="layout-cell theme-description">
|
||||
<a class="find-more-themes" href="http://octobercms.com/themes"><?= e(trans('cms::lang.theme.find_more_themes')) ?></a>
|
||||
<a
|
||||
class="find-more-themes"
|
||||
href="http://octobercms.com/themes"
|
||||
target="_blank">
|
||||
<?= e(trans('cms::lang.theme.find_more_themes')) ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
$author = $theme->getConfigValue('author');
|
||||
?>
|
||||
|
||||
<div class="layout-cell min-height theme-thumbnail">
|
||||
<div class="thumbnail-container"><img src="<?= $theme->getPreviewImageUrl() ?>"/></div>
|
||||
</div>
|
||||
<div class="layout-cell min-height theme-description">
|
||||
<h3><?= e($theme->getConfigValue('name', $theme->getDirName())) ?></h3>
|
||||
<?php if (strlen($author)): ?>
|
||||
<p class="author">by <a href="<?= e($theme->getConfigValue('homepage', '#')) ?>"><?= e($author) ?></a></p>
|
||||
<?php endif ?>
|
||||
<p class="description">
|
||||
<?= e($theme->getConfigValue('description', 'The theme description is not provided.')) ?>
|
||||
</p>
|
||||
<div class="controls">
|
||||
|
||||
<?php if ($theme->isActiveTheme()): ?>
|
||||
<button
|
||||
type="submit"
|
||||
disabled
|
||||
class="btn btn-disabled">
|
||||
<i class="icon-star"></i>
|
||||
<?= e(trans('cms::lang.theme.active_button')) ?>
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<button
|
||||
type="submit"
|
||||
data-request="onSetActiveTheme"
|
||||
data-request-data="theme: '<?= e($theme->getDirName()) ?>'"
|
||||
data-stripe-load-indicator
|
||||
class="btn btn-primary">
|
||||
<i class="icon-check"></i>
|
||||
<?= e(trans('cms::lang.theme.activate_button')) ?>
|
||||
</button>
|
||||
<?php endif ?>
|
||||
<?php if ($theme->hasCustomData()): ?>
|
||||
<a
|
||||
href="<?= Backend::url('cms/themes/update/'.$theme->getDirName()) ?>"
|
||||
class="btn btn-default">
|
||||
<i class="icon-paint-brush"></i>
|
||||
<?= e(trans('cms::lang.theme.customize_button')) ?>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
<div class="dropdown">
|
||||
<button
|
||||
data-toggle="dropdown"
|
||||
class="btn btn-default">
|
||||
<i class="icon-wrench"></i>
|
||||
Manage
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu" data-dropdown-title="Manage theme">
|
||||
<li role="presentation">
|
||||
<a
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
data-control="popup"
|
||||
data-size="huge"
|
||||
data-handler="onLoadThemeFieldsForm"
|
||||
data-request-data="theme: '<?= e($theme->getDirName()) ?>'"
|
||||
href="javascript:;"
|
||||
class="oc-icon-pencil">
|
||||
Edit properties
|
||||
</a>
|
||||
</li>
|
||||
<!--
|
||||
<li role="presentation">
|
||||
<a
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
href="javascript:;"
|
||||
class="oc-icon-download">
|
||||
Download
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
href="javascript:;"
|
||||
class="oc-icon-copy">
|
||||
Duplicate
|
||||
</a>
|
||||
</li>
|
||||
<li role="presentation" class="divider"></li>
|
||||
<li role="presentation">
|
||||
<a
|
||||
role="menuitem"
|
||||
tabindex="-1"
|
||||
href="javascript:;"
|
||||
class="oc-icon-trash">
|
||||
Delete
|
||||
</a>
|
||||
</li>
|
||||
-->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -13,6 +13,7 @@ return [
|
|||
'file_name_required' => 'The File Name field is required.'
|
||||
],
|
||||
'theme' => [
|
||||
'not_found_name' => "The theme ':name' is not found.",
|
||||
'active' => [
|
||||
'not_set' => 'The active theme is not set.',
|
||||
'not_found' => 'The active theme is not found.'
|
||||
|
|
|
|||
Loading…
Reference in New Issue