support work for a long-term fix for issue #390, essentially one can specify a theme:schema string anywhere a theme is input. It will be honoured unless an existing schema setting over-rides this behaviour. This should also be backward compatible but the theme selection code has been cleaned up slightly and there may be subtle differences in behaviour after this commit. On my site this required a page refresh as the first page load after this change was a bit confused.

This commit is contained in:
redmatrix 2016-05-17 17:46:30 -07:00
parent 51edd472c2
commit 20cb4130d4
6 changed files with 153 additions and 112 deletions

131
Zotlabs/Render/Theme.php Normal file
View file

@ -0,0 +1,131 @@
<?php
namespace Zotlabs\Render;
class Theme {
static $system_theme = null;
static $system_mobile_theme = null;
static $session_theme = null;
static $session_mobile_theme = null;
static $base_themes = array('redbasic');
static public function current(){
self::$system_theme = ((isset(\App::$config['system']['theme']))
? \App::$config['system']['theme'] : '');
self::$session_theme = ((isset($_SESSION) && x($_SESSION,'theme'))
? $_SESSION['theme'] : self::$system_theme);
self::$system_mobile_theme = ((isset(\App::$config['system']['mobile_theme']))
? \App::$config['system']['mobile_theme'] : '');
self::$session_mobile_theme = ((isset($_SESSION) && x($_SESSION,'mobile_theme'))
? $_SESSION['mobile_theme'] : self::$system_mobile_theme);
$page_theme = null;
// Find the theme that belongs to the channel whose stuff we are looking at
if(\App::$profile_uid) {
$r = q("select channel_theme from channel where channel_id = %d limit 1",
intval(\App::$profile_uid)
);
if($r) {
$page_theme = $r[0]['channel_theme'];
}
}
// Themes from Comanche layouts over-ride the channel theme
if(array_key_exists('theme', \App::$layout) && \App::$layout['theme'])
$page_theme = \App::$layout['theme'];
// If the viewer is on a mobile device, ensure that we're using a mobile
// theme of some kind or whatever the viewer's preference is for mobile
// viewing (if applicable)
if(\App::$is_mobile || \App::$is_tablet) {
if(isset($_SESSION['show_mobile']) && (! $_SESSION['show_mobile'])) {
$chosen_theme = self::$session_theme;
}
else {
$chosen_theme = self::$session_mobile_theme;
if($chosen_theme === '' || $chosen_theme === '---' ) {
// user has selected to have the mobile theme be the same as the normal one
$chosen_theme = self::$session_theme;
}
}
}
else {
$chosen_theme = self::$session_theme;
if($page_theme) {
$chosen_theme = $page_theme;
}
}
// Allow theme selection of the form 'theme_name:schema_name'
$themepair = explode(':', $chosen_theme);
if($chosen_theme && (file_exists('view/theme/' . $themepair[0] . '/css/style.css') || file_exists('view/theme/' . $themepair[0] . '/php/style.php'))) {
return($themepair);
}
foreach(self::$base_themes as $t) {
if(file_exists('view/theme/' . $t . '/css/style.css') ||
file_exists('view/theme/' . $t . '/php/style.php')) {
return(array($t));
}
}
// Worst case scenario, the default base theme or themes don't exist; perhaps somebody renamed it/them.
// Find any theme at all and use it.
$fallback = array_merge(glob('view/theme/*/css/style.css'),glob('view/theme/*/php/style.php'));
if(count($fallback))
return(array(str_replace('view/theme/','', substr($fallback[0],0,-14))));
}
/**
* @brief Return full URL to theme which is currently in effect.
*
* Provide a sane default if nothing is chosen or the specified theme does not exist.
*
* @param bool $installing default false
*
* @return string
*/
function url($installing = false) {
if($installing)
return self::$base_themes[0];
$theme = self::current();
$t = $theme[0];
$s = ((count($theme) > 1) ? $t[1] : '');
$opts = '';
$opts = ((\App::$profile_uid) ? '?f=&puid=' . \App::$profile_uid : '');
$schema_str = ((x(\App::$layout,'schema')) ? '&schema=' . App::$layout['schema'] : '');
if(($s) && (! $schema_str))
$schema_str = '&schema=' . $s;
$opts .= $schema_str;
if(file_exists('view/theme/' . $t . '/php/style.php'))
return('view/theme/' . $t . '/php/style.pcss' . $opts);
return('view/theme/' . $t . '/css/style.css');
}
}

