Developer's Guide for Creating Plugins for the Breeze Website Builder™

Developing Plugin Consoles

You may need to have some custom control console for your plugin for a variety of reasons, i.e., you want to store setup information for your plugin in a custom table. There are few restrictions for building these console. Note: This step is optional as many plugins only to to add code to the pages themselves and can be styled using your own pre-defined style sheets it the CSS editor. But if you do need some kind of control console, here are some tips.

To give your console a button in the main menu of the Breeze Website Builder™, you will make sure your plugin record has the following fields populated:

Required:

console_path
This is the path to a backend console module that you created to FTP to the site. A button will appear in the main menu of the Breeze Website Builder™ when somebody creates a page with your plugin in it. You can put it in any folder you wish. Make the path absolute with regard to webroot, i.e. /plugins/my_plugin_console.php

console_link_text
This is simply the text you want to show on the button for accessing your backend console to your plugin.

console_link_image
This the path to the image that will be used for the plugin console button normal state.

console_link_image_mo
This the path to the image that will be used for the plugin console button mouse-over (hover) state.

console_link_image_down
This the path to the image that will be used for the plugin console button down state.

Optional, but highly recommended:

language_folder
Folder name to store language Files. Typical path is manage/plugins/lang/yourpluginname and is relative to document root.

console_link_text_define
Name of language define for console link test in language files. If a language file is provided, this will be used instead of console_link_text.

Optional:

button_group
Group to include console button, i.e CONTENT, MENUS, etc. Possible values are content_functions, menu_functions, style_functions, page_functions and other_functions. If left blank, the button group will default to other_functions.

AccessLevel
Access level required to have access to your backend console. If the logged-in user does not have sufficient privileges to use your plugin, then they will not see your plugin button on the main menu.

 

Console Code Suggestions

At the top of your module, you will need the following line:

include ("check_session.php");

This code does two things: First, it ensures that you one has access to your console unless they are logged into the Breeze Website Builder™. Second, it hands your module a handle to the database as $bwb_dbh.

It is strongly recommended that you make your console capable of working with language files. You will need the following code new the top of module:

$query = "SELECT `language_folder` FROM " . BWB_TABLE_PREFIX . "plugins WHERE `name` = 'mypluginname'";
$result = $bwb_dbh->query($query);
$row = $result->fetch(PDO::FETCH_ASSOC);
$language_folder = $row['language_folder'];

$document_root = $_SERVER['DOCUMENT_ROOT'];
if (defined(BWB_LANG))
   include_once ($document_root . "/" . $language_folder . "/" . BWB_LANG . ".php");
else
   include_once ($document_root . "/" . $language_folder . "/en.php");

where mypluginname is the name of your plugin as defined in your plugin record. Your plugin record will contain a string in the language_folder field that is the path to your language file. The typical path would be manage/plugins/lang/mypluginname and is relative to document root. Your language definition files go in that folder and are named as two-letter ISO country codes with the PHP extension, i.e. en.php. Below is an example of the English language file for the calendar and events plugin that is includes in the default installation of the Breeze Website Builder™:

<?php
////////////////////////////////////////////////////////////////////////
// Breeze Website Builder
// Copyright Silver Dolphin Solutions, LLC, Edward Lemmers, P.E.
// For licensing, see license.txt.
// Created: 3/1/2015 ELL

