A powerful dashboard script


Dashy minimum requirements:

  • PHP >= 5.4
  • Mcrypt PHP Extension
  • OpenSSL PHP Extension
  • Mbstring PHP Extension
  • Tokenizer PHP Extension
  • GD PHP Extension
  • FileInfo PHP Extension
  • MySql 5
  • Make sure mod_rewrite is enabled on your server
  • Please make sure that GET PUT DELETE POST are enabled in your server.

Dashy is built on top of laravel 5.0, so you can check documentation here: laravel 5.0


Installation instruction:

  • Download Dashy and unzip in a folder on your webserver. You can unzip also in the web root
  • Create a database
  • Rename .env.example file in .env
In the .env file there are different sections.

The first section is for app configuration:


You can leave it the same values.

The second section is for database settings:


Add your database credentials. DB_PREFIX is optional.

The third section is for google oauth settings:


In this section you set the oauth user credentials. If you want use google services like Analytics, you should create a new project on the google console. Once you have a project, you should set credentials.

Simply goes to Api & auth section of the console, click on credentials, create new client id, choose web application on the modal window. Simply copy/paste the client id and the client secret on the config.php file.

In the google console redirect uri section, add your redirect uri that is something as http://www.yourdomain.com/yourpathtodashy/auth/provider/response/google. For further information about google console, please go to https://developers.google.com/console/help/new/. Please do not forget to enable the api you want use in the google console.

Perform install:

Simply go to http://YOUR_PATH/install and you'll be prompted to step by step installation.

Public path:

Please note that for access your site you should type public in the url: http://YOURSITE:COM/PUBLIC. This is for security reason by laravel.

If you want avoid having "public" in the url simply set your htaccess to rewrite the url. Something like this:

  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/dashy/public/
  ServerName dashy.mysite.com

  <directory /var/www/dashy/public>
      DirectoryIndex index.php
      AllowOverride ALL


Setting up Dashy

After a successfull installation from the above process, it is required you setup your admin panel.

  1. Login to your admin panel by following this link www.yoursite.com/auth/login
  2. Default credentials are: Username: admin@admin.com / Password: secret
  3. When you login as administrator you have access to /admin section where you could change site settings

Creating custom widget

With Dashy you could also integrate your custom widget. It's simple and require few steps. But first we should analyze a widget.

Anatomy of a widget

A widget is composed by three elements:

  1. A folder which contains view to display the form to edit settings and a view to show the output
  2. A folder which contains angularJs directive, controller and model
  3. A php file as datasource which retrieve our data
  4. Show a menu item to add widget


So proceed with first step. Please note that there is an example folder in views/widgets. Each widget need two views: edit.html (for showing editing form) and show.html (for showing result).



Open the edit.html. In the first row we have this line of code:

<div ng-controller="ExampleCtrl">

The ng-controller attribute tells angular that "ExampleCtrl" should be used to control this view. So let's go to the controller. This is located in javascript/widgets/example. Please remember to always create a folder to group each widget. Order is important.

Let's give a look to controller.js.

