From Fedora Project Wiki


About Beacon

Beacon is a WYSIWYG web-based plug-able editor. Beacon is aimed at being a generic XML editor. Any XML format that has an ultimate output format like PDF or HTML is a good candidate for a beacon-editable document. Beacon allows the user to edit the output of that XML document and will automatically generate the input corresponding to the output the user sees.


Beacon has two backends:

  1. PHP
  2. Python

PHP requirements:

  • PHP 5 or higher
  • PHP XSL support
  • PHP Curl support

Python requirements

Under construction

Besides these for the PHP version you will also need to set write permission to the tmp directory in php/storage/tmp/ so the web server can write to it. So make sure you are allowed to do this!


Getting PHP version of Beacon

Beacon is currently available only through its GIT repository. To check out an anonymous copy:

 $git clone git:// beacon

This will create a copy of Beacon in the beacon folder. If you plan on using the default PHP version then you can skip the next section. If you want to use the Python/Django version then continue below.

Checking out the Python version of Beacon

You can check out the Python version by the following sequence of commands after checking out from the repository as mentioned above.

 $ git branch django origin/django

Branch django set up to track remote branch refs/remotes/origin/django.

 $ git checkout django

Switched to branch "django" Now you have a Python copy of Beacon.

Configuring Basic Beacon Setup

