HTML Logo by World Wide Web Consortium (www.w3.org). Click to learn more about our commitment to accessibility and standards.

Moving forward with Composr

ocPortal has been relaunched as Composr CMS, which is now in beta. ocPortal 9 will be superseded by Composr 10.

Head over to compo.sr for our new site, and to our migration roadmap. Existing ocPortal member accounts have been mirrored.


More Useful Miniblocks Via Functions

There are no pages beneath this page

Posted
Submitted by ChrisW
In the previous tutorial, Creating Miniblocks from Third-Party Code , we saw how to write the PHP necessary for ocPortal to run our commands. In this short tutorial we will expand on this to create more interesting and useful miniblocks, which do more than simply repeat what they're told.

Functions

One of the most widely used ideas in programming is that of the function. Like functions in Maths (such as sine and cosine), functions can be used in PHP to re-use some process which has been defined before. All that is required to use a function is knowing its name, knowing what it needs to be given to act upon (eg. sine and cosine need to be given an angle to work with) and having it available to your program (not every function is available all of the time, since it would take up far too much memory to have them all waiting around and not being used). What makes functions so powerful is that in order to use them, we don't need to care about how they do what they do (their "implementation"), all we have to know is how to make them run ("calling" them).

Using a function in PHP is the same as in Maths, where we just write the function's name, then put whatever we want it to act upon (its "arguments") inside some parentheses (brackets) next to the name. For instance "sine(2)". If we need to give a function multiple arguments then we put commas between them, for example if we wanted the maximum of a series of numbers we might say "max(6,3,98.5,12)". If a function doesn't require any arguments then we simply leave the brackets empty, for example if we want a random number we might write "random()". The difference between functions in Maths and functions in programming is that programming functions don't just turn numbers into other numbers, they can do anything that the language (in our case PHP) is capable of. Here are some examples of using PHP functions (with comments describing what they do):

Code (php)

// 2 whole number arguments. Gives us an image
// with a palette of 16,777,216 colours, a width of
// 800 pixels and a height of 600 pixels.
imagecreatetruecolor(800,600)

// 1 text ("string") argument. Gives us the
// lowercase text 'hello world'.
strtolower('HELLO WORLD')

// No arguments. Gives us the "base URL"
// option of an ocPortal site
get_base_url()
 

Since a function can "give back" some value (we say it "returns" the value) we can pass this straight into another function as an argument by simply nesting the calls to the functions, like this:

Code (php)

// This will call the "get_base_url" function,
// which gives us a text string, and passes
// that string straight to the "strtoupper"
// function which makes it uppercase.
strtoupper(get_base_url())
 

We will use the variety of functions defined by PHP and ocPortal to spice up our map miniblock.

Using Functions In Miniblocks

ocPortal defines many functions, and a comprehensive description of them all can be found in the Application Programmers' Interface documentation. Here we will use a few simple functions to make the output of our map miniblock more useful. The functions we'll use are:
  • array, which takes any number of arguments of any type. It gives back an "array", or ordered list, containing whatever arguments you gave it. For example "array('a','b','c','d',9,10,11,12)" will return an array (list) of values ('a','b','c','d',9,10,11,12).
  • implode, which takes as arguments a string of text and an array of text strings. It returns a text string generated by sticking together each string in the array argument, with the string argument in between. For example "implode('hello',array('a','b','cde','f'))" will return a string of text 'ahellobhellocdehellof'.
  • strval, which takes an argument of any type and returns a text string representing it. For example "strval(58.7)" will return the text string '58.7' (which is not the same as the number 58.7, since that isn't a text string, it's a number).
  • get_option, which takes a string argument which should be the name of an ocPortal configuration option. It returns the value of that option. For example "get_option('site_closed')" returns (in my case, with an open site) 0.

The Minimodule Code

The following is the code of our improved minimodule. We put it in a file in the same way as in the first example. I've decided to call this file "main_openstreetmap_options.php" so that I can have both versions of the minimodule installed at once. The code still produces the HTML we took from openstreetmap.org like before, but rather than putting the whole thing in quotes and using it as-is, we split it up so that optional bits, like the values for width and height, can be swapped out for the values of ocPortal configuration options.
We then use the "echo" command to output each of these bits in turn, so that the browser sees them as one long piece of HTML. A few points to notice are that we keep the quote marks and commas of the HTML intact, which is important since the browser will be expecting them; we also put our calls to the "get_option function inside a call to the "strval" function, this is because our options will give us numbers and we want to convert them into text string (which strval does for us); finally we add 0.01 to the longitude and latitude at one point, this is because the OpenStreetMap code uses a different value for the left, right, top and bottom of the map so we need to keep them slightly apart or else our map will have zero contents.

Code (php)

<?php
/* This is a minimodule to show a map from OpenStreetMap.org.
It uses site configuration options to determine what should be
displayed */

