Translations of this page?:

Feng Office Plugin Tutorial: Hello World

In this tutorial we will create a minimal plugin that shows a simple message in a Feng Office tab. This should provide a basic understanding of how the Feng Office Plugin System works.

A tutorial for a less “trivial” example is being developed and can be found here.

Creating the plugin Structure

First, choose a plugin name, and create a folder with that name in the Feng Office plugins folder:

FENGOFFICE_ROOT/plugins/PLUGIN_NAME

where FENGOFFICE_ROOT is the document root for Feng Office on your server and PLUGIN_NAME is the name of your new plugin, in our case 'helloworld', for example:

/public_html/fengoffice/plugins/helloworld

All the necessary resources and code for your plugin will be placed in this folder, including javascripts, css, images and, of course, the application php (templates, views, controllers, models). One exception is the theme-specific CSS, which must be inserted in the relevant CSS stylesheet within your theme.

Plugin Metadata

The first file you need to create is the plugin metadata 'info.php'. Create this file under your plugin root folder 'plugins/PLUGIN_NAME/info.php' containing this php code:

info.php
<?php return array(
    "name"        => "helloworld",            // plugin name
    "version"     => "1",                     // plugin version
    "author"      => "Feng Office",           // author name
    "website"     => "http://fengoffice.com", // author website URL
    "description" => "My first Feng plugin"   // brief description	
);?>

This will provide information about the plugin version, description, order, dependencies, category, author and other metadata necessary for third party plugin management.

However, if you want to create a new tab along with your plugin, you will need to specify it with a tab definition follows:

info.php
<?php return array(
    "name"        => "helloworld",            // plugin name
    "version"     => "1",                     // plugin version
    "author"      => "Feng Office",           // author name
    "website"     => "http://fengoffice.com", // author website URL
    "description" => "My first Feng plugin",  // brief description	
    "tabs" => array(                          // tab definition
       array(
         "id"                        => "helloworld-panel", //tab id
         "ordering"                  => 2,                  //tab ordering position
         "title"                     => "helloworld tab",   //tab title (lookup key for lang file)
         "icon_cls"                  => "ico-world",        //CSS class for tab's icon
         "refresh_on_context_change" => true,               //re-run the controller if e.g. new workspace is chosen
         "default_controller"        => "helloworld",       //default controller
         "default_action"            => "say_hello" ,       //default action(method) called when tab is selected or context changes - used to list objects, etc.
         "initial_controller"        => "" ,                //initial controller
         "initial_action"            => "" ,                //initial action(method) called once per session - can be used to load js scripts, etc.
         "type"                      => "plugin",           //type - use "plugin"
         "object_type_id"            => 0                   //id of the content object if it is related to one, otherwise 0                        
                )
     )
);?>        

Note: Please look below at the 'Email' plugin example for further details regarding a content object association.

This tells the installer that it will have to create a new tab in the system, specifying id, title and many other configuration options, but the most important ones are default_controller and default_action.

The tab title will be looked up in a language file. In our case the lookup string will be “helloworld tab”. We need to provide a return string in the language file. Create the language folder 'plugins/PLUGIN_NAME/language/LANGUAGE', in our case 'plugins/helloworld/language/en_us'. Two files are placed into this folder: 'lang.js' and 'lang.php'. Simply copy the lang.js script from another plugin, and create 'lang.php' as follows:

lang.php
<?php return array(
	'helloworld tab'=>'World',
);

This will display 'World' as the our new tab's title. For multi-lingual support you may repeat this process for other languages.

Creating the Controller – The business layer

At this point we assume that you are familiar with MVC concepts. If not, we strongly suggest you explore the topic before proceeding.

Create the folder 'application/controllers' under your plugin structure:

 FENGOFFICE_ROOT/plugins/PLUGIN_NAME/application/controllers

Then create the following class under this folder:

[PLUGIN_NAME]Controller.class.php

That is, in our example (note the CamelCase):

HelloworldController.class.php

…with the following content:

HelloworldController.class.php
<?php class HelloworldController extends ApplicationController {                
        var $plugin_name = "helloworld"; //name of the plugin
 
        function __construct() {
                parent::__construct();
                prepare_company_website_controller($this, 'website');              
        }
 
        function say_hello() {
                $txt = "Hello World ! ! ! ! ";
                tpl_assign('message',$txt);
        }
}?>

In this case the controller loads the data, and assigns it to the view in a variable called 'message'.

Notes:

  • We have not spoken about models yet, so the data is hard-coded in order to simplify the example.
  • This is not what the actual Mail plugin does, but it has been used this way to explain it better

Creating the View – The Presentation Layer

Create the folders 'application/views/helloworld' under your plugin structure so that it looks like: FENG_ROOT/plugin/PLUGIN_NAME/application/views/OBJECT_NAME

i.e.: FENG_ROOT/plugin/helloworld/application/views/helloworld

Within the last folder, create the following file: 'say_hello.php' with the following content:

say_hello.php
<div class="hello-world">
        <h1><?php echo $message ?></h1>
        <p>Congratulations ! ! !</p> 
        <p>This is your first hello world application. <p>
</div>

Note: When invoking a controller action (or method talking in OOP), the system automatically loads the view with the same name; controller function 'ACTION()' will invoke view 'ACTION.php'.

Configuring the Tab Icon

In info.php we set the array element

"icon_cls" => "ico-world"

and now we need to create a CSS class .ico-world that styles a background with the desired icon image.

Create CSS stylesheet for the theme's tab at [FENG_ROOT]/plugins/helloworld/public/assets/css/helloworld.css and insert the class .ico-world. You may also create your an image folder for your plugin at [FENGOFFICE_ROOT]/plugins/helloworld/public/assets/images or, if suitable images are already available, simply use them instead, as we do here, i.e., the default theme's 16×16 sprites with a vertical offset of -357 pixels.

helloworld.css
.ico-world {
	background: transparent url('/public/assets/themes/default/images/16x16/all_16_16_vertical.png') no-repeat scroll 0 -357px !important;
}

Custom CSS and JS

Custom CSS and JS can be done in many ways:

INLINE (not recommended):

Each view can make use of <script> and <style> tags, but this does not follow the best practices of web development

Automatically load the css JS (recommended):

While loading a page, Feng Office will include the JS and css on its head section if you create those files following this convention: plugins/PLG_NAME/public/assets/javascript/PLG_NAME.js plugins/PLG_NAME/public/assets/css/PLG_NAME.css

At Runtime

In any place of your controller method add the following line: require_javascript('WhateverYorJsIsNamed.js', $this→plugin_name); Sometimes you want to include JS libraries only on some user actions, so this way is better if that is your case.

Installing the plugin

If you don't see the 'Plugins' icon in the Administration panel, then enable it by editing 'config/config.php' and inserting the line:

define('PLUGIN_MANAGER', true);
  • Close and restart Feng Office
  • Navigate to Adminstration → Plugins. You should now see an entry for 'helloworld' and an 'Install' link just below.
  • Manually edit the default theme stylesheet to include the class for the tab icon. (See Configuring the Tab Icon above)
  • Click the 'Install' link and, if successful, click the 'Activate' link.
  • Now refresh the browser (Ctrl+F5) and you should see your new tab “World” appear. If not, check the tab ordering for conflicts (Administration → Tabs) and retry.

To move the plugin to another instance of Feng Office simply:

  • Upload the helloworld folder to the new server
  • Make sure the plugin manager is enabled
  • Manually edit the default theme CSS stylesheet
  • Navigate to Administration → Plugins and 'Install' and 'Activate'
  • If necessary, set the tab order in Administration → Tabs
  • Refresh the browser

Note on Installing: With each plugin we may supply scripts that run at install time only. They are placed in the 'plugins/PLUGIN_NAME/install/' folder and invoked in order: 'sql/mysql_schema.php', 'sql/mysql_initial_data.php' and 'install.php'.

Note on Uninstalling. With each plugin we should supply a script called 'plugins/PLUGIN_NAME/uninstall.php', which is invoked by the Plugin Manager and whose function it is to remove the plugin's data and files.