Beacon stores all its configuration in a file called beacon.conf. Navigate to your beacon directory and you will see two files. beacon.conf and beacon.conf.sample. beacon.conf.sample is a self documenting example of how a typical conf file would be. Here are the contents:

    // Complete URL of your Beacon installation
    "url": "http://localhost/beacon/beacondev/trunk/editor/",
    // This option chooses the backend to be used
    // Possible options: php, python
    "backend": "php",
    // All PHP related settings
    // These are mostly used by javascript
    "php": {
       // Provide all paths relative to the 'url'
       // The one that handles all of the AJAX requests
       "handler": "index.php",
       // Path to php scripts
       "path": "php/",
       // Path to all javascript
       "scriptpath": "js/",
       // Path to CSS
       "csspath": "css/",
       // Path to all images
       "imagepath": "img/",
       // Path to all plugins
       "pluginpath": "plugins/",
       // Path to store temporary files
       "tmppath": "php/storage/tmp/",
       // Path to i18n
       "i18npath": "i18n/",
       // Path to all HTML
       "htmlpath" : "html/"
    // All Python related settings
    // Please clone the settings name from PHP above
    "python": {
    // List the plugins here that are to be loaded
    "plugins": ["guidexml"],
    // Language to show
    "language": "en_US",
    // Container in which to display Beacon
    "container": "#container",
    // If the document is root or not.
    // This informs Beacon that it is not the "only" item
    // on the page and loads its CSS/Javascript accordingly
    "isRoot": true,
    // Choose a theme. Themes are available on the JQuery Website.
    "theme": "redmond",
    // Method of storage to be used
    // Currently only flatfile is used
    "storage": "flatfile"

As you can see the configuration is stored in the JSON format. This makes it easy for the Javascript to parse the config file. When you actually want to change something do it in beacon.conf file and not in beacon.conf.sample. The latter is just a reference on how to edit the file.

If you are using the default setup and not planning to hack on it then all you need to do is set the url to your setup. So if beacon is supposed to be at then set url to that (assuming editor contains the .conf file). This informs the javascript on where to fetch everything from.

Important: Do not forget the trailing slashes in the settings. They are crucial! Assume this for all settings that involve paths.

Now we'll move to backend specific configs.

PHP Specific settings

There is one more variable you need to set in index.php file in beacon/editor/index.php. Open index.php in your favorite editor and navigate to around line number 18 which says:

  // Set the full path here
  $fullPath = "/some/path/";

Change this to the absolute path of beacon folder on your system.

Now navigate to beacon/editor/php/storage/ and set the permissions of tmp/ folder (if doesn't exist create one) so that the webserver can write to it. This is used to write the documents to server. Beacon(PHP) doesn't support any other method of storage except flatfiles.

Python settings

It just works.

Using Beacon

Running Beacon

Assuming everything went well above just point you browser to the url you have give above and Beacon should be appearing in front of you.

More on this later...

Hacking on Beacon


Beacon is currently in its experimental stages and needs a lot more development. If you'd like to join the bandwagon please grab a cup of your favorite brew and drop by at #beacon on :)

This part of the guide will detail on how to hack on Beacon in 2 different areas. Making a new backend and making a plugin.

Developing a new Backend

Javascript frontend of beacon is quite independent of its backend. It uses the conf file to look for resources and throwing ajax requests to the server. For the purpose of this tutorial I'll guide you based on the PHP example. Beacon is contained in /var/www/beacon/editor/ and url looks like http://localhost/beacon/editor/ are my assumptions.

When the browser accesses the above url index.php loads the config file and serves /var/www/beacon/editor/html/beaconfull.html (all strings surrounded by {} are the ones that need to be localized). The following code in beaconfull.html is what starts the javascript magic:

  <script type="text/javascript">
    // This is important to make the fileupload work!
    window.beacon = {};
    $(document).ready(function() {
        // Start up Beacon by showing the Container
        beacon = new Beacon("#BeaconContainer", "{pathtoconf}");

"#BeaconContainer" is the HTML element in which you would like to load beacon and "{pathtoconf}" is where you would supply a full HTTP path to the conf file so Beacon can load it via Ajax. Your backend should typically provide this while serving this page by reading it from beacon.conf file and replacing "{pathtoconf}". It would be at http://localhost/beacon/editor/beacon.conf in the case of this tutorial.

After the page has loaded and config file is loaded the JS will make calls for fetching remaining scripts. All the paths are calculated by reading the conf variable. As you can see, the php section contains a lot of paths. Beacon 'boots' up in the following sequence:

  1. Fetch the conf file
  2. Fetch the language file from i18npath
  3. Fetch extra javascript from scriptpath
  4. Fetch Plugin data from pluginpath
  5. Fetch the main UI HTML by requesting to the handler (in case of PHP its index.php). Hereon, all requests are made to the handler.

Important: All paths are calculated by adding the url in front of the path value. Hence give it accordingly.

The page mentioned in handler is what handles all Javascript requests. The following section documents all calls made to the handler and associated return values.

Ajax Calls

Following code snippets describe all the Ajax calls made to the handler. This list will continue to grow.

Fetching the UI.

  json = {
    action: "beaconui",
    payload: null
  // Return value should be localized HTML that is to be displayed (contained in beaconui.html).

Creating a new document with the given id.

  json = {
    action: "newdoc",
    payload: {
       id: /* Document ID */,
       plugin: /* Plugin Name */
  // Return value should be the localized HTML contained in document.html. 
  //One has to create a new document in this case.

Important: The HTML in document.html has two values that need to be filled up. All element ids in the HTML are prefixed with {id} which needs to be replaced with the id given in the json. Also the Iframe has {src} in its attribute which needs to point to the URL that will serve the html document on the initial load. This needs to be done to all HTML contained in document.html henceforth.

Fetching a Document UI.

The difference between this and above is that no new document is created. A UI is returned with simply a reference to the document mentioned by id.

  json = {
    action: "documentui",
    payload: {
       id: /* Document ID */,
       plugin: /* Plugin Name */
  // Return value should be the localized HTML contained in document.html. 
  //One should not create a new document.

Fetching the Document from a URL and creating a doc with that source and given id.

  json = {
    action: "documentui",
    payload: {
       id: /* Document ID */,
       plugin: /* Plugin Name */,
       url: /* URL from where the document source is to be fetched. */
  // The server should grab the source XML from the URL provided and serve
  // the document ui from document.html in the same way as done before.

Deleting a doc for given id.

  json = {
    action: "deletdoc",
    payload: {
       id: /* Document ID */,
       plugin: /* Plugin Name */
  // The server should delete the document from storage.

Fetching the XML for given id.

  json = {
    action: "getsrc",
    payload: {
       id: /* Document ID */,
       plugin: /* Plugin Name */,
       html: /* Complete HTML string from Iframe (escaped) */
  // The server should parse the HTML and return XML.

Fetching the displayable HTML for given id.

  json = {
    action: "gethtml",
    payload: {
       id: /* Document ID */,
       plugin: /* Plugin Name */,
       src: /* Complete source XML string from Source view (escaped) */
  // The server should parse the XML and return displayable HTML.

More to come soon...

Writing a plugin

Beacon has a plugin framework to make it a generic XML editor. More to come soon...