Actions

Add new menu and view by a plugin

From LimeSurvey Manual

Revision as of 17:44, 7 August 2017 by Markusfluer (talk | contribs) (Added help for 3.0.0 onwards)

How to write a plugin that adds a menu to the admin menubar & when clicked renders some content.

3.0.0.beta-1 and above

Since 3.0.0 it is possible to manually add and create menu entries. Depending on your plugin you can use this function as a benchmark to add either a menuentry or a full menu for your plugin. Please also have a look at the manual page for menucreation.

For this special case there is the newly added plugin event "onPluginRegistration" that is called once when the plugin is discovered.

  public function onPluginRegistration(){
    $menuArray = array(
        "parent_id" => 1, //1 -> main surveymenu, 2-> quickemenu, NULL -> new base menu in sidebar
        "title" => "[your plugin menus name]",
        "position" => "side", // possible positions are "side" and "collapsed" state 3.0.0.beta-1
        "description" => "[your plugins menu description]"
    );
    $newMenuId = SurveyMenu::staticAddMenu($menuArray);

    // repeat this as often as you need it
    $menuEntryArray = array(
        "name" => "[name of the action]"
        "title" => "[title for the action]",
        "menu_title" => "[title for the action]", 
        "menu_description" => "[description for the action]",
        "menu_icon" => "[icon for action]", //it is either the fontawesome classname withot the fa- prefix, or the iconclass classname, or a src link
        "menu_icon_type" => "fontawesome", // either 'fontawesome', 'iconclass' or 'image'
        "menu_link" => "[admin/]controller/sa/action", //the link will be parsed through yii's createURL method
        "addSurveyId" => true, //add the surveyid parameter to the url
        "addQuestionGroupId" => true, //add gid parameter to url
        "addQuestionId" => true, //add qid parameter to url
        "manualParams" => "" //please read up on this setting as it may render the link useless
    );
    SurveyMenu::staticAddMenuEntry($newMenuId, $menuEntryArray);

  }


2.55.0 and above

1. Create a new plugin, in our case called PageDemo. In the plugins/ folder, there should be a folder name called PageDemo and within it a class called PageDemo inheriting \ls\pluginmanager\PluginBase. Also create a folder called views/ in your plugin folder and add index.php to it.

plugins/
  PageDemo/
    PageDemo.php
    views/
      index.php

This is the PageDemo.php file so far, with basic settings:

<?php

use \ls\menu\MenuItem;
use \ls\menu\Menu;

/**
 * Demo for adding new admin page in LimeSurvey 2.56.1
 * @since 2016-11-22
 * @author Olle Härstedt
 */
class PageDemo extends \ls\pluginmanager\PluginBase
{
    static protected $description = 'Short demo on how to show a new admin page';
    static protected $name = 'PageDemo';
    protected $storage = 'DbStorage';
}

2. Subscribe to event beforeAdminMenuRender to append menus:

    /**
     * Init plugin and subscribe to event
     * @return void
     */
    public function init()
    {
        $this->subscribe('beforeAdminMenuRender');
    }

3. Add a method called beforeAdminMenurender to the plugin class and append a menu object to the event:

    /**
     * Append menus to top admin menu bar
     * @return void
     */
    public function beforeAdminMenuRender()
    {
        // Create the URL to the plugin action
        $url = $this->api->createUrl(
            'admin/pluginhelper',
            array(
                'sa'     => 'fullpagewrapper',
                'plugin' => $this->getName(),
                'method' => 'actionIndex'  // Method name in our plugin
            )
        );

        // Append menu
        $event = $this->getEvent();
        $event->append('extraMenus', array(
            new Menu(array(
                'label' => 'Menu label',
                'href'  => $url
            ))
        ));
    }

4. Add the method actionIndex to the plugin class. This method will call renderPartial to render a view in the views/ folder.

    /**
     * @return string html 
     */
    public function actionIndex()
    {
        return $this->renderPartial('index', array(), true);
    }

5. Add some HTML to the view index.php in the views/ folder

<div class='container-fluid'>
    <h3 class='pagetitle'>A page</h3>
    <div class='row'>
        <div class='col-sm-6'>
            <p>Left column</p>
        </div>
        <div class='col-sm-6'>
            <p>Right column</p>
        </div>
    </div>
</div>

6. Result

2.06 lts/2.6.x lts

1. Create a new plugin. let us call it Rewards

2. register for events afterAdminMenuLoad and newDirectRequest in the constructor

3. implement the above methods methods in the new plugin class

4. In the method afterAdminMenuLoad, add a new menu item and link it to

   admin/plugins/direct?plugin=<plugin_name>&function=<plugin_action>
   e.g
   admin/plugins/direct?plugin=rewards&function=assignRewards

The best way to to this would be to make use of the createURL method:

   'href' => $this->api->createUrl('plugins/direct', array('plugin' => 'Rewards', 'function' => 'assignRewards')),

5. implement the method newDirectRequest

   public function newDirectRequest(){
       $event = $this->event;
       
       // you can get other params from the request object
       $request = $event->get('request');
       
       //get the function name to call and use the method call_user_func
       $functionToCall = $event->get('function');        
       $content = call_user_func(array($this,$functionToCall)); 
       //set the content on the event      
       $event->setContent($this, $content);        
   }


6. implement the method plugin_action, in our case it is assignRewards(). In this method currently i am just trying to return some dummy content, you can have sophisticated page rendered.

   public function assignRewards() {
        $content = "<h1> plugin content set succesfully </h1>";
        return $content;        
    }


7. The full Rewards.php File:Rewards1.zip


8. This is how the UI looks now.