wiki:FaqCustomizations

TOC?

FAQ: Customizations

Customizations of CSS and JavaScript

Since version 3.1 p.mapper has a function to load all CSS (*.css) and JavaScript (*.js) files that are loacted under the respective config directory (the default is /config/default/) after all files of the /javascript/ and /templates/ directories. This way all settings of the files in these directories are overwritten with the settings under the config directory.

It is therefore recommended to make modifications and add new styles in a separate file (called e.g custom.css) under the config directory. It is also possible to overwrite existing JavaScript functions by cloning them and putting them also under the config directory (e.g. in a file called custom.js) and make all modifications there. In addition, any *js file under the /javascript/ directory is loaded, so it's also possible to add new JavaScript functions there in a new *js file

A very good tool for working with CSS is the Firebug extension for Firefox. It allows modifying styles on the fly and lets you identify the CSS files determining the style of an element.

Plugins

Since version 3.1 p.mapper has also the possibility to add new functionality using a plugin API. All plugins should be placed under the /plugins/ directory and loaded via the config XML file (config_xyz.xml) under the <plugins> key: add all plugins to be loaded as a comma-separated list.

Plugin development

Configuration

The name of the plugin and the folder name must be identical. The configuration file for the plugin shall have the name config.inc and must be directly below the plugin directory. config.inc is a PHP file and has the following structure:

  // PHP files loaded into map.phtml
  $phpFiles = array("exportquery.php", "export.xls.php");

  // PHP files loaded into globals.php
  // = in map.phtml (almost pmapper beginning), AJAX calls, printing, etc...
  $phpMapObjModifierFiles = array("ms_auto_refmap.php");

  // JavaScript files referenced in map.phtml 
  $jsFiles  = array("export.js");

  // CSS files referenced in map.phtml
  $cssFiles = array("export.css");
  
  // JavaScript init function to be executed at loading time of the application
  $jsInitFunction = "myPlugin_init()";

All PHP, JavaScript and CSS files listed in the respective arrays are loaded into the main file map.phtml and are available there.

If it is necessary to execute a JavaScript function every time the map is refreshed then add to the init function referenced in config.inc something like

   $("#pmMapRefreshImg").bind("load", function(e){
      pm_scaleBar.update(PMap.scale);
   });

This requires a new entry in map.phtml, e.g. after

  <div id="pmQueryContainer" class="jqmDialog hide"></div>

like

  <div id="pmMapRefresh" style="visibility:hidden">
     <img id="pmMapRefreshImg" src="images/pixel.gif" alt="maprefresh">
  </div>

and the latest version of /javascript/xmlhttp.js. Binding the event directly to the mapImg object causes less smooth swapping of the map image.

Adding a plugin to the GUI

A functionality can be attached to the GUI e.g. via a button or a menu entry. In this case the plugin needs to be referenced in the $buttons or the $menu array in the php_config.php file. The steps are shown by an example of the coordinates plugin that shows the coordinates of the mouse click (this could be used as base for digitization of points).

in php_config.php and an entry in the buttons array like

  "coords"      => array(_p("Show Coordinates"), "0"),

The "0" means that it is a mouse tool and changes the active button, but does not directly launch anything (like e.g. the "home" button does). There are 2 functions related to this tool and they are included in the file coordinates.js (that is referenced in config.inc):

  function coords_click() {...}
  function coords_start(imgxy) {...}

Note that the functions have the coords in common, this prefix must be the one used in php_config.php/$buttons.

The "_click()" function must specify the behaviour of the tool, e.g. if the mouse shall be able to draw a box or just allow clicks (see examples in mapserver.js/domouseclick() for the various default tools). The "_click()" function is executed by every click in the map and launches the "_start()" function. In this function the developer has to define what to do further on with the information that it has received from the mouse click, i.e. the pixel coordinates from the clicked area on the map.

Limitations of the plugin API

p.mapper was developed as an application framework that shall allow multiple functionalities that are fairly easy to set up and use. It has not been designed as a development framework like Chameleon. So the plugins API has been added recently and might lack some functionalities. Therefore an integration of a plugin could in rare cases require some modifications of the main source, e.g. for interaction with mouse events. In this case you can contact me and I will see if and how this can be achieved.

Available plugins

A short description of plugins is available here.

Query results rendered into PDF

I'd like to work on the possibility to attach the info related to selected area (for some layers) to the pdf print under the legend. What's the right way?

The plugins directory has a folder "export" (development version see here) that allows export of query results to PDF, Excel and CSV.

Some frequently asked customizations

Sub-categories

p.mapper does not foresee any deeper tree structure for the TOC than "CATEGORIES - GROUPS". If you want such functionality ("sub-categories", "nested categories", "category levels") you need to implement this by yourself. Some files to be modified for this are eg.

  • incphp
    • toc.php
    • layerview.php
    • init/initmap.php
  • javascript/pm.toc.js
  • config/config_default.xml

Creating dialog boxes with PM.Dlg.createDnRDlg

In plugins writing or extending p.mapper code, it is nice to use dialog boxes in the p.mapper way. Here it is an example for the PM.Dlg.createDnRDlg() function:

var dlgOptions = {
    width: 640, height: 480, left: 100, top: 50,
    resizeable: true,
    newsize: true,
    container: 'pmDlgContainer',
    name: 'PopupWindow'
};
 
var dlg = PM.Dlg.createDnRDlg(
    dlgOptions,
    _p('Dialog title'),
    popupUrl
);

The non-trivial options are:

newsize
Defines if the dialog should always be reset to its width/height defined in the options. If false it keeps the dimensions of the state when it was closed last time.
container
Defines the ID of a <div> element to add the dialog to. But don't worry too much with this, if the container with this ID does not exist it will be created automatically. You should just avoid to use ID's that might already be used for other things (like 'map'). If two dialogs use the same container then opening one will always close the other one if already opened.
name
Should be unique (treat it like an ID, no blanks, no special chars), so taking the name of the plugin directory (which must be unique) is a good idea. But only important if more than one dialog are open at the same time.

Once the dialog is opened, it can be addressed (e.g. to change its content) using jQuery. In the following example if the dialog does not exists, it will be created; otherwise its content is reloaded and it is shown:

var dlgOptions = {
    width: 640, height: 480, left: 100, top: 50,
    resizeable: true, newsize: true,
    container: 'pmDlgContainer',
    name: 'PopupWindow'
};
 
var popupUrl = PM_PLUGIN_LOCATION + '/popup/popup.php?' + SID + '&key=' + val;
var dlgObject = $('#' + dlgOptions.container + '_MSG');
if (dlgObject.length < 1) {
    var dlg = PM.Dlg.createDnRDlg(dlgOptions, _p('Pop-up window'), popupUrl);
} else {
    $.ajax({
        url: popupUrl,
        type: 'GET',
        dataType: 'html',
        success: function(response) {
            dlgObject.html(response);
            dlgObject.parent().parent().show();
        }
    });
}

When using forms, p.mapper has two handy PM.Form JavaScript functions to read all the form values and to transform them into a string to be used in AJAX post or get requests:

PM.Form.getFormKVP()
Returns everything in a string ready for URL concatenation, like &key1=value1&key2=value2...
PM.Form.getFormKvpObjAll()
Returns everything in object/array notation, like {key1: value1, key2: value2, ...}
Last modified 6 years ago Last modified on Jul 22, 2011, 3:20:35 PM