NB: It’s a work in progress. . To add this you need: -
- The Widget Controller
- .htaccess Changes
- The Widget Container Front-End Component
- A _widgets directory
- Your First Widget
Widget Controller
The widget controller is basically a standard controller that then mimics the Loader class and loads the widget screens. It also provides a little support for Ajax links, so that you can put anchor links in your widgets and the response will come back to calling widget only.
// ================================================================================= //
class WidgetController extends Controller
{
// ============================================================================= //
function All() {}
function Input() {}
function Delete() {}
// ============================================================================= //
function Run()
{
// expecting parameters: -
//
// $this->get['widget'] = 'raketu'
// $this->get['screen'] = 'home';
//
// this widget would be available on the following URL: -
//
// http://www.blah.com/widget/raketu/home.html
// basically what do we have to do ...
//
// 1. get the widget's controller
require_once "_widgets/" . $this->get['widget'] . "/Controller.php";
// 2. get the widget 'screen' - basically this is the same as
// running a regular command in Orqi.
$controller_name = $this->get['widget'] . 'Controller';
$action_name = $this->get['screen'];
$widget_controller = new $controller_name();
$widget_controller->Initialise($this->config, $this->session, $this->get, $this->post, $this->files);
$widget_controller->$action_name();
}
// ============================================================================= //
function LoadWidget($widget_name='', $screen='', $sendtoscreen=true)
{
if (!$sendtoscreen) ob_start();
switch (true)
{
case file_exists("_widgets/" . $widget_name . "/_" . $screen . ".php"):
require "_widgets/" . $widget_name . "/_" . $screen . ".php";
break;
default:
echo "<p>" . $widget_name . "'s' " . $screen . " screen is missing.</p>";
break;
}
if (!$sendtoscreen)
{
$return_html = ob_get_contents();
ob_end_clean();
return $return_html;
}
else return false;
}
// ============================================================================= //
function MakeWidgetLink($widget='', $screen='', $params='', $secure='')
{
if (empty($widget) || empty($screen)) return $this->config->app['location'] . '/';
else
{
if ($this->config->app['mod_rewrite'] == false)
{
$site_text = (empty($this->config->app['default'])) ? "" : "site=" . $this->config->app['default'] . "&";
$link_text = $this->config->app['location'] . "/index.php?" . $site_text . "object=widget&action=run&widget=" . $widget . "&screen=" . $screen;
$separator = "&";
}
else
{
$site_text = (empty($this->config->app['default'])) ? "" : $this->config->app['default'] . "/";
$link_text = $this->config->app['location'] . '/' . $site_text ."widget/" . $widget . "/" . $screen . "." . $this->config->app['extension'];
$separator = "?";
}
if ($this->config->app['ssl'] == true && (!empty($_SERVER['HTTPS']) || $secure == true))
{
$link_text = str_replace('http:', 'https:', $link_text);
}
if (!empty($params)) $link_text .= $separator . $params;
return "javascript: rh_" . $widget . ".LoadPart('widget_" . $widget . "', '" . $link_text . "');";
}
}
// ============================================================================= //
}
// ================================================================================= //
.htaccess Changes
Put this line in your .htaccess file. You can get by without mod_rewrite, but I’d really recommend it as the urls can get proper tricky.
RewriteRule ^widget/(.*)/(.*).html$ index.php?object=widget&action=run&widget=$1&screen=$2&%{QUERY_STRING} [L]
The Widget Container Front-End Component
This is a work in progress very much meaning I’m not particularly happy with it’s state, but at least it is working. It will load a div with a specified ID and then give you a slice of supporting javascript that will wait for and process ajax instructions on that specified ID only.
<?
// param1: is the name of the widget
$separator = "?";
$extra_parameters = "";
if (!empty($param2))
{
$extra_parameters .= $separator . "param1=" . $param2;
$separator = "&";
}
if (!empty($param3)) $extra_parameters .= $separator . "param2=" . $param3;
?>
<script>
var ResponseHandlerFor_<?=$param1?> = function()
{
this.FillWidget = function(request)
{
$('widget_<?=$param1?>').innerHTML = request.responseText;
}
this.Oopslol = function()
{
$('widget_<?=$param1?>').innerHTML = "<h3>ooops.</h3><p>there was an error.</p>";
}
this.PreLoader = function(element_id)
{
$(element_id).innerHTML += "<p><img src='/_img/loading_animation.gif'></p>";
return false;
}
this.LoadPart = function(element_id, url)
{
this.PreLoader(element_id);
new Ajax.Request(url, {method:'get', onComplete:rh_<?=$param1?>.FillWidget, onFailure:rh_<?=$param1?>.Oopslol});
return false;
}
this.PostForm = function(submit_form)
{
$(submit_form).request({onComplete:rh_<?=$param1?>.FillWidget, onFailure:rh_<?=$param1?>.Oopslol});
$('widget_<?=$param1?>').innerHTML = "<h2>LOADING</h2><p>Please wait ...</p><p><img src='/_img/loading_animation.gif'></p>";
}
this.OnLoadHandler = function()
{
this.LoadPart('widget_<?=$param1?>', '/widget/<?=$param1?>/home.html<?=$extra_parameters?>');
}
}
var rh_<?=$param1?> = new ResponseHandlerFor_<?=$param1?>();
</script>
<div class="widget" id="widget_<?=$param1?>" style="margin: 0px 5px 5px 0px; float: left; width: 300px; border: 1px dotted #ccc;"></div>
<script>rh_<?=$param1?>.OnLoadHandler();</script>
A _widgets directory
Create a directory called “_widgets” in your project root. It’s that simple.
Scriptaculous
Ah, yes. Without scriptaculous none of the AJAX stuff will work. Probably best to download it and put it in your “_js” directory. You can include scriptaculous site wide in your _HeadTag.php component.
<script src="<?=$this->config->resource['js']?>/scriptaculous.js" type="text/javascript" language="javascript" charset="utf-8"></script>
Your own widget
Please see the article entitled “Your First Widget” for more information.