1
0
mirror of https://github.com/e107inc/e107.git synced 2025-08-02 20:57:26 +02:00

Closes #4748 - Bootstrap5 Theme enhancements. Bootswatch 5.

This commit is contained in:
Cameron
2022-04-05 19:49:08 -07:00
parent 45372f285c
commit 6eff4cb5f7
15 changed files with 152 additions and 99 deletions

View File

@@ -301,9 +301,13 @@ if(defined("PREVIEWTHEME"))
} }
else else
{ {
$css_default = "all"; // TODO - default should be defined by the theme $css_default = "all";
// theme-css.php auto-detection TODO - convert it to constant or anything different from GLOBAL
if (isset($theme_css_php) && $theme_css_php) if(method_exists('theme', 'css')) // new v2.3.2 theme styles load override.
{
e107::callMethod('theme', 'css');
}
elseif (isset($theme_css_php) && $theme_css_php)
{ {
//echo "<link rel='stylesheet' href='".THEME_ABS."theme-css.php' type='text/css' />\n"; //echo "<link rel='stylesheet' href='".THEME_ABS."theme-css.php' type='text/css' />\n";
$e_js->themeCSS('theme-css.php', $css_default); $e_js->themeCSS('theme-css.php', $css_default);
@@ -352,16 +356,10 @@ $e_js->renderLinks();
// Other CSS - from unknown location, different from core/theme/plugin location or backward compatibility; NOTE - could be removed in the future!!! // Other CSS - from unknown location, different from core/theme/plugin location or backward compatibility; NOTE - could be removed in the future!!!
//TODO Additional options for 'bootstrap' and 'style' (ie. THEME_STYLE loaded above). Requires changes to js_manager.php
$CSSORDER = deftrue('CSSORDER') ? explode(",",CSSORDER) : array('library', 'other','core','plugin','theme','inline'); $CSSORDER = deftrue('CSSORDER') ? explode(",",CSSORDER) : array('library', 'other','core','plugin','theme','inline');
/** Experimental - Subject to removal at any time. Use at own risk */ /** Experimental - Subject to removal at any time. Use at own risk */
if(method_exists('theme', 'css')) if(method_exists('theme', 'cssFilter'))
{ {
$e_js->set('_theme_css_processor', true); $e_js->set('_theme_css_processor', true);
} }

View File

@@ -2652,7 +2652,7 @@ class e107
$jshandler = self::getJs(); $jshandler = self::getJs();
$jshandler->setDependency($dep); $jshandler->setDependency($dep);
if(strpos($data,'http')===0) if(strpos($data,'http')===0 && ($type !== 'theme'))
{ {
$type = 'url'; $type = 'url';
} }
@@ -2670,7 +2670,7 @@ class e107
break; break;
case 'theme': case 'theme':
// data is path relative to current theme // data is path relative to current theme or URL to load in the 'theme' zone.
$jshandler->themeCSS($data, $media, $preComment, $postComment); $jshandler->themeCSS($data, $media, $preComment, $postComment);
break; break;

View File

@@ -1083,7 +1083,7 @@ class e_jsmanager
break; break;
case 'theme_css': case 'theme_css':
$file_path = $runtime_location.$this->_sep.'{e_THEME}'.$this->getCurrentTheme().'/'.trim($file_path, '/').$this->_sep.$pre.$this->_sep.$post; $file_path = $runtime_location.$this->_sep.(strpos($file_path, 'http') !== 0 && strpos($file_path, '//') !== 0 ?'{e_THEME}'.$this->getCurrentTheme().'/'.trim($file_path, '/') : $file_path).$this->_sep.$pre.$this->_sep.$post;
if(!isset($this->_e_css['theme'])) $this->_e_css['theme'] = array(); if(!isset($this->_e_css['theme'])) $this->_e_css['theme'] = array();
$registry = &$this->_e_css['theme']; $registry = &$this->_e_css['theme'];
$runtime = true; $runtime = true;
@@ -1291,8 +1291,8 @@ class e_jsmanager
case 'core_css': //e_jslib case 'core_css': //e_jslib
if($this->_theme_css_processor) if($this->_theme_css_processor)
{ {
$this->_e_css['core'] = e107::callMethod('theme', 'css', $this->_e_css['core'], 'core'); $this->_e_css['core'] = e107::callMethod('theme', 'cssFilter', $this->_e_css['core'], 'core');
e107::getMessage()->addDebug('Theme css() method is experimental and is subject to removal at any time. Use at own risk'); e107::getMessage()->addDebug('Theme cssFilter() method is experimental and is subject to removal at any time. Use at own risk');
} }
$this->renderFile(varset($this->_e_css['core'], array()), $external, 'Core CSS', $mod, false); $this->renderFile(varset($this->_e_css['core'], array()), $external, 'Core CSS', $mod, false);
unset($this->_e_css['core']); unset($this->_e_css['core']);
@@ -1301,7 +1301,7 @@ class e_jsmanager
case 'plugin_css': //e_jslib case 'plugin_css': //e_jslib
if($this->_theme_css_processor) if($this->_theme_css_processor)
{ {
$this->_e_css['plugin'] = e107::callMethod('theme', 'css', $this->_e_css['plugin'], 'plugin'); $this->_e_css['plugin'] = e107::callMethod('theme', 'cssFilter', $this->_e_css['plugin'], 'plugin');
} }
$this->renderFile(varset($this->_e_css['plugin'], array()), $external, 'Plugin CSS', $mod, false); $this->renderFile(varset($this->_e_css['plugin'], array()), $external, 'Plugin CSS', $mod, false);
unset($this->_e_css['plugin']); unset($this->_e_css['plugin']);
@@ -1315,7 +1315,7 @@ class e_jsmanager
case 'other_css': case 'other_css':
if($this->_theme_css_processor) if($this->_theme_css_processor)
{ {
$this->_e_css['other'] = e107::callMethod('theme', 'css', $this->_e_css['other'], 'other'); $this->_e_css['other'] = e107::callMethod('theme', 'cssFilter', $this->_e_css['other'], 'other');
} }
$this->renderFile(varset($this->_e_css['other'], array()), $external, 'Other CSS', $mod, false); $this->renderFile(varset($this->_e_css['other'], array()), $external, 'Other CSS', $mod, false);
unset($this->_e_css['other']); unset($this->_e_css['other']);

View File

@@ -166,7 +166,7 @@ class e_theme
/** /**
* Return an array of theme library or stylesheet values (as defined in theme.xml) that match the desired scope. * Return an array of theme library or stylesheet values (as defined in theme.xml) that match the desired scope.
* @note New in v2.3.1+ * @note New in v2.3.1+
* @param string $type library | stylesheet * @param string $type library | css
* @param string $scope front | admin | all | auto (as defined in theme.xml) * @param string $scope front | admin | all | auto (as defined in theme.xml)
* @return array * @return array
*/ */
@@ -287,8 +287,7 @@ class e_theme
/** /**
* Load library dependencies. * Load library dependencies.
* *
* @param string $scope * @param string $scope front | admin | all | auto
* front | admin | all | auto
*/ */
public function loadLibrary($scope = 'auto') public function loadLibrary($scope = 'auto')
{ {
@@ -302,6 +301,8 @@ class e_theme
$loaded = []; $loaded = [];
$excludeCSS = (string) $this->cssAttribute('auto', 'exclude'); // current theme style
foreach($libraries as $name => $library) foreach($libraries as $name => $library)
{ {
@@ -310,6 +311,11 @@ class e_theme
continue; continue;
} }
if($name === $excludeCSS)
{
$library['files'] = 'js'; // load only JS, but not CSS since the style excluded it.
}
if($name === 'bootstrap' && !empty($library['version'])) if($name === 'bootstrap' && !empty($library['version']))
{ {
if((int) $library['version'] > 3) // quick fix. if((int) $library['version'] > 3) // quick fix.
@@ -1348,7 +1354,7 @@ class e_theme
define('THEME_STYLE', $pref['admincss']); define('THEME_STYLE', $pref['admincss']);
self::initThemeLayout(); // the equivalent for frontend is in header_default.php self::initThemeLayout(); // the equivalent for frontend is in header_default.php
} }
elseif(!empty($pref['themecss']) && file_exists(THEME.$pref['themecss'])) elseif(!empty($pref['themecss']) && (file_exists(THEME.$pref['themecss']) || strpos($pref['themecss'],'https') === 0))
{ {
define('THEME_STYLE', $pref['themecss']); define('THEME_STYLE', $pref['themecss']);
} }
@@ -2831,38 +2837,12 @@ class themeHandler
$text .= varset($itext); $text .= varset($itext);
// Render skin previews. // Render skin previews.
if(self::RENDER_ADMINPREFS === $mode) if($skinText = self::renderSkin($theme, $mode, $pref))
{ {
$parms = []; $text .= $skinText;
$parms['path'] = e_THEME.$theme['path'].'/';
$parms['block-class'] = 'admin-css-selector col-md-3';
foreach($theme['css'] as $val)
{
$kid = $val['name'];
// $val['description'];
$parms['optArray'][$kid] = array(
'thumbnail' => $val['thumbnail'],
'label' => $val['info']."<br /><small>".$val['description']."</small>",
);
} }
elseif(!empty($theme['multipleStylesheets']) && $mode && !empty($theme['css']) && self::RENDER_SITEPREFS === $mode)
$text .= "<tr><td style='vertical-align:top;'><b>".TPVLAN_95.":</b></td>
<td colspan='2' style='vertical-align:top'>
";
$text .= e107::getForm()->radioImage('admincss', vartrue($pref['admincss']), $parms);
$text .= "</td></tr>";
}
if(array_key_exists("multipleStylesheets", $theme) && $mode && !empty($theme['css']) && self::RENDER_SITEPREFS === $mode)
{ {
$pLabel = TPVLAN_22; $pLabel = TPVLAN_22;
@@ -3461,8 +3441,48 @@ class themeHandler
} }
*/ */
/**
* @param array $theme
* @param string $mode
* @param mixed $value
* @return array
*/
private static function renderSkin($theme, $mode, $pref)
{
$parms = [];
$parms['path'] = e_THEME . $theme['path'] . '/';
$parms['block-class'] = 'admin-css-selector col-md-3';
foreach($theme['css'] as $val)
{
if(empty($val['thumbnail']))
{
continue;
}
$kid = $val['name'];
// $val['description'];
$parms['optArray'][$kid] = array(
'thumbnail' => $val['thumbnail'],
'label' => $val['info'] . "<br /><small>" . $val['description'] . "</small>",
);
}
if(empty($parms['optArray']))
{
return '';
}
$text = "<tr><td style='vertical-align:top;'><b>" . TPVLAN_95 . ":</b></td>
<td colspan='2' style='vertical-align:top'>
";
$css = ($mode === self::RENDER_ADMINPREFS) ? 'admincss' : 'themecss';
$text .= e107::getForm()->radioImage($css, vartrue($pref[$css]), $parms);
$text .= "</td></tr>";
return $text;
}
} }

View File

@@ -30,7 +30,7 @@ $HERO_TEMPLATE['default']['footer'] = '</div><div class="carousel-controls">
</div>'; </div>';
$HERO_TEMPLATE['default']['start'] = '<div class="carousel-item item {HERO_SLIDE_ACTIVE}" style="background-image:{HERO_BGIMAGE}"> $HERO_TEMPLATE['default']['start'] = '<div class="carousel-item item {HERO_SLIDE_ACTIVE} bg-dark" style="background-image:{HERO_BGIMAGE}">
<div class="container"> <div class="container">
<div class="carousel-caption"> <div class="carousel-caption">

View File

@@ -23,7 +23,7 @@ class e_themeTest extends \Codeception\Test\Unit
} }
catch(Exception $e) catch(Exception $e)
{ {
$this->assertTrue(false, "Couldn't load e_theme object"); $this->fail("Couldn't load e_theme object");
} }
$this->tm->clearCache(); $this->tm->clearCache();
@@ -31,12 +31,13 @@ class e_themeTest extends \Codeception\Test\Unit
} }
/*
public function testCssAttribute() public function testCssAttribute()
{ {
$result = e107::getTheme('bootstrap5')->cssAttribute('front','name');
$this->assertSame('style.css', $result);
} }
/*
public function testUpgradeThemeCode() public function testUpgradeThemeCode()
{ {
@@ -484,11 +485,18 @@ class e_themeTest extends \Codeception\Test\Unit
{ {
} }
*/
public function testGetThemeInfo() public function testGetThemeInfo()
{ {
$themeObj = $this->tm;
$data = $themeObj::getThemeInfo('bootstrap3');
$result= !empty($data['stylesheetThumbnails']['admin']);
$this->assertTrue($result);
}*/ $data = $themeObj::getThemeInfo('bootstrap5');
$result= !empty($data['stylesheetThumbnails']['front']);
$this->assertTrue($result);
}
public function testGetThemeLayout() public function testGetThemeLayout()
{ {

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -105,8 +105,18 @@ ul.social-buttons li a {
/* margin-top: 60px;*/ /* margin-top: 60px;*/
padding: 2rem 1rem; padding: 2rem 1rem;
/* margin-bottom: 2rem;*/ /* margin-bottom: 2rem;*/
background-color: #e9ecef; /* background-color: #e9ecef;*/
/* border-radius: .3rem;*/ /* border-radius: .3rem;*/
} }
#carousel-hero.carousel {
position: relative;
left: 0;
top: 70px;
width: 100%;
height: 100%;
overflow: hidden;
margin-bottom: 60px;
}
/* CUSTOM Responsive Styles */ /* CUSTOM Responsive Styles */