///////////////////////// Calendar and Events /////////////////////////
// Buttons:
define('CALENDAR_EVENTS_HEADING', "Revise Schedule");
define('CALENDAR_EVENTS_REVISE_SCHEDULE_BTN', "Revise Schedule");
define('CALENDAR_EVENTS_ADD_EVENT_BTN', "Add New Event");
// Console Text:
define('CALENDAR_EVENTS_SAVE_INSTRUCTIONS', "Note: Changes will not be recorded unless you select");
define('CALENDAR_EVENTS_DATE_FORMAT', "(YYYY-mm-dd)");
define('CALENDAR_EVENTS_START_TIME', "Start Time");
define('CALENDAR_EVENTS_END_TIME', "End Time");
// Popup Messages:
define('CALENDAR_EVENTS_DELETE_EVENT_CONFIRM_1_MSG', "Are you sure you want to delete the <b>");
define('CALENDAR_EVENTS_DELETE_EVENT_CONFIRM_2_MSG', "</b> event?");
define('CALENDAR_EVENTS_DATE_FORMAT_MSG', "Please fill in the date in the format of 'yyyy-mm-dd'.");
define('CALENDAR_EVENTS_COULD_NOT_DELETE_EVENT_MSG', "No records found. Could not delete event.");
define('CALENDAR_EVENTS_LOCATING_EVENTS_MSG', "Locating events...");
define('CALENDAR_EVENTS_EVENT_DELETED_MSG', "Event deleted");
define('CALENDAR_EVENTS_DELETING_EVENT_MSG', "Deleting event...");
define('CALENDAR_EVENTS_COULD_NOT_UPDATE_EVENT_MSG', "No records found. Could not update event.");
define('CALENDAR_EVENTS_EVENT_UPDATED_MSG', "Event updated");
define('CALENDAR_EVENTS_UPDATING_EVENT_MSG', "Updating event...");
define('CALENDAR_EVENTS_COULD_NOT_UPDATE_USER_LISTS_MSG', "No records found. Could not update user lists.");
define('CALENDAR_EVENTS_USER_LIST_UPDATED_MSG', "User lists updated");
define('CALENDAR_EVENTS_UPDATING_USER_LIST_MSG', "Updating user lists...");
define('CALENDAR_EVENTS_MEMORY_LIMIT_ERR', "You have reached the memory limit of the number of events that can be added in one session. To continue, save any unsaved events and refresh the page.");
define('CALENDAR_EVENTS_STARTING_USER_QUERY_MSG', "Starting user query...");

?>

The definitions should begin with the capitalized version of your plugin name to make them unique from other definitions that may be used in the Breeze Website Builder™. In this example, CALENDAR_EVENTS_ was chosen. Some typical definitions you will probably want to use are:

MYPLUGINNAME_HEADING      Define for heading at the top of your plugin. (CALENDAR_EVENTS_HEADING in above example.)
MYPLUGINNAME_NAMEOFMYBREEZEBUTTON_BTN      Define for the button that shows up inside the Breeze Website Builder™. ('CALENDAR_EVENTS_REVISE_SCHEDULE_BTN' in above example.)

The left parameter in each define remains constant in all of your language definition files. This is what you insert in your code in your console wherever you need text on the screen or wherever a popup message may occur. The right parameter is the text that will be substituted on the screen or popup message and changes from language definition file to language definition file Inside of your module, instead of literal text, you would place the defined constant. An example from the calendar and events plugin is as follows:

<div id="btn_add_event" class='button_console_add' onClick="AddEvent();"><span class='button_console_text_w_icon'><?php echo CALENDAR_EVENTS_ADD_EVENT_BTN; ?></span></div>

 

To prevent the Breeze Website Builder™ from locking up under certain conditions, the following lines of code should be included in either a JavaScript section in your module, or an included JS file:

///////////////////////////////////////////////////////////////////////////////////////////////////////////
function ResizeWorkspace(mainWidth, mainHeight, menuWidth, headerHeight) {

}

function DisplayNotSavedMessage(btn) {
     // Needed to complete call when deleting unsaved page.
     window.parent.SetWorkSavedNotSaved(true);
     window.parent.next_btn = btn;
     window.parent.DoNextClick();
}

The ResizeWorkspace function is used by some of the Breeze Website Builder™ modules to resize elements in itself whenever the browser window is resized. The parent frame expects this function to be available, thus even if nothing needs to be resized, the empty function needs to be present to avoid a JavaScript error. If your module has elements that do not gracefully resize when the parent frame is resized, you can add code here to handle the resize.

The DisplayNotSavedMessage function is used by some modules to prevent steering away from that module if there are edits which have not been saved. The parent frame expects this function to be available, thus even if nothing it is not necessary to display a yes/no popup for saving your work, the empty function needs to be present to avoid a JavaScript error. If on the other hand you want your module to warn the user about loosing unsaved edits, add the following DisplayNotSavedMessage function to your module instead:

function DisplayNotSavedMessage(btn)
{
     popup_msg.top_offset = 0;
     popup_msg.left_offset = 300;
     popup_msg.popup_msg_type = 3;
     popup_msg.popup_btn_cnt = 2;
     popup_msg.popup_msg_cell = EDITOR_PAGE_NOT_SAVED_MSG;
     popup_msg.popup_button_2_span = YES_WORD;
     popup_msg.popup_button_1_span = NO_WORD;
     popup_msg.popup_timeout = -1;
     popup_msg.ShowPopupMsg();
     document.getElementById("popup_button_2_span").onclick = function () { SaveBeforeMain(); };
     document.getElementById("popup_button_1_span").onclick = function () { DoMainMenuAction(); };
}

Then add the following lines of code to your module somewhere and call this code whenever the user makes any changes:

saved = false;
window.parent.SetWorkSavedNotSaved(saved);

 

You will probably want to have the title of your plugin displayed on the browser tab, but because your console will be running inside of an iframe, that tab will display only the name of the parent. You can feed your console title to the parent with the following code:

window.parent.document.title = document.title;

 

If you want to provide help documentation for your plugin, you can add HTML code similar to the example shown below to create a help button:

<div class="button_heading_sub_level_1"><div class="button_heading_text_sub_level_1"><?php echo MYPLUGIN_HEADING; ?></div><div class="button_heading_help" onclick="OpenHelpWindow();">&nbsp;</div></div>

Then add JavaScript code similar to the following in your module:

//////////////////////////////////////////////////////////////////////////////////////
function OpenHelpWindow()
{
     window.open("http://breezewebsitebuilder.com/docs/cms/help.html#edit_schedule", "Help",      "scrollbars=1,resizable=1,status=0,toolbar=0,menubar=0,location=0,height=700,width=800");
}

 

Using a Sub Folder to Organize Your Module Files

The use of a sub folder is not only possible but is the preferred method for organizing your plugin files. For example, you probably want to put your plugin in {webroot}/manage/plugins/my_plugin/ where my_plugin is the name of your plugin or whatever you want to name your folder. You could then have a JavaScript and CSS folder under your main folder, i.e. {webroot}/manage/plugins/my_plugin/js/ and {webroot}/manage/plugins/my_plugin/css/. There is one caveat to this: A version of the included check_session.php file will need to be included in your main folder {webroot}/manage/plugins/my_plugin/. This file will be slightly modified compared to the one in the plugins folder. Here is the code you will need to place in your check_session.php file:

error_reporting (E_ALL ^ E_NOTICE);

include ("../../../connect/config.php");

$sess_save_path = session_save_path();
if (!isset($sess_save_path) || ($sess_save_path == ""))
   session_save_path(SESSION_SAVE_PATH);

session_start();
$userid = $_SESSION['userid'];
$curr_session = md5(session_id());

include ("../../../connect/db_connect.php");

$query = "SELECT `Session`, `IP`, `AccessLevel` FROM `" . BWB_TABLE_PREFIX . "users` WHERE `UserID`=:userid";
$stmt = $bwb_dbh->prepare($query);
$stmt->execute(array(':userid' => $userid));
$row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT);

$session = $row['Session'];
$ip = $row['IP'];
$access_level = $row['AccessLevel'];
$curr_ip = $_SERVER['REMOTE_ADDR'];

if (($curr_session != $session) || ($curr_ip != $ip))
   header("Location: /index.php");

 

if (defined("BWB_LANG"))
   include ("../../lang/" . BWB_LANG . ".php");
else
   include ("../../lang/en.php");

$query = "SELECT `option_value` FROM `" . BWB_TABLE_PREFIX . "options_selected` WHERE `option_name`='Theme'";
$result = $bwb_dbh->query($query);
if ($result->rowCount() > 0) {
   $row = $result->fetch(PDO::FETCH_ASSOC);
   $theme = $row['option_value'];
}
else
   $theme = "classic";

 

 

Everything else that you would put is your module is driven solely by the needs of your plugin. Happy coding!