The Uninstall mechanism is not covered in this tutorial, and for now we will manually uninstall:

  • Uncheck the tab in Administration → Tabs
  • 'Deactivate' and 'Uninstall' in Administration → Plugins
  • Remove your plugin folder from the plugins folder
  • Launch phpMyAdmin and delete the relevant records in the 'plugins', 'tab_panels' and 'tab_panel_permissions' tables.

Example with the Email Plugin

In this case we will take the Email plugin as an example provided that anyone can access its source code. The plugin name is 'mail'.

Create a folder named 'PLUGIN_NAME' under FENGOFFICE_ROOT/plugins.

All the necessary resources and code for your plugin will be placed here: javascripts, css, images, php (templates, views, controllers, models).

Plugin Metadata

The first file you need to create is the plugin metadata 'info.php'. Create this file under you plugin root folder 'plugins/PLUGIN_NAME/info.php' containing this php code:

<?php return array(
        "name" => "mail", //name of the plugin
	"version" => "1", //version of the plugin
	"author" => "Feng Office", //author
	"website" => "http://fengoffice.com", //website of the author
	"description" => "Email web client", //brief description of the plugin
	"dependences" => array('core_dimensions'), //if the plugin depends on another plugin to work correctly
	"order" => 1
);?>

This will provide information about the plugin version, description, order, dependences, category, author and other metadata necessary for third party plugin management.

If you want to create a new tab or associate it with a content object, you have to specify to the metadata file some extra configuration as shown below:

<?php return array(
    "name" => "mail",
	"version" => "2",
	"author" => "Feng Office",
	"website" => "http://fengoffice.com",
	"description" => "Email web client",
	"dependences" => array('core_dimensions'),// Array of plugin names (TODO check dependences)
	"order" => 1,
        "types" => array ( //association with a content object
		array(
			"id" => 22, //id of the content object
			"name" => "mail", //content object name
			"handler_class" => "MailContents", //name of the handler class
			"table_name" => "mail_contents", //name of the table containing it
			"type" => "content_object", 
			"icon" => "mail", //icon of the content object
			
		)
	),
    "tabs" => array ( //tab creation
                array(
                        "id" => "mails-panel", //plugin id
                        "ordering" => 2, //order of the tab when shown among the rest, 0 being the first
                        "title" => "email tab", //lang that will be used to specify the tab name
                        "icon_cls" => "ico-mail",  //icon that the tab will have
                        "refresh_on_context_change" => true, 
                        "default_controller" => "mail", //name of the controller 
                        "default_action" => "init" , //first action it will do when loading 
                        "initial_controller" => "" , 
                        "initial_action" => "" ,
                        "type" => "plugin", //type
                        "object_type_id" => 22 //id of the content object if it is related to one
                )
     )
);?>        

This tells the installer that it will have to create a new tab in the system, specifying id, title and many other configuration options, but the most important ones are default_controller and default_action.

Creating the Controller – The business layer

Create the folder 'application/controllers' under your plugin structure - so that it looks like FENG_ROOT/plugins/PLUGIN_NAME/application/controllers -, and create the following class under this folder:

Name of the class: [PLUGIN_NAME]Controller.class.php ⇒ i.e.: MailController.class.php

<?php class MailController extends ApplicationController {                
        var $plugin_name = "mail"; //name of the plugin
 
        function __construct() {
                parent::__construct();
                prepare_company_website_controller($this, 'website');
                Env::useHelper('MailUtilities.class', $this->plugin_name); //in case it needs an extra class to handle some functions
		require_javascript("AddMail.js",  $this->plugin_name); //in case it requires a JavaScript file to load certain data
        }

        function init() {
                //do something
        }
}?>

Discussion

PLEASE NOTE: Comments to the wiki should only contain suggestions and questions that help us to improve the manual (and not the software). These comments will be deleted as soon as the information has been integrated into the manual.

Posts that do not contribute to the DOCUMENTATION of the project will be DELETED.

Ask QUESTIONS on the product here.
Report BUGS here.
Propose NEW FEATURES here.


Enter your comment
 
plugins_documentation.txt · Last modified: 2013-02-27 18:06 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Noncommercial-Share Alike 3.0 Unported


Terms of Service | Privacy and Security policies | Copyright © 2014 fengoffice.com