View File

@@ -10,6 +10,8 @@ if(!defined('e107_INIT'))
class theme implements e_theme_render class theme implements e_theme_render
{ {
public function init() public function init()
{ {
@@ -17,15 +19,8 @@ if(!defined('e107_INIT'))
e107::meta('viewport', 'width=device-width, initial-scale=1.0'); // added to <head> e107::meta('viewport', 'width=device-width, initial-scale=1.0'); // added to <head>
// e107::link('rel="preload" href="{THEME}fonts/myfont.woff2?v=2.2.0" as="font" type="font/woff2" crossorigin'); // added to <head> // e107::link('rel="preload" href="{THEME}fonts/myfont.woff2?v=2.2.0" as="font" type="font/woff2" crossorigin'); // added to <head>
// e107::meta('apple-mobile-web-app-capable','yes'); // e107::meta('apple-mobile-web-app-capable','yes');
if($bootswatch = e107::pref('theme', 'bootswatch', false))
{
e107::css('url', 'https://bootswatch.com/4/' . $bootswatch . '/bootstrap.min.css');
e107::css('url', 'https://bootswatch.com/4/' . $bootswatch . '/bootstrap.min.css');
}
$login_iframe = e107::pref('theme', 'login_iframe', false); $login_iframe = e107::pref('theme', 'login_iframe', false);
if(THEME_LAYOUT === "splash" && $login_iframe) if(THEME_LAYOUT === "splash" && $login_iframe)
@@ -36,13 +31,23 @@ if(!defined('e107_INIT'))
} }
/**
* Override how THEME_STYLE is loaded. Duplicates will be automatically removed.
* @return void
*/
function css()
{
e107::css('theme', THEME_STYLE);
e107::css('theme', 'style.css'); // always load style.css last.
}
/** /**
* @param string $text * @param string $text
* @return string without p tags added always with bbcodes * @return string without p tags added always with bbcodes
* note: this solves W3C validation issue and CSS style problems * note: this solves W3C validation issue and CSS style problems
* use this carefully, mainly for custom menus, let decision on theme developers * use this carefully, mainly for custom menus, let decision on theme developers
*/ */
function remove_ptags($text = '') // FIXME this is a bug in e107 if this is required. function remove_ptags($text = '') // FIXME this is a bug in e107 if this is required.
{ {
@@ -72,6 +77,9 @@ if(!defined('e107_INIT'))
$style = 'splash'; $style = 'splash';
break; break;
case 'news_months_menu':
$style = 'listgroup';
break;
} }
echo "\n<!-- tablestyle initial: style=" . $style . " mode=" . $mode . " UniqueId=" . varset($options['uniqueId']) . " -->\n\n"; echo "\n<!-- tablestyle initial: style=" . $style . " mode=" . $mode . " UniqueId=" . varset($options['uniqueId']) . " -->\n\n";

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<e107Theme name="Bootstrap 5" version="1.0" date="2021-03-22" compatibility="2.3.1"> <e107Theme name="Bootstrap 5" version="1.1" date="2022-04-05" compatibility="2.3.2">
<author name ="e107 Inc" email="e107inc@something.com" url="https://e107.org" /> <author name ="e107 Inc" email="e107inc@something.com" url="https://e107.org" />
<summary>Bootstrap 5 basic theme</summary> <summary>Bootstrap 5 basic theme</summary>
<description>A starter template for bootstrap5 themes.</description> <description>A starter template for bootstrap5 themes.</description>
@@ -10,12 +10,14 @@
<plugin name='rss_menu' url='core' /> <plugin name='rss_menu' url='core' />
<plugin name='social' url='core' /> <plugin name='social' url='core' />
<plugin name='tinymce4' url='core' /> <plugin name='tinymce4' url='core' />
<plugin name='gsitemap' url='core' />
</plugins> </plugins>
<keywords> <keywords>
<word>bootstrap</word> <word>bootstrap</word>
<word>bootstrap5</word> <word>bootstrap5</word>
<word>clean</word> <word>clean</word>
<word>wireframe</word> <word>wireframe</word>
<word>bootswatch</word>
</keywords> </keywords>
<libraries> <libraries>
<library name="bootstrap" version="5" scope="front"/> <library name="bootstrap" version="5" scope="front"/>
@@ -24,7 +26,12 @@
<library name="animate.css" scope="front" /> <library name="animate.css" scope="front" />
</libraries> </libraries>
<stylesheets> <stylesheets>
<css file="style.css" name="Default" /> <css file="style.css" name="Default" thumbnail='preview_frontend.png' scope='front' />
<css file="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.1.3/lux/bootstrap.min.css" name="Lux" thumbnail='images/lux.png' scope='front' exclude='bootstrap' />
<css file="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.1.3/sketchy/bootstrap.min.css" name="Sketchy" thumbnail='images/sketchy.png' scope='front' exclude='bootstrap' />
<css file="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.1.3/quartz/bootstrap.min.css" name="Quartz" thumbnail='images/quartz.png' scope='front' exclude='bootstrap' />
<css file="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.1.3/slate/bootstrap.min.css" name="Slate" thumbnail='images/slate.png' scope='front' exclude='bootstrap' />
<css file="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.1.3/superhero/bootstrap.min.css" name="Superhero" thumbnail='images/superhero.png' scope='front' exclude='bootstrap' />
</stylesheets> </stylesheets>
<screenshots> <screenshots>
<image>preview_frontend.png</image> <image>preview_frontend.png</image>
@@ -47,7 +54,6 @@
</layouts> </layouts>
<themePrefs> <themePrefs>
<pref name='cardmenu_look'>1</pref> <pref name='cardmenu_look'>1</pref>
<pref name='inlinecss'></pref>
<pref name='login_iframe'></pref> <pref name='login_iframe'></pref>
</themePrefs> </themePrefs>
</e107Theme> </e107Theme>

View File

@@ -33,22 +33,25 @@ class theme_config implements e_theme_config
"lux" => 'Lux', "lux" => 'Lux',
"materia" => 'Materia', "materia" => 'Materia',
"minty" => 'Minty', "minty" => 'Minty',
'morph' => 'Morph',
"pulse" => 'Pulse', "pulse" => 'Pulse',
'quartz' => 'Quartz',
"sandstone" => 'Sandstone', "sandstone" => 'Sandstone',
"simplex" => 'Simplex', "simplex" => 'Simplex',
"sketchy"=> 'sketchy', "sketchy" => 'Sketchy',
"slate" => 'Slate', "slate" => 'Slate',
"solar" => 'Solar', "solar" => 'Solar',
"spacelab" => 'Spacelab', "spacelab" => 'Spacelab',
"superhero" => 'Superhero', "superhero" => 'Superhero',
"united" => 'United', "united" => 'United',
"yeti" => 'Yeti', "yeti" => 'Yeti',
'zephyr' => 'Zephyr',
); );
$previewLink = " <a class='btn btn-default btn-secondary e-modal' data-modal-caption=\"Use the 'Themes' menu to view the selection.\" href='http://bootswatch.com/default/'>".LAN_PREVIEW."</a>"; $previewLink = " <a class='btn btn-default btn-secondary e-modal' data-modal-caption=\"Use the 'Themes' menu to view the selection.\" href='http://bootswatch.com/default/'>".LAN_PREVIEW."</a>";
return array( return array(
'bootswatch' => array('title'=>LAN_THEMEPREF_01, 'type'=>'dropdown', 'writeParms'=>array('optArray'=> $bootswatch, 'post'=>$previewLink, 'default'=>LAN_DEFAULT)), //'bootswatch' => array('title'=>LAN_THEMEPREF_01, 'type'=>'dropdown', 'writeParms'=>array('optArray'=> $bootswatch, 'post'=>$previewLink, 'default'=>LAN_DEFAULT)),
'cardmenu_look' => array('title' => LAN_THEMEPREF_02, 'type'=>'boolean', 'writeParms'=>array(),'help'=>''), 'cardmenu_look' => array('title' => LAN_THEMEPREF_02, 'type'=>'boolean', 'writeParms'=>array(),'help'=>''),
'login_iframe' => array('title' => LAN_THEMEPREF_03, 'type'=>'boolean', 'writeParms'=>array(),'help'=>''), 'login_iframe' => array('title' => LAN_THEMEPREF_03, 'type'=>'boolean', 'writeParms'=>array(),'help'=>''),
); );