View file

@ -246,11 +246,13 @@ class Browser extends DAV\Browser\Plugin {
\App::$page['content'] = $html;
load_pdl($a);
$theme_info_file = "view/theme/" . current_theme() . "/php/theme.php";
$current_theme = \Zotlabs\Render\Theme::current();
$theme_info_file = "view/theme/" . $current_theme[0] . "/php/theme.php";
if (file_exists($theme_info_file)){
require_once($theme_info_file);
if (function_exists(str_replace('-', '_', current_theme()) . '_init')) {
$func = str_replace('-', '_', current_theme()) . '_init';
if (function_exists(str_replace('-', '_', $current_theme[0]) . '_init')) {
$func = str_replace('-', '_', $current_theme[0]) . '_init';
$func($a);
}
}

View file

@ -206,13 +206,15 @@ class Router {
* load current theme info
*/
$theme_info_file = 'view/theme/' . current_theme() . '/php/theme.php';
$current_theme = \Zotlabs\Render\Theme::current();
$theme_info_file = 'view/theme/' . $current_theme[0] . '/php/theme.php';
if (file_exists($theme_info_file)){
require_once($theme_info_file);
}
if(function_exists(str_replace('-', '_', current_theme()) . '_init')) {
$func = str_replace('-', '_', current_theme()) . '_init';
if(function_exists(str_replace('-', '_', $current_theme[0]) . '_init')) {
$func = str_replace('-', '_', $current_theme[0]) . '_init';
$func($a);
}
elseif (x(\App::$theme_info, 'extends') && file_exists('view/theme/' . \App::$theme_info['extends'] . '/php/theme.php')) {

106
boot.php
View file

@ -1874,105 +1874,6 @@ function is_windows() {
return ((strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? true : false);
}
function current_theme(){
$app_base_themes = array('redbasic');
$a = get_app();
$page_theme = null;
// Find the theme that belongs to the channel whose stuff we are looking at
if(App::$profile_uid && App::$profile_uid != local_channel()) {
$r = q("select channel_theme from channel where channel_id = %d limit 1",
intval(App::$profile_uid)
);
if($r)
$page_theme = $r[0]['channel_theme'];
}
if(array_key_exists('theme', App::$layout) && App::$layout['theme'])
$page_theme = App::$layout['theme'];
// Allow folks to over-rule channel themes and always use their own on their own site.
// The default is for channel themes to take precedence over your own on pages belonging
// to that channel.
if($page_theme && local_channel() && App::$profile_uid && local_channel() != App::$profile_uid) {
if(get_pconfig(local_channel(),'system','always_my_theme'))
$page_theme = null;
}
$is_mobile = App::$is_mobile || App::$is_tablet;
$standard_system_theme = ((isset(App::$config['system']['theme'])) ? App::$config['system']['theme'] : '');
$standard_theme_name = ((isset($_SESSION) && x($_SESSION,'theme')) ? $_SESSION['theme'] : $standard_system_theme);
if($is_mobile) {
if(isset($_SESSION['show_mobile']) && !$_SESSION['show_mobile']) {
$system_theme = $standard_system_theme;
$theme_name = $standard_theme_name;
}
else {
$system_theme = ((isset(App::$config['system']['mobile_theme'])) ? App::$config['system']['mobile_theme'] : '');
$theme_name = ((isset($_SESSION) && x($_SESSION,'mobile_theme')) ? $_SESSION['mobile_theme'] : $system_theme);
if($theme_name === '' || $theme_name === '---' ) {
// user has selected to have the mobile theme be the same as the normal one
$system_theme = $standard_system_theme;
$theme_name = $standard_theme_name;
}
}
}
else {
$system_theme = $standard_system_theme;
$theme_name = $standard_theme_name;
if($page_theme)
$theme_name = $page_theme;
}
if($theme_name &&
(file_exists('view/theme/' . $theme_name . '/css/style.css') ||
file_exists('view/theme/' . $theme_name . '/php/style.php')))
return($theme_name);
foreach($app_base_themes as $t) {
if(file_exists('view/theme/' . $t . '/css/style.css') ||
file_exists('view/theme/' . $t . '/php/style.php'))
return($t);
}
$fallback = array_merge(glob('view/theme/*/css/style.css'),glob('view/theme/*/php/style.php'));
if(count($fallback))
return (str_replace('view/theme/','', substr($fallback[0],0,-10)));
}
/**
* @brief Return full URL to theme which is currently in effect.
*
* Provide a sane default if nothing is chosen or the specified theme does not exist.
*
* @param bool $installing default false
*
* @return string
*/
function current_theme_url($installing = false) {
global $a;
$t = current_theme();
$opts = '';
$opts = ((App::$profile_uid) ? '?f=&puid=' . App::$profile_uid : '');
$opts .= ((x(App::$layout,'schema')) ? '&schema=' . App::$layout['schema'] : '');
if(file_exists('view/theme/' . $t . '/php/style.php'))
return('view/theme/' . $t . '/php/style.pcss' . $opts);
return('view/theme/' . $t . '/css/style.css');
}
/**
* @brief Check if current user has admin role.
*
@ -1980,6 +1881,7 @@ function current_theme_url($installing = false) {
*
* @return bool true if user is an admin
*/
function is_site_admin() {
$a = get_app();
@ -2209,7 +2111,9 @@ function construct_page(&$a) {
}
}
if (($p = theme_include(current_theme() . '.js')) != '')
$current_theme = Zotlabs\Render\Theme::current();
if (($p = theme_include($current_theme[0] . '.js')) != '')
head_add_js($p);
if (($p = theme_include('mod_' . App::$module . '.php')) != '')
@ -2223,7 +2127,7 @@ function construct_page(&$a) {
head_add_css(((x(App::$page, 'template')) ? App::$page['template'] : 'default' ) . '.css');
head_add_css('mod_' . App::$module . '.css');
head_add_css(current_theme_url($installing));
head_add_css(Zotlabs\Render\Theme::url($installing));
head_add_js('mod_' . App::$module . '.js');

View file

@ -648,12 +648,13 @@ function theme_include($file, $root = '') {
else
$parent = 'NOPATH';
$theme = current_theme();
$theme = Zotlabs\Render\Theme::current();
$thname = $theme[0];
$ext = substr($file,strrpos($file,'.')+1);
$paths = array(
"{$root}view/theme/$theme/$ext/$file",
"{$root}view/theme/$thname/$ext/$file",
"{$root}view/theme/$parent/$ext/$file",
"{$root}view/site/$ext/$file",
"{$root}view/$ext/$file",

View file

@ -11,13 +11,14 @@ class FriendicaSmarty extends Smarty {
parent::__construct();
$a = get_app();
$theme = current_theme();
$theme = Zotlabs\Render\Theme::current();
$thname = $theme[0];
// setTemplateDir can be set to an array, which Smarty will parse in order.
// The order is thus very important here
$template_dirs = array('theme' => "view/theme/$theme/tpl/");
$template_dirs = array('theme' => "view/theme/$thname/tpl/");
if( x(App::$theme_info,"extends") )
$template_dirs = $template_dirs + array('extends' => "view/theme/".App::$theme_info["extends"]."/tpl/");
$template_dirs = $template_dirs + array('extends' => "view/theme/" . App::$theme_info["extends"] . "/tpl/");
$template_dirs = $template_dirs + array('base' => 'view/tpl/');
$this->setTemplateDir($template_dirs);