Widget Developer Documentation

Advanced Operations with Context

Context was introduced in the page on Collections and Content Sets. Be sure you’ve read that page thoroughly. This page builds off of that one.

As a refresher: context is a description of which records your widget has received for rendering. Or, in the language of database queries, it is an indication of which rows of data have been retrieved and passed to your widget to be displayed. 

To put it another way: context is a description of which chunk (or page) of data the widget has received. It is only relevant when working with collections and content sets.

The default context

As discussed on the Collections and Content Sets page, the default context gives your widget ten entries at a time, starting with the first (most recent) entry. So, if you do nothing to change the context, here is how your widget will receive it:

// retrieve the context from the widget renderer
//
$context = Moboom::getContext();
$startAt  = $context['from'];   // default: 0
$pageSize = $context['size'];   // default: 10
$total    = $context['total'];  // (this has no default)

You can override the default context in two ways.

On the URL. There are several variables that can be passed in the query string. Details can be found on the previous page. As one simple example, consider a widget which displays the most recent entries from a blog. This widget will receive ten entries from the renderer. However, you can force a larger dataset by changing the URL to, for example, mysite.com/blog?size=20. Now, when your widget executes on that page, it will be given twenty entries from the blog table.

Using a page element. The API function Moboom::includePageElement() takes two parameters. The first indicates which page element to render, and the second gives you a way to override the context for that page element. A full example of how to use this is given below.

A few examples with query strings

Each of these URLs should be run through Moboom::createUrl() before you use them in an anchor tag.

// create a link which changes the page number
//
$url = "/blog-listing?page=2";

// retrieve a larger data set
//
$url = "/blog-listing?size=100";

// retrieve a single post with a known ID
//
$url = "/blog-listing?id=3";

// query for posts with a given category
//
$url = "/blog-listing?q=Category:Design";

// sort by author
//
$url = "/blog-listing?sortby=Author&sort=ASC";

Multiple content sets on one page

Consider a web page with several custom widgets. One widget lists the most recent entries from a blog, and another lists the most recent news items. These widgets pull from two distinct content sets.

What context is used for those widgets? And what happens if you override the default context with query strings?

The query string overrides the default context, but this new context is passed to all widgets on the page. For example, if you link to a page using the query variable ?page=2, then all widgets on the page will receive items 11-20 from the content set. For this reason, query variables are best used on pages which only use a single content set.

If you have multiple widgets on a single page, and each of them needs an independent context, then you need to use page elements.

Page elements with context

As mentioned above, the API function Moboom::includePageElement() accepts a context parameter. Here is a simple example:

$pageElt = Moboom::getWidgetSetting( 'page_element');
$context = "size=1000";
Moboom::includePageElement( $pageElt, $context);

This widget asks the user to select a page element, to which it passes the context as shown above. If that page element contains widgets that use collections, they will be sent a set of elements with the requested context. In this case, those widgets will be sent the first 1000 elements, instead of the ten that it would get by default.

In our own widget development at Moboom, we’ve started using a custom widget which is deceptively simple and extraordinarily powerful. We call it the Page element with context widget. Here is the code:

<?php
$pageElt = Moboom::getWidgetSetting('page_element');
$context = Moboom::getWidgetSetting('context');

if ( empty($pageElt) && Moboom::isDesignMode())
    echo "(No page element specified.)";
else
    echo Moboom::includePageElement( $pageElt, $context);

Consider what happens when we want to have a blog listing page, but instead of using the default page size of 10, we want a page size of 20. One way to override the default context, described above, is to ensure that all links to that page are tagged with a query variable: mysite.com/blog?size=20. This is not optimal for many reasons: the overhead required to ensure that every link to your page is tagged with a query string is simply not maintainable.

Using the Page element with context widget, we have another solution which is much more elegant. Now, we place our blog listing widget inside a page element. Assign its settings as usual, with connections to the appropriate content set. And on the blog listing page, create an instance of the Page element with context widget. Set up that widget by selecting the new page element, and entering size=20 in the context.

The diagram below illustrates how to connect the dots. If we didn’t need to override the default context, we would only need two elements: the Blog listing page and the Blog listing widget. In order to set the context manually, we add two new elements: the Page element with context widget, and the Blog listing page element. And no query strings needed!

Study this simple diagram, and build a version of it for yourself. We recommend you try it out using a content set large enough to run some experiments on.