app.controller("ExampleCtrl", ["$scope", function($scope) {
  var defaults = {
    sizeX: 1, 
    sizeY: 1,
    minSizeX: 1, 
    minSizeY: 1,
    label: null,
    settings: null

  if (!$scope.widget.id) {
    _.extend($scope.widget, defaults);


We simply assign default value to widget: dimensions, minimum dimensions (this is to prevent that some widget will be resized too smaller). The if statement simply extend the widget config. In this case the widget will be by default the minimum size. At the moment we can also delete label and settings, that we don't use right now. When a user clicks on submit button, a new widget example will be created with the settings we have choosen.

Now take a look at the directive.js: this file is responsible of the view show.html.

app.directive("example", ["$http", "ExampleModel", "myCache", function( $http, ExampleModel, myCache ) {

  function link(scope, element, attrs) {

    function onSuccess(data) {
		scope.enableSpinner = false
		scope.datamap = data
    function onFail(data) {
		scope.enableSpinner = false
    function update() {
		scope.enableSpinner = true
    	return ExampleModel.getDataExample(scope.widget).then(onSuccess,onFail);
    scope.updateWidget = function(w){
		var cacheId = scope.widget.id;
		var cachedData = myCache.remove(cacheId);
    	return update();

	scope.$on('widgetUpdate', function(event, widget) {
		if(widget === scope.widget.id){

  return {
    templateUrl: "views/widgets/example/show.html",
    link: link

At the end of the file we see templateUrl: "views/widgets/example/show.html". This tells angular which view to show. So when a new widget example is called this directive is responsible of the view shown. The other important line is link:link: this tells the directive the funtion to use when it's compiled. So in the link function we will insert all our logic.

Note also that in the first line we have added some dependencies: "$http", "ExampleModel", "myCache". The ExampleModel is the last piece of our widget and is responsile of the http requests.

When the directive get compiled run the update() function that enable the loading icon image, and call the ExampleModel.getDataExample function.

The ExampleModel is our service and is the service.js file:

    $http( {method: 'GET',
        url: BASE_URL + 'api/data_sources/example/',
        params: { widget_id: task.config.id, 
                  action: task.config.action, 
                  site: task.config.site, 
                  api_id: task.config.api_id }
    }).success(function(data, status, headers, config) {....

The service simply calls an url and pass some parameters.

So now comes our datasource. Please open api/index.php and uncomment this line:

// Example datasource
//require_once BASEPATH . 'routes/data_sources/example.php';                

In our sample datasource we simply crete a json

$app->get('/data_sources/example/', function() use($app) {	
    $result = array ('EN'=>18,'FR'=>29,'ES'=>38);
    $app->response->setBody(json_encode($result, JSON_NUMERIC_CHECK));

The last step is to add a menu item. Simply uncomment this line in index.php

    "name": "Example",
    "widget": "example",
    "submenu": []

Creating a simple widget

So let's build our first simple widget. For this tutorial we will create a very simple widget that embed a youtube video, just to show how easy is customize and extend Dashy with all your widget.

The first thing is to create a folder inside /javascript/widgets/ and give it a name, in this case "youtube". Inside this folder create a file controller.js with this code:

app.controller('YoutubeCtrl', ['$scope', function($scope) {
  var defaults = {
    sizeX: 2, 
	sizeY: 2,
    minSizeX: 2, 
	minSizeY: 2

  if (!$scope.widget.id) {
    _.extend($scope.widget, defaults);


It's a very simple angular controller that create a widget with base dimensions. Please note the name of the controller "YoutubeCtrl". Now in the "/views/widgets/" folder we will create the form to edit the data of the widget, like add a name and add the url of the video to display. So create a new folder "youtube" and create a file named "edit.html":

<div ng-controller="YoutubeCtrl">

<div td-field label="Name">
<input name="name" class="form-control" ng-model="widget.name" type="text" autofocus required />

<div td-field label="Video">
<input name="video" class="form-control" ng-model="widget.settings.video" type="text" autofocus required />


This file simply display a form with some input. Please note the "ng-controller="YoutubeCtrl"" attribute: this will tell angularJs to use YoutubeCtrl to edit our form. The form will create two model widget.name and widget.settings.video. Now let's create a directive that will show our youtube video. Go back to "/javascript/widgets/youtube/" folder and create a directive.j file.

app.directive('youtube', ['', function() {

  function link(scope, element, attrs) {

    function update() {
		scope.datavideo = scope.widget.settings.video;
    scope.updateWidget = function(w){
    // init the widget;

    scope.$on('widgetUpdate', function(event, widget) {
        if(widget === scope.widget.id){


  return {
    templateUrl: 'views/widgets/youtube/show.html',
    link: link

In the first line we give a name to directive "youtube". Note: always use camelcase as naming conventions in angularJs. Further info here. This simply directive will fire "update()" funtion that assign to scope.datavideo the value we set in the edit form. At the end of the file we choose which template to use to render this directive. So now we should create the show.html view. Go back to "/views/widgets/youtube/" folder and create a "show.html" file. The view is very simple, it embed a directive that display a youtube video if we pass an url.

<div ng-if="datavideo" class="wdgWrapper">
	<youtube-video video-id="datavideo" player-width="'100%'" player-height="'100%'"></youtube-video>

Issue and bug tracking

We use bitbucket for our issue tracking: please submit any bugs here. You could also suggest new features.