I know there is a forum topic for morphogenesis at XOOPS france
http://www.frxoops.org , but I couldn't find one here to discuss well the theme, so I'm opening this thread for this.
To recap a little this is the definition I had once made for morpho:
As the name symbolizes it, it is meant to be the body structural part of a default XOOPS theme template serving as a canvas starting point for theme designers to develop their designs under specific XOOPS standards and W3C compliance.
It is completely based on the default theme of XOOPS 2.3, which is based on
Zeta Reticuli by Leo. The process I did was to take the graphical part out and leave just the wire frame keeping the architecture done by Leo.
It started with
Morphogenesis V. 1, Kris, took the development of Morphogenesis too, and made:
Morphogenesis V.1.1.0 and
Morphogenesis V.2Despite I have continued with the 1.0.X branch on the themes I've been making, the 2.0 branch has additional code by Kris with lots of extra functions.
This is it's raw elemental XHTML structure:
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<{$xoops_langcode}>" lang="<{$xoops_langcode}>">
<head>
<{* Center blocks display order valid values are: lrc (left right / center) lcr (left center right) clr (center / left right) *}>
<{assign var=theme_top_order value=lcr}>
<{assign var=theme_bottom_order value=lrc}>
<{assign var=theme_name value=$xoTheme->folderName}>
<title><{$xoops_pagetitle}> : <{$xoops_sitename}> : <{$xoops_slogan}>title>
<meta name="robots" content="<{$xoops_meta_robots}>" />
<meta name="keywords" content="<{$xoops_meta_keywords}>" />
<meta name="description" content="<{$xoops_meta_description}>" />
<meta name="rating" content="<{$xoops_meta_rating}>" />
<meta name="author" content="<{$xoops_meta_author}>" />
<meta name="copyright" content="<{$xoops_meta_copyright}>" />
<meta name="generator" content="XOOPS" />
<link rel="shortcut icon" type="image/ico" href="<{xoImgUrl /favicon.ico}>" />
<link rel="icon" type="image/png" href="<{xoImgUrl /icon.png}>" />
<link rel="stylesheet" type="text/css" media="screen" href="<{xoImgUrl /layout-soup.css}>" />
<link rel="stylesheet" type="text/css" media="all" title="Blue" href="<{xoImgUrl /style.css}>" />
<{$xoops_module_header}>
head>
<body class="<{$xoops_dirname}> theme-default">
<{if $xoBlocks.canvas_left and $xoBlocks.canvas_right}><{assign var=columns_layout value='threecolumns-layout'}>
<{elseif $xoBlocks.canvas_left}><{assign var=columns_layout value='leftcolumn-layout'}>
<{elseif $xoBlocks.canvas_right}><{assign var=columns_layout value='rightcolumn-layout'}>
<{/if}>
<div id="xo-canvas"<{if $columns_layout}> class="<{$columns_layout}>"<{/if}>>
<{if $xoops_banner and $xoops_banner != ' '}>
<div id="xo-banner" class="commercial">
<a id="xo-main-logo" href="<{xoAppUrl /}>"><img src="<{xoImgUrl img/header-logo_small.gif}>" alt="<{$xoops_sitename}>" />a>
<a id="xo-site-title" class="commercial" href="<{xoAppUrl /}>">mor·pho·gen·e·sisa>
<div id="xo-site-slogan">birth of evolutiondiv>
<div id="xo-banner-ad"><{$xoops_banner|smarty:nodefaults}>div>
div>
<{else}>
<div id="xo-banner">
<a id="xo-site-title" href="<{xoAppUrl /}>"><h1><{$xoops_sitename}>h1>a>
<div id="xo-site-slogan"><{$xoops_slogan}>div>
div>
<{/if}>
<div id="xo-canvas-content">
<{if $xoBlocks.canvas_top}>
<{includeq file="$theme_name/blockszone.html" blocks=$xoBlocks.canvas_top
zoneClass='' zoneId='xo-canvas-header'
}>
<{/if}>
<table id="xo-canvas-columns" cellspacing="0">
<tr>
<{if $xoBlocks.canvas_left}>
<{includeq file="$theme_name/blockszone.html" blocks=$xoBlocks.canvas_left
zoneClass='xo-canvas-column' zoneId='xo-canvas-leftcolumn' zoneTag='td'
}>
<{/if}>
<td id="xo-page">
<{if $xoBlocks.page_topleft or $xoBlocks.page_topcenter or $xoBlocks.page_topright}>
<div class="xo-blockszone xo-<{$theme_top_order}>pageblocks" id="xo-page-topblocks">
<{includeq file="$theme_name/centerblocks.html" topbottom=top lcr=$theme_top_order|substr:0:1}>
<{includeq file="$theme_name/centerblocks.html" topbottom=top lcr=$theme_top_order|substr:1:1}>
<{includeq file="$theme_name/centerblocks.html" topbottom=top lcr=$theme_top_order|substr:2:1}>
div>
<{/if}>
<{if $xoops_contents}><div id="xo-content"><{$xoops_contents}>div><{/if}>
<{if $xoBlocks.page_bottomleft or $xoBlocks.page_bottomcenter or $xoBlocks.page_bottomright}>
<div class="xo-blockszone xo-<{$theme_bottom_order}>pageblocks" id="xo-page-bottomblocks">
<{includeq file="$theme_name/centerblocks.html" topbottom=bottom lcr=$theme_bottom_order|substr:0:1}>
<{includeq file="$theme_name/centerblocks.html" topbottom=bottom lcr=$theme_bottom_order|substr:1:1}>
<{includeq file="$theme_name/centerblocks.html" topbottom=bottom lcr=$theme_bottom_order|substr:2:1}>
div>
<{/if}>
td>
<{if $xoBlocks.canvas_right}>
<{includeq file="$theme_name/blockszone.html" blocks=$xoBlocks.canvas_right
zoneClass='xo-canvas-column' zoneId='xo-canvas-rightcolumn' zoneTag='td'
}>
<{/if}>
tr>
table>
<{if $xoBlocks.canvas_bottom}>
<{includeq file="$theme_name/blockszone.html" blocks=$xoBlocks.canvas_bottom
zoneClass='' zoneId='xo-canvas-footer'
}>
<{/if}>
div>
<div id="xo-footer">
<{$xoops_footer}>
div>
div>
body>
html>
Kris has taken the time to define all the structural elements at a wiki he has done here:
http://labs.xoofoo.org/modules/wiwimod/What I wanted to show those who are interested in relation to this is something David showed me earlier which looks like the theme engine and where we see clearly the reason of being of the main properties defined in the above theme.html.
see code here.
2 /**
3 * xos_opal_Theme component class file
4 *
5 * @copyright The XOOPS project https://xoops.org/
6 * @license http://www.fsf.org/copyleft/gpl.html GNU public license
7 * @author Skalpa Keo
8 * @since 2.3.0
9 * @version $Id$
10 * @package xos_opal
11 * @subpackage xos_opal_Theme
12 */
13
14 /**
15 * xos_opal_ThemeFactory
16 *
17 * @author Skalpa Keo
18 * @package xos_opal
19 * @subpackage xos_opal_Theme
20 * @since 2.3.0
21 */
22 class xos_opal_ThemeFactory {
23 /**
24 * Currently enabled themes (if empty, all the themes in themes/ are allowed)
25 * @var array
26 */
27 var $allowedThemes = array();
28 /**
29 * Default theme to instanciate if none specified
30 * @var string
31 */
32 var $defaultTheme = 'default';
33 /**
34 * If users are allowed to choose a custom theme
35 * @var bool
36 */
37 var $allowUserSelection = true;
38
39 /**
40 * Instanciate the specified theme
41 */
42 function &createInstance( $options = array(), $initArgs = array() ) {
43 // Grab the theme folder from request vars if present
44 if ( @empty( $options['folderName'] ) ) {
45 if ( $req = @$_REQUEST['_xo_theme_name'] ) {
46 if ( $this->isThemeAllowed( $req ) ) {
47 $options['folderName'] = $req;
48 if ( isset( $_SESSION ) && $this->allowUserSelection ) {
49 $_SESSION[ $this->xoBundleIdentifier ]['defaultTheme'] = $req;
50 }
51 }
52 } elseif ( isset( $_SESSION[ $this->xoBundleIdentifier ]['defaultTheme'] ) ) {
53 $options['folderName'] = $_SESSION[ $this->xoBundleIdentifier ]['defaultTheme'];
54 } elseif ( @empty( $options['folderName'] ) || !$this->isThemeAllowed( $options['folderName'] ) ) {
55 $options['folderName'] = $this->defaultTheme;
56 }
57 }
58 // Retrieve the desired content-type from the request
59 if ( @empty( $options['contentType'] ) && !empty($_REQUEST['_xo_mime_type']) ) {
60 $options['contentType'] = $_REQUEST['_xo_mime_type'];
61 }
62
63 // Read the theme bundle info file
64 global $xoops;
65 $options['path'] = $xoops->path( '/themes/' . $options['folderName'] );
66 if ( $info = @include( $options['path'] . "/xo-info.php" ) ) {
67 $options = array_merge( $info, $options );
68 } else {
69 $options['themeAPI'] = '2.0';
70 $options['parentTheme'] = ( $options['folderName'] == 'xoops20' ? '' : 'xoops20' );
71 }
72 $inst =& XOS::createInstanceOf( 'xos_opal_Theme', $options );
73
74 return $inst;
75 }
76
77 /**
78 * Checks if the specified theme is enabled or not
79 * @param string $name
80 * @return bool
81 */
82 function isThemeAllowed( $name ) {
83 return ( empty( $this->allowedThemes ) || in_array( $name, $this->allowedThemes ) );
84 }
85
86 /**
87 * List the available themes
88 *
89 * @param boolean $allowed Whether to return the allowed themes, or all of them
90 * @return array
91 */
92 function enumerate( $allowed = false ) {
93 global $xoops;
94 $themes = array();
95 $root = $xoops->path( '/themes/' );
96 if ( $dh = opendir( $root ) ) {
97 while ( $file = readdir($dh) ) {
98 if ( $file{0} != '.' && $file != 'CVS' && is_dir( "$root/$file" ) ) {
99 $themes[] = $file;
100 }
101 }
102 closedir( $dh );
103 }
104 if ( !empty($this->allowedThemes) && $allowed ) {
105 return array_intersect( $themes, $this->allowedThemes );
106 }
107 return $themes;
108 }
109
110 }
111
112 class xos_opal_Theme {
113 /**
114 * The name of this theme
115 * @var string
116 */
117 var $folderName = '';
118 /**
119 * Physical path of this theme folder
120 * @var string
121 */
122 var $path = '';
123 var $url = '';
124
125 /**
126 * Default content-type of pages generated by this theme
127 * @var string
128 */
129 var $contentType = '';
130 /**
131 * Output format doctype
132 * @var string
133 */
134 var $doctype = 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"';
135 /**
136 * Document namespaces
137 * @var string
138 */
139 var $namespaces = array();
140
141 /**
142 * Whether or not the theme engine should include the output generated by php
143 * @var string
144 */
145 var $bufferOutput = true;
146 /**
147 * Canvas-level template to use
148 * @var string
149 */
150 var $canvasTemplate = '';
151 /**
152 * Page-level template to use
153 * @var string
154 */
155 var $pageTemplate = '';
156 /**
157 * Content-level template to use
158 * @var string
159 */
160 var $contentTemplate = '';
161 /**
162 * Text content to display right after the contentTemplate output
163 * @var string
164 */
165 var $content = '';
166 /**
167 * The API version supported by this theme (used to achieve BC)
168 * @var string
169 */
170 var $themeAPI = '2.3';
171 /**
172 * Name of this theme parent (if any)
173 * @var string
174 */
175 var $parentTheme = '';
176 /**
177 * Array containing all this theme ancestors (parent,grand-parent,etc...)
178 * @var array
179 * @access protected
180 */
181 var $parentInfos = array();
182 /**
183 * Page construction plug-ins to use
184 * @var array
185 * @access public
186 */
187 var $plugins = array( 'xos_logos_PageBuilder' );
188
189 /**
190 * List of mime-types supported by this theme
191 * @var array
192 * @access public
193 */
194 var $supportedMimeTypes = '';
195 var $allowXHTML = true;
196
197 var $renderCount = 0;
198 /**
199 * Pointer to the theme template engine
200 * @var xos_opal_Smarty
201 */
202 var $template = false;
203
204 /**
205 * Array containing the document meta-information
206 * @var array
207 */
208 var $metas = array(
209 'http' => array(
210 'Content-Script-Type' => 'text/javascript',
211 'Content-Style-Type' => 'text/css',
212 ),
213 'meta' => array(
214 'generator' => 'XOOPS',
215 'robots' => 'index,follow',
216 'copyright' => 'Copyright 2000-2006',
217 ),
218 'link' => array(),
219 'script' => array(),
220 );
221
222 /**
223 * Array of strings to be inserted in the head tag of HTML documents
224 * @var array
225 */
226 var $htmlHeadStrings = array();
227 /**
228 * Custom variables that will always be assigned to the template
229 * @var array
230 */
231 var $templateVars = array(
232 'slogan' => 'Put a slogan if you wish',
233 'footer' => 'Powered by XOOPS, the noosphere, and caffeine',
234 );
235
236
237 /**#@-*/
238
239 /**#@+ @tasktype 10 Initialization*/
240 /**
241 * Initializes this theme
242 *
243 * Upon initialization, the theme creates its template engine and instanciates the
244 * plug-ins from the specified {@link $plugins} list. If the theme is a 2.0 theme, that does not
245 * display redirection messages, the HTTP redirections system is disabled to ensure users will
246 * see the redirection screen.
247 *
248 * @param array $options
249 * @return bool
250 */
251 function xoInit( $options = array() ) {
252 global $xoops;
253
254 if ( isset( $_SESSION ) ) {
255 $_SESSION[$xoops->services['http']->xoBundleIdentifier]['tmpDisallowRedirections'] = ( $this->themeAPI == '2.0' );
256 }
257 if ( $this->namespaces && !is_array( $this->namespaces ) ) {
258 $this->namespaces = array( '' => $this->namespaces );
259 }
260 if ( $this->supportedMimeTypes && !is_array( $this->supportedMimeTypes ) ) {
261 $this->supportedMimeTypes = explode( ",", $this->supportedMimeTypes );
262 }
263
264 if ( !$this->contentType || !in_array( $this->contentType, $this->supportedMimeTypes ) ) {
265 $this->contentType = $this->supportedMimeTypes[0];
266 }
267 if ( $this->contentType == 'application/xhtml+xml' ) {
268 if ( !$this->allowXHTML || false === strpos( $_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml' ) ) {
269 $this->contentType = 'text/html';
270 }
271 }
272
273 $this->template =& XOS::create( 'xos_opal_Smarty' );
274 $this->template->currentTheme =& $this;
275 $this->template->compile_id = '';
276
277 if ( $this->bufferOutput ) {
278 ob_start();
279 }
280 // Instanciate and initialize all the theme plugins
281 foreach ( $this->plugins as $k => $bundleId ) {
282 $this->plugins[$k] =& XOS::create( $bundleId, array( 'theme' => &$this ) );
283 }
284 return true;
285 }
286 /**#@-*/
287
288 /**#@+ @tasktype 20 Manipulating page meta-iformation*/
289 /**
290 * Adds script code to the document head
291 *
292 * This methods allows the insertion of an external script file (if $src is provided), or
293 * of a script snippet. The file URI is parsed to take benefit of the theme resource
294 * overloading system.
295 *
296 * The $attributes parameter allows you to specify the attributes that will be added to the
297 * inserted n";
573 }
574 break;
575 case 'link':
576 foreach ( $this->metas[$type] as $rel => $attrs ) {
577 echo '. $rel . '"' . $this->renderAttributes( $attrs ) . " />n";
578 }
579 break;
580 case 'stylesheet':
581 foreach ( $this->metas[$type] as $attrs ) {
582 if ( @$attrs['_'] ) {
583 echo '";
584 } else {
585 echo '. $this->renderAttributes($attrs) . " />n";
586 }
587 }
588 break;
589 case 'http':
590 foreach ( $this->metas[$type] as $name => $content ) {
591 echo '. htmlspecialchars( $name, ENT_QUOTES ) . '" content="' . htmlspecialchars( $content, ENT_QUOTES) . "" />n";
592 }
593 break;
594 default:
595 foreach ( $this->metas[$type] as $name => $content ) {
596 echo 'n";
597 }
598 break;
599 }
600 }
601
602 function genElementId( $tagName = 'xos' ) {
603 static $cache = array();
604 if ( !isset( $cache[ $tagName ] ) ) {
605 $cache[$tagName] = 1;
606 }
607 return $tagName . '-' . $cache[$tagName]++;
608 }
609
610 function renderAttributes( $coll ) {
611 $str = '';
612 foreach ( $coll as $name => $val ) {
613 if ( $name != '_' ) {
614 $str .= ' ' . $name . '="' . htmlspecialchars( $val, ENT_QUOTES ) . '"';
615 }
616 }
617 return $str;
618 }
619
620
621 function resourcePath( $path, $fromDocRoot = true ) {
622 global $xoops;
623
624 $parts = explode( '#', $path, 2 );
625 if ( count( $parts ) > 1 ) {
626 list( $bundleId, $resPath ) = $parts;
627 // This is component resource: modules are in 'modules', and components in 'components'
628 $themedRoot = ( substr( $parts[0], 0, 4 ) == 'mod_' ) ? 'modules' : 'components';
629 if ( file_exists( "$this->path/$themedRoot/$bundleId/$resPath" ) ) {
630 return "themes/$this->folderName/$themedRoot/$bundleId/$resPath";
631 } else {
632 return XOS::classVar( $bundleId, 'xoBundleRoot' ) . '/' . $resPath;
633 }
634 }
635 if ( substr( $path, 0, 1 ) == '/' ) {
636 $path = substr( $path, 1 );
637 $fromDocRoot = false;
638 }
639 if ( file_exists( "$this->path/$path" ) ) {
640 return "themes/$this->folderName/$path";
641 }
642 if ( !empty( $this->parentTheme ) ) {
643 if ( !is_object( $this->parentTheme ) ) {
644 $this->parentTheme =& XOS::create( 'xos_opal_Theme', array( 'folderName' => $this->parentTheme ) );
645 }
646 if ( is_object( $this->parentTheme ) ) {
647 return $this->parentTheme->resourcePath( $path, $fromDocRoot );
648 }
649 }
650 return $fromDocRoot ? "www/$path" : "themes/$this->folderName/$path";
651 }
652
653
654
655
656 }
657
658
659 ?>
I think that is excellent work, and shows the significance and importance of clearly defined properties. Yet we could only see it's true power if the developers of XOOPS follow the same line and merge the past work with future work, otherwise this is just an example of what could have been.