echo '<iframe width="';  // HTML
echo strval(get_option('map_width'));
echo '" height="';  // HTML
echo strval(get_option('map_height'));
echo '" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://www.openstreetmap.org/export/embed.html?bbox=';  // HT$
echo strval(get_option('longitude'));
echo ',';  // HTML
echo strval(get_option('latitude'));
echo ',';  // HTML
echo strval(get_option('longitude')+0.01);  // Give the map an area of 0.01x0.01
echo ',';  // HTML
echo strval(get_option('latitude')+0.01);  // Give the map an area of 0.01x0.01
echo '&amp;layer=mapnik" style="border: 1px solid black"></iframe><br/><small><a href="http://www.openstreetmap.org/?lat=';  // HTML
echo strval(get_option('latitude'));
echo '&amp;lon=';  // HTML
echo strval(get_option('longitude'));
echo '&amp;zoom=';  // HTML
echo strval(get_option('map_zoom'));
echo '&amp;layers=M">View Larger Map</a></small>';  // HTML
 

This is starting to look complicated isn't it! We just need to keep in mind that everything inside /* and */ are just comments, they're not part of the code, as are the comments after the slashes "//". Everything that is just repeating the copy-pasted HTML from before has been given the comment "HTML". Disregarding those bits we see that the only new parts are the function calls and the "+0.01".

Notice that each line ends in a semicolon ";" like the "echo" line in our first example. It's very common to forget to put these, so it may help if you think of semicolons as the symbol for "and then". For example

Code (php)

1 + 2;
3 + 4;
 
Means "one plus two and then three plus four and then (end)". If you're having problems with your miniblock then I'd recommend you check each line for its semicolon, and check whether your opening and closing quotes match.

Required ocPortal Setup

This miniblock uses functions to get ocPortal options, however I've made up these options for the example. In order for this miniblock to work we need to add these options to the ocPortal site we're going to run it on (you probably won't want to do this on a live site if you're only experimenting. I do my experimenting on a local installation of ocPortal that I don't mind reinstalling whenever I mess it up ;) ). The following code will do it:

Code (php)

<?php
add_config_option('MAP_WIDTH','map_width','integer','return 300;','BLOCKS','MAP_BLOCK');
add_config_option('MAP_HEIGHT','map_height','integer','return 300;','BLOCKS','MAP_BLOCK');
add_config_option('MAP_ZOOM','map_zoom','integer','return 16;','BLOCKS','MAP_BLOCK');
add_config_option('LONGITUDE','longitude','float','return 0.0;','BLOCKS','MAP_BLOCK');
add_config_option('LATITUDE','latitude','float','return 0.0;','BLOCKS','MAP_BLOCK');
 

As you can see, it's all just more function calls with text string arguments. In order to run this code, you can either use the "OcCLE" commandline from your site's admin zone (put a colon in the entry box and copy in the first "add_config_option" line then press the "Go" button, then repeat for the rest of the "add_config_option" lines) or you can save them to a file called "set_up_map.php" inside the "minimodules_custom" folder of the "pages" folder in the "adminzone" folder of your installation. Now you can run it by visiting your site with "/adminzone/index.php?page=set_up_map" at the end of the address. You've just made your first "minimodule", which you can learn about in other tutorials :)

The next thing to do is to set up the translation strings needed by these options. In ocPortal prettty much everything is translatable, so we can't just give an English name to the add_config_option function and leave all non-English speakers unable to use the miniblock. Instead, what we gave to the add_config_option function were code names which we can use to reference these options' names. Now we must define these names in at least one language.

The quickest way to do this is to put them in the "global" language file, which is available to all parts of the site. We're going to define the names for English, so copy the file "lang/EN/global.ini" in your ocPortal installation into the folder "lang_custom/EN" then open this copy in your programming text editor. Go to the end of the file and add these lines:

Code

MAP_BLOCK=Map block
MAP_WIDTH=Map width
MAP_HEIGHT=Map height
MAP_ZOOM=Zoom level
LONGITUDE=Longitude
LATITUDE=Latitude
CONFIG_GROUP_DESCRIP_MAP_BLOCK=Parameters to control the OpenStreetMap block.

Save the file and visit your site's admin zone. Go to "Configuration" under the "Setup" menu and click on "Block options". There should be a section called "Map block" where you can enter the latitude, longitude, width, height and zoom level of the map.

Using the Miniblock

To include this new miniblock on a page you just need to call it from Comcode like any other block or miniblock via the code [block]main_openstreetmap_options[/block] (or whatever filename ou gave it, without the ".php"). Below is a screenshot of this miniblock embedded on the homepage of a test site.


I hope you've not been too overwhelmed by this further exploration of ocPortal, PHP and programming in general :)
 
Posted
Submitted by ChrisW
If you wish to turn your miniblock into an ocPortal addon that anyone can install then you can follow the instructions and diagrams in this section of the ocPortal programming framework tutorial. ocPortal, by default, gives administrators access to a "tree view" of all the addons which have been published on ocPortal.com. This means that, if you upload your addon to ocPortal.com, it will appear inside (almost) every ocPortal installation in the world, and can be downloaded and installed automatically with just a few clicks!
 
CEDI change-log Post