Control behavior based on device classifications
Without media queries:
Device telemetry stack to pass information to server
PHP objects in the core to access this information:
Classification
Screen
Classification
used by handlers
Screen
to determine mobile or desktop
Basic |
|
|
Standard |
|
|
Full |
|
|
A file per classification:
.src.css
versions are sources for minification
Source files must be minified for each build
Core CSS is loaded from /root/css/default
Custom CSS goes other subdirectories within /root/css
Loaded in FIFO order from /config/css.ini
Good for institutional-specific overrides
Assembled based on classifications like CSS handler
Complicated by URL parameters
basic_libs
, standard_libs
, full_libs
basic
, standard
, full
Libraries in /root/js/core
are always loaded
Other libraries included on request from /root/js
JS
objectIncludes are fetched through curl and minified
Need a way to determine device capabilities
Media queries aren't sufficient
Why not use metadata?
Instead, use Javascript to detect capabilities
How does browser-side code get to server?
What about devices without Javascript?
Capability detection
mwf.capability
to determine capabilitiesmwf.classification
Deliver data to server
Performance hit on first-load
Federation requires pass-through, not refresh
Infinite loop issues
mwf.capability
abstracts Modernizr and othersmwf.browser
for browser sizemwf.userAgent
for UA informationmwf.screen
for device sizemwf.classification
for classifying devicesmwf.override
for override handlingSubset of data exposed in PHP
PHP objects abstract the cookies set
Classification
Screen
User_Agent
*Browser
*User_Agent
and Browser
not advisable
Classification can be overridden by URI of any page
?override=[CLASSIFICATION]
?override=no
Mobile redirection script
assets/redirect/js.php?m=[URL]
?override_redirect=1
?override_redirect=0
Programmatic representation of MWF elements
$decorator = Site_Decorator::menu();
$decorator->set_title('Menu Title');
$decorator->add_item('Item 1', '#1');
$decorator->add_item('Item 2', '#2');
echo $decorator->render();
<div class="menu">
<h1>Menu Title</h1>
<ul>
<li><a href="#1">Item 1</a></li>
<li><a href="#1">Item 2</a></li>
</ul>
</div>
Site_Decorator::menu()
Site_Decorator::content()
Site_Decorator::button()
Site_Decorator::header()
Site_Decorator::footer()
Site_Decorator::form()
Site_Decorator::input()
Site_Decorator
is actually a factory
class Site_Decorator extends Decorator {
public static function button(){
$args = func_get_args();
return self::factory(__FUNCTION__, $args);
}
// ...
public static function factory($name, $args = array())
{
$name = strtolower($name);
require_once(dirname(__FILE__).'/site/'.$name.'.class.php');
$class = $name.'_Site_Decorator';
$refl = new ReflectionClass($class);
return $refl->hasMethod('__construct')
? $refl->newInstanceArgs($args) : new $class();
}
}
Site decorators extend underlying HTML decorators
class Content_Site_Decorator extends Tag_HTML_Decorator
{
public function __construct($inner = '', $params = array())
{
parent::__construct('div', $inner, $params);
$this->add_class('content');
}
// ...
They include additional entity-specific methods
public function &set_padded($val = true)
{
return $val ? $this->remove_class('not-padded')
: $this->add_class('not-padded');
}
Programmatic definition of HTML
Pattern of reuse
Extend as needed
Everyone wants rich interactivity, but...
How about a CSS-based solution?
Define a target element
<div class="expandable example">
<h2>Expandable Target</h2>
<p>This div will expand when Trigger is pressed</p>
</div>
Define a trigger element
<a href="#" class="trigger t-example">Trigger</a>
Include libary in JS handler
<script src="js.php?standard_libs=interactivity/expandable"></script>
<div class="expandable example">
<h2>Expandable Target</h2>
<p>This div will expand when Trigger is pressed</p>
</div>
<a href="#" class="trigger t-example">Trigger</a>
trigger
t-
The class expandable
defines transition from interactivity/expandable
Can represent any trigger/target interaction
Defined by a handler with event hooks
Handler is registered with mwf.standard.interactivity
mwf.standard.interactivity.expandable = {
'handler': {
'init':function(){
if(!$(this).hasClass('expanded'))
$(this).addClass('collapsed');
},
'exec':function(){
if($(this).hasClass('collapsed'))
$(this).removeClass('collapsed').addClass('expanded');
else
$(this).removeClass('expanded').addClass('collapsed');
}
}
}
mwf.standard.interactivity.expandable = {
'handler': {
// ...
}
};
mwf.standard.interactivity.registerHandler(
'expandable', // effect class name
'click', // trigger event
mwf.standard.interactivity.expandable.handler // effect handler
);
mwf.standard.interactivity.yourPlugin = {
'handler': {
'init':function(){ /* ... */ },
'exec':function(){ /* ... */ },
'initContainerBefore':function(){ /* ... */ },
'execContainerBefore':function(){ /* ... */ },
'initContainerAfter':function(){ /* ... */ },
'execContainerAfter':function(){ /* ... */ }
}
}
MWF is community source
GitHub is the starting point for MWF collaboration
For a campus,
Core developers fork from MWF or campus repository
Construct specifications for review on the GitHub wiki
File merge requests or issues for code review
Core Dev meetings on an as-needed basis