Elgg is an open source social networking engine. In simple terms, it allows you to run your own social networking site. Facebook is a social networking site. It offers a flexible core which can be extended with plug-ins. Numerous free plug-ins are available online and their quality ranges from superb to barely functional.
Features
Key features of ELGG are:
Social networks have changed the dynamics of interaction which has led to all kinds of revolutions and most visible impact is the wave of oppressive governments in the Middle East falling and reforming as people unite for democratic change. Social networks are powered by social networking software. Social networking is a very interesting topic is so many ways but here we are only concerned with a fast emerging and power social networking software, Elgg.
Social networks can be global such as myspace of facebook where anyone can join and mingle as they see fit. Social networks can also be closed networks specific to an organization or a group with specific interests. For example, a social network of members of some religious organization, a social network of a group of scientists working in nanotechnology or a social network for all Athabasca University staff, students, and faculty. New social networks are being created everyday.
Businesses and individuals are beginning to realize the benefits of social networks. They allows concerned parties to interact more closely. For example, are you interested in registration problems at University of Phoenix? If they have a problem, it doesn't concern me and I have no obligation or opinion on this matter. However, this is a very important issue for University of Phoenix students and faculty. They can easily communicate on a social network specific to University of Phoenix privately within the group. Their comments won't show up on our google searches. Students can voice complaints and concerned departments can hear them and act upon them immediately.
Blog is short for weblog. It a allows users to post content (text, links, images, video, etc.) and others can post comments on this. Most blog posts get few or no comments but some receive numerous comments. Blogs are generally informational or news contents e.g. Blackberry curve has low battery life, Problem migrating from Word 2003 to Word 2007, etc.
Forums are used to discussions. A forum is composed of thread. Users can post their opinions in relevant threads.
Communities are spaces created by users to be accessed by a small group of like-minded peers.
Profiles A profile contains information about the user. It can contain any information the user is asked and chooses to provide e.g. favorite movie, education background, research interest, etc.
Friends In a social network, a friend is someone you choose to interact and share information with.
Tags Tags are words which describe properties of a content. Suppose I post an article on the benefits of grapefruit in reducing cholesterol intake by intestines. This is an article about health, nutrition, heart disease, cholesterol, citrus fruits, etc. This article is not specifically about heart disease but certainly touches it. It is not about citrus fruits but it is about grapefruit which is a citrus fruit. Tags are alternatives to hierarchical categorization. They allows users to quickly and easily find related information. If you click on citrus fruits, all articles containing citrus fruits tag would appear.
Feeds Posts in a social network component such as blog can be aggregated into feeds. These feeds can be made available to other content providers. For example, take a look at http://www.swisspak.com. It shows newsfeeds on Pakistan and Switzerland inside its page. The data has been collected from 4500 different news sites by moreover.com and packaged as rss feeds. Swisspak reads these feeds and displays them on their site. The same can be done with a set of postings on a social network.
Requirements
For Elgg, you need:
Download Elgg
Setting permissions to Elgg installation
create .htaccess file
$ cd elgg-1.x $ cp htaccess_dist .htaccess
Make the .htaccess file writable by Apache or simply do chmod 777 .htacess and remove write permissions after the installation is complete.
Open .htaccess file for editing. Make sure RewriteEngine is set to on. If elgg directory is located at ~/username, then set RewriteBase as follows:
RewriteEngine on RewriteBase /~username/
If the elgg directory is located in the webroot, such as, /var/www/elgg177 in Ubuntu, set it as follows:
RewriteEngine on #RewriteBase /
Yes. You comment out RewriteBase since you are already in the webroot.
Next, copy settings file
$ cp engine/settings.example.php engine/settings.php
Make this file apache writable. Then edit the file settings.php to set $CONFIG->url. If elgg is located at ~/username/elgg then set it like the first option below. If it is located in a folder called elgg under the webroot, set it like the second option below:
$CONFIG->url = "http://someserver.com/~username/"; $CONFIG->url = "http://localhost";
Create database for Elgg
Create a database:
$ mysql -u root -p mysql> create database elgg; mysql> create user elgg_user identified by 'pass'; mysql> grant all on elgg.* to 'elgg_user'@'localhost';
Replace the word pass with your password. We created a database, a user, and and granted full access to the elgg database to this user.
Create data folder
Create a data directory outside the elgg installation and make it Apache writable.
Install from browser
Navigate to the elgg directory with your browser. If your webroot is /var/www and elgg is located at /var/www/elgg, then type http://localhost/elgg. Fill out the information in the html forms and you are good to go. If you see any error messages, see the troubleshooting sections.
If you get the error message, "Elgg couldn't connect to the database using the given credentials", it is most likely because you didn't input the database connection information in the correct location, entered erroneous database connection information or the database user account doesn't have sufficient permissions to create tables in the database.
First of all make sure that you have a file /your_elgg_installation_directory/engine/settings.php If you don't run, the following command:
Edit settings.php to add your database connectivity information. You need to edit the following 4 lines in the file:
$CONFIG->dbuser = '{{CONFIG_DBUSER}}'
$CONFIG->dbpass = '{{CONFIG_DBPASS}}'
$CONFIG->dbname = '{{CONFIG_DBNAME}}'
$CONFIG->dbhost = '{{CONFIG_DBHOST}}'
You need to change them to something like the following:
$CONFIG->dbuser = 'elgguser' $CONFIG->dbpass = 'secret' $CONFIG->dbname = 'elgg' $CONFIG->dbhost = 'localhost'
Save the modifications and refresh the page which showed the error message in your browser.
While installing elgg, users often get the extremely frustrating error message "The requested URL engine/handlers/action_handler.php was not found on this server". This problem could stem from various different sources so you need to check all of them and fix the one or more issues which need to fixed.
First of all check whether your Apache mod_rewrite is function in the elgg installation directory. See testing mod_rewrite article to see how to test whether Apache mod_rewrite is functioning properly.
Second, make sure that the RewriteBase in you .htaccess file is pointing to the correct address. If your elgg is installed on
/home/me/elgg
where it can be accessed with
http://mysite.com/~me/elgg
then your RewriteBase should be as follows:
RewriteBase /~me/
Third, go to /home/me/elgg/engine/settings.php and set the variable $CONFIG->url as follows:
$CONFIG->url = "http://mysite.com/~me/"
Assuming that $CONFIG->dbprefix is set to 'elgg_', all tables in the database would begin with elgg_. Log into your database and make sure the your elgg_sites_entity table looks as follows:
mysql> select * from elgg_sites_entity; +------+---------------+-------------+----------------------------------------------+ | guid | name | description | url | +------+---------------+-------------+----------------------------------------------+ | 1 | New Elgg site | | http://mysite.com/~me/ | +------+---------------+-------------+----------------------------------------------+
Note that the only import field here is the url.
If you still face problem, try tweaking these variables. These are the four places which are most likely to generate this kind of error.
Elgg installed inside the web root
If your system is installed inside the webroot, e.g. /var/www/elgg then use the following settings:
#RewriteBase / $CONFIG->url = "http://localhost/"; mysql> select * from elgg_sites_entity; +------+---------------+-------------+----------------------------------------------+ | guid | name | description | url | +------+---------------+-------------+----------------------------------------------+ | 1 | New Elgg site | | http://localhost/elgg/ | +------+---------------+-------------+----------------------------------------------+
When you log in as an administrator, you get access to administration tools. At the top of the page, click on "Administration" to go into Administration screen. As you install and enable more plugins, your Administration menu would have more options. Only the standard installation is covered on this page. On the left menu, you would see the following links:
Statistics
Provides very basic statistics about site usage.
Site Administration
You are better off not changing anything here. These are the parameters you set when you installed elgg. Edit this page only if you know what you are doing.
User Administration
This section allows you to create, remove and find users.
Tool Administration
Elgg can be extended with plugins. Plugins provide additional functionality. For example, a plugin can provide calendar functionality. To install a plugin, you need to download and unzip it to the mod directory. Then refresh this page to see it in the list. Click on "Enable" to enable it. Now you can use calendar. To disable it, click on the "Disable" button next to the plugin.
System Diagnostics
Here you can generate a report of Elgg diagnostics
Log browser
Here you can see logs for all activity in Elgg.
Default profile widgets
This allows you to customize your view. Simply drag-and-drop items from the Widget gallery to Left widget, Middle widgets, or Right widget screens. This is how items would appear on your profile page.
Default dashboard widgets
This allows you to customize your dashboard. Simply drag-and-drop items from the Widget gallery to Left widget, Middle widgets, or Right widget screens. This is how items would appear on your dashboard.
There would be several other options based on your installation but these are more most important ones.
Elgg data mode is designed such that it allows users to create new plugins, even plugins with its own data types without creating new tables in the database. This feature offers many benefits as well as poses problems. The elgg way to is to work with the conceptual data model without modifying the database. An ER diagram of the database would only cause confusion since elgg the entity model has been abstracted in the elgg core.
Elgg works with atomic data units called entities. From programming perspective, an entity is an object of ElggEntity class. All entities extend this class. For most of your development work, you would be working with the following classes which extend ElggEntity:
In addition to the ElggEntity classes, elgg also provides several helper classes such as ElggAnnotation. This class allows users to add additional information to an entity. For example, comments on video.
Entity and helper classes are located in /engine/lib. You should not modify any of these files.
Elgg actions provide developers an easy and standardized way to add interactivity to their plugins. Actions need to be registered before they can be used. Actions are defined inside individual modules inside the actions directory.
Elgg has an advanced event handling system. Events are triggered by user or system actions. Plugin developers need to register their event handlers for events for every event they want their plugin to respond to.
A theme is a plugin which changes the look and feel of the Elgg installation. Since most of us are not designer and it is even harder to build a design that would work seamlessly with Elgg, there is support for themes. Programmers develop and plugins which add new functionality to Elgg. Designers create new designs that all of us can install and use.
Downloading and installing themes
A theme is a plugin. The main steps of themes creation are:
First, create a directory called snazzy under the mod directory.
$ cd mod $ mkdir snazzy
Since the name of the directory is the plugin name, this theme is called snazzy.
Create start.php
Create a file called start.php inside the directory snazzy.
$ cd snazzy $ vi start.php
and copy paste the following code:
1 <?php
2 // initialize the theme
3 function snazzy_init() {
4 // nothing to do
5 }
6
7 // initialize log browser
8 register_elgg_event_handler('init','system','snazzy_init');
9 ?>
Line 8 simple tell Elgg to call the function snazzy_init() when the plugin is initialized. See Elgg Events and Plugin Hooks for more details. Every plugin requires start.php file since it contains code which is loaded into the Elgg engine. See start.php and manifest.xml files for details.
Create manifest.xml
Create a file manifest.xml and copy paste the following code into it.
<?xml version="1.0" encoding="UTF-8"?>
<plugin_manifest>
<field key="author" value="Nazim" />
<field key="version" value="1.0" />
<field key="description" value="Snazzy theme" />
<field key="website" value="http://molecularsciences.org" />
<field key="copyright" value="molecularsciences.org" />
<field key="licence" value="GNU" />
<field key="elgg_version" value="2011030101" />
</plugin_manifest>
The manifest.xml file describes the plugin and is required for every plugin. See start.php and manifest.xml files for details.
Structure of a theme plugin
In a plugin, every file needs to be placed at a specific location.
your_plugin/graphics/place_image_files_here
your_plugin/views/default/php_files_for_views_go_here
Creating a theme by extending view(s)
Creating a theme involves extending and/or overriding views. A view is a visual component e.g. the top bar, spotlight, etc. When you extend a view, you are adding a new view function to the view. It could be a very complex graphical feature or even something as simple as adding favicon HTML to a theme that doesn't already have this code. To extend a view, we call the extend_view function from our init function in start.php. For example,
1 <?php
2 // initialize the theme
3 function snazzy_init() {
4 // add favicon
5 extend_view('metatags','metatags');
6 }
7
8 // initialize log browser
9 register_elgg_event_handler('init','system','snazzy_init');
10 ?>
Line five calls metatags.php. The first parameter is the name of the view, the second is its location. The second parameter is calling the file snazzy/views/default/metatags.php. I am printing the syntax of extend_view since no documentation is available on it at the time of this writing.
extend_view($view, $view_name, $priority = 501, $viewtype = '')
Create a file snazzy/views/default/metatags.php and add the following code to it:
<link rel="shortcut icon" type="image/x-icon" href="http://localhost/elgg177/mod/snazzy/graphics/snazzy.gif">
The code adds a favicon. The favicon should be placed inside snazzy/graphics/. If you don't have a favicon, simply use mine by replacing the URL with http://molecularsciences.org/files/bluebreeze_favicon.gif.
Save all your files. Open Elgg in your browser. Go to Administration > Tool Administration. Scroll down to snazzy and click on the Enable button/link. Navigate to another page or hit refresh. You should see the icon just to the left of the URL in the browser.
Creating a theme by overriding view(s)
Elgg plugins have a view hierarchy and views down the hierarchy can replace any file in the core view. For example:
/mod/snazzy/views/default/page_elements/spotlight.php
will replace:
/views/default/page_elements/spotlight.php
Overriding can only happen if the plugin is enabled. If snazzy theme is not enabled, it does not override the core view.
Elgg views can be divided into groups called page elements. header, sidebars, and footer are examples of a page element. The string
page_elements/header
refers to the file
views/default/page_elements/header.php
If you are developing an Elgg theme, you would almost certainly be frustrated due to view caching. The visual components of elgg, views are cached, including the CSS files. So even though you have edited your CSS file you would not see your changes since elgg is referring to an older version of your CSS. To see which version of the CSS file is being used, view the page source on your browser. You would see something like:
<link rel="stylesheet" href="http://mysite/_css/css.css?lastcache=1301522663&viewtype=default" type="text/css" />
The number 1301522663 is an epoch timestamp. It means that elgg is using the CSS file as it was at that moment.
To view your modifications, you can do one to the following three things:
Elgg is difficult to get started with for newcomers. Here I list some points which have not been classified into full page explanation. Nevertheless they are important and useful to know.
Plugin order matters
Plugin order in the Administer > Tools Administration section is important. If your plugin is overriding a function in blog, then the blog plugin should appear above your plugin in the list.
main index page is only called when you log in or log out
The main index. page i.e elgg_installation_directory/index.php is called only when you log in or log out. After this, the start.php of the plugin is called.
Elgg provides two types of events:
Elgg Events
Elgg events are triggered when Elgg is loaded or a content is created, modified or deleted. Events are triggered in response to an action by a user. Naturally, you would like your plugin to respond to relevant events triggers. To enable a plugin to repond to event triggers, event handlers must be registered. For example, the following code tells the system to call the function snazzy_init() when this plugin is initialized.
register_elgg_event_handler('init','system','snazzy_init');
The first parameter is the event type, which is initialization in this example. The second parameter is the type of object e.g. system, user, etc. The third parameter is the function which is to be called in response to the event trigger. The fourth parameter is priority of execution whose value has to be an integer.
Event type can be init, boot, all, pagesetup, log, update, create, friend, profileupdate, plugin_boot, delete, join, leave, or annotate.
Making your plugin load first
If you need your plugin to be loaded first, you need to pass the parameter "plugins_boot' as follows:
register_elgg_event_handler('plugins_boot', 'system', 'myplugin_init');
Simplepie plugin uses this code in its start.php.
Bypassing Elgg event handler
You can bypass Elgg event handler by calling
myplugin_init()
instead of
register_elgg_event_handler('init', 'system', 'myplugin_init', 1);
This would ensure that myplugin_init() would be called before all other plugins as well as ALL start.php files with don't contain _init() functions. Unless it is very very necessary, avoid calling your functions this way.
Elgg Developer Tools plugin uses this code in its start.php
Difference between plugins_boot and bypassing register_elgg_event_handler()
- SimplePie uses plugins_boot
- Elgg Developer Tools bypasses register_elgg_event_handler
- Tips and Eager Widgets don't contain init() functions in their start.php
- profile and Tinyurl contain init() functions
This is the order the plugins would be called:
Elgg Developer Tools Tips Eager Widgets SimplePie Profile Tinyurl
Often plugins require or allow users to define certain parameters. This makes plugins more robust and user-friendly. Elgg allows developers to build very simple to very complex interfaces to collect this data from users. This section covers the how and why of creating user-friendly plugins settings interfaces.
We would be creating a custom spotlight plugin called xspot. Spotlight is the block that appears at the bottom of the page and is very useful for providing links to help files and other useful information.
To create the plugin, we need to first create a directory inside the mod directory
$ cd mod $ mkdir xspot
Then we create a manifest file (manifest.xml) inside this xspot directory:
<?xml version="1.0" encoding="UTF-8"?>
<plugin_manifest>
<field key="author" value="Nazim Rahman" />
<field key="version" value="0.1" />
<field key="description" value="Provides custom spotlight content" />
<field key="website" value="molecularsciences.org" />
<field key="copyright" value="Copyright 2011" />
<field key="licence" value="GNU Public License version 2" />
<field key="elgg_version" value="2011072201" />
</plugin_manifest>
When you click on Admin, you get list of items on the left nav bar e.g. Statistics, Site Administration, Tool Administration, System Diagnostics, etc. Obviously, once you are working with your tabs, you generally would not need or want these links to be visible. To make this disappear, you simply need to change your context.
Open mod/xspot/pages/index.php
change
set_context('admin');
to
set_context('xspot');
Save and reload. The admin menus are in admin context and they would not longer appear when you are in xspot context.
To fully understand this page, you need to read http://www.molecularsciences.org/elgg/elgg_plugin_settings first.
Our plugin directory would have the following structure:
xspot/manifest.xml xspot/start.php xspot/languages/en.php xspot/pages/index.php
start.php
In this file, we would be registering handlers.
<?php
function xspot_init() {
global $CONFIG;
// registers page handler. The page handler can define page specific functions
// such URL and location of file to be called
register_page_handler('xspot','xspot_page_handler');
if (get_context() == 'admin') {
add_submenu_item(elgg_echo('xspot:menu'), $CONFIG->wwwroot . 'pg/xspot/index/');
}
return true;
}
function xspot_page_handler($page) {
global $CONFIG;
// defines file to be called for the specified URL.
switch ($page[0]) {
case 'index':
include $CONFIG->pluginspath . 'xspot/pages/index.php';
break;
}
return true;
}
register_elgg_event_handler('init','system','xspot_init');
?>
The function register_elgg_event_handler() registers xspot_init to be called in the order it is defined in Admin > Tools Administration page. xspot_init() function registers the page handler and add a submenu item. This item would appear on the left column of Admin page in Elgg. elgg_echo('xspot:menu') simple prints the value of the array variable xspot:menu defined in languages/en.php. We only want admins to be able to see this page so the if statement is restricting the context to admin. The get_context() function fetches the current context. A context is a string defined somewhere with set_context() to mean something. See what is context and how does it work for more information.
The xspot_page_handler() function defines that if the URL is pg/xspot/index/, then mod/xspot/pages/index.php should be called.
languages/en.php
This is simply a language file for the plugin. It define strings which the plugin can call to print.
<?php
$english = array(
'xspot:menu' => 'Exhanced Spotlight',
'xspot:settings:page:title' => 'Enhanced Spotlight Settings'
);
add_translation("en",$english);
?>
Note that we just discussed the variable xspot:menu used in start.php.
pages/index.php
<?php
// include the Elgg engine
include_once dirname(dirname(dirname(dirname(__FILE__)))) . "/engine/start.php";
global $CONFIG;
admin_gatekeeper();
set_context('admin');
set_page_owner($_SESSION['guid']);
$title = elgg_echo('xspot:settings:page:title');
// create content for main column
$content = elgg_view_title($title);
$content .= 'text text text.';
// layout the sidebar and main column using the default sidebar
$body = elgg_view_layout('two_column_left_sidebar', '', $content);
// create the complete html page and send to browser
page_draw($title, $body);
?>
admin_gatekeeper() only allows admin users to access this page. set_content() is used to set the context admin which was looked up in start.php. elgg_view_title adds title formating to the string. elgg_view_layout() defines that the layout of the page. Finally, page_draw() prints the page to screen.
Output
To view the page you created,
1. Go to Admin > Tools Administration and enable xspot plugin
2. Click on Enhanced Spotlight link on the left nav bar.
If you don't see this, run upgrade.php in your browser.
To fully understand this page, you should first read
1. http://www.molecularsciences.org/elgg/elgg_plugin_settings
2. http://molecularsciences.org/elgg/elgg_plugin_settings/creating_a_settin...
Our plugin directory would have the following structure:
xspot/manifest.xml xspot/start.php xspot/languages/en.php xspot/pages/index.php xspot/views/default/xspot/admin/xspot.php xspot/views/default/xspot/admin/tab1.php xspot/views/default/xspot/admin/tab2.php
start.php
In this file, we would be registering handlers.
<?php
function xspot_init() {
global $CONFIG;
// registers page handler. The page handler can define page specific functions
// such URL and location of file to be called
register_page_handler('xspot','xspot_page_handler');
if (get_context() == 'admin') {
add_submenu_item(elgg_echo('xspot:menu'), $CONFIG->wwwroot . 'pg/xspot/index/');
}
return true;
}
function xspot_page_handler($page) {
global $CONFIG;
// defines file to be called for the specified URL.
switch ($page[0]) {
case 'index':
include $CONFIG->pluginspath . 'xspot/pages/index.php';
break;
}
return true;
}
register_elgg_event_handler('init','system','xspot_init');
?>
Same code as previous page.
languages/en.php
This is simply a language file for the plugin. It define strings which the plugin can call to print.
<?php
$english = array(
'xspot:menu' => 'Exhanced Spotlight',
'xspot:settings:page:title' => 'Enhanced Spotlight Settings',
'xspot:tabl:title' => 'Tab 1',
'xspot:tab1:text' => 'tab1 text',
'xspot:tab2:title' => 'Tab 2',
'xspot:tab2:text' => 'tab2 text'
);
add_translation("en",$english);
?>
The code in bold has been added to the en.php in the previous page.
pages/index.php
<?php
// include the Elgg engine
include_once dirname(dirname(dirname(dirname(__FILE__)))) . "/engine/start.php";
global $CONFIG;
admin_gatekeeper();
set_context('admin');
set_page_owner($_SESSION['guid']);
$tab = isset($_GET['tab']) ? $_GET['tab'] : 'tab1';
$title = elgg_echo('xspot:settings:page:title');
// create content for main column
$content = elgg_view_title($title);
$content .= elgg_view("xspot/admin/xspot", array('tab' => $tab));
// layout the sidebar and main column using the default sidebar
$body = elgg_view_layout('two_column_left_sidebar', '', $content);
// create the complete html page and send to browser
page_draw($title, $body);
?>
The code in bold has been modified from the pages/index.php from the previous page. The first bold lines sets the default tab, "tab1", if a tab is not defined in the URL. elgg_view defines the view to be called and passes an array defining the default tab to the view.
views/default/xspot/admin/xspot.php
<?php
global $CONFIG;
// $tab is the tab passed from start.php
$tab = $vars['tab'];
$tab1select = '';
$tab2select = '';
// if a tab is selected, the css class=selected needs to be added to its tag
switch($tab) {
case 'tab1':
$tab1select = 'class="selected"';
break;
case 'tab2':
$tab2select = 'class="selected"';
break;
}
?>
<div class="contentWrapper">
<div id="elgg_horizontal_tabbed_nav">
<ul>
<li <?php echo $tab1sselect; ?>>
<a href="<?php echo $CONFIG->wwwroot . 'mod/xspot/pages/index.php?tab=tab1'; ?>">
<?php echo elgg_echo('xspot:tabl:title'); ?>
</a></li>
<li <?php echo $tab2select; ?>>
<a href="<?php echo $CONFIG->wwwroot . 'mod/xspot/pages/index.php?tab=tab2'; ?>">
<?php echo elgg_echo('xspot:tab2:title'); ?>
</a></li>
</ul>
</div>
<?php
switch($tab) {
case 'one':
echo elgg_view("xspot/admin/tab1");
break;
case 'two':
echo elgg_view("xspot/admin/tab2");
break;
default:
echo elgg_view("xspot/admin/tab1");
break;
}
?>
</div>
The first part other of the code enclosed in <?php and ?> simply serves to insert the css code class="selected" inside the HTML tag of the active tab. The second part of the code inside the div tags simply write the HTML code for tabs which will printed to screen later. The last part of the code enclosed in <?php and ?> calls the appropriate file to print the content of the relevant tab.
views/default/xspot/admin/tab1.php
<?php
echo elgg_view('output/longtext', array('value' => elgg_echo("xspot:tab1:text")));
?>
views/default/xspot/admin/tab2.php
<?php
echo elgg_view('output/longtext', array('value' => elgg_echo("xspot:tab2:text")));
?>
These two functions hold a simple string of text. Change them to anything you like and the code is good to go.
Output
To view the page you created,
1. Go to Admin > Tools Administration and enable xspot plugin
2. Click on Enhanced Spotlight link on the left nav bar.
3. Click on the tabs
If you don't see this, run upgrade.php in your browser.
To fully understand this page, you should start at http://www.molecularsciences.org/elgg/elgg_plugin_settings and read through the pages.
Here, you will see how to create a simple form, add it to your tabbed interface, and how to process the form.
Our plugin directory would have the following structure:
xspot/manifest.xml xspot/start.php xspot/actions/edit.php xspot/languages/en.php xspot/pages/index.php xspot/views/default/xspot/admin/xspot.php xspot/views/default/xspot/admin/tab1.php xspot/views/default/xspot/admin/tab2.php
start.php
In this file, we would be registering handlers.
<?php
function xspot_init() {
global $CONFIG;
register_page_handler('xspot','xspot_page_handler');
// register actions
register_action("xspot/edit", false, $CONFIG->pluginspath . "xspot/actions/edit.php", true);
if (get_context() == 'admin') {
add_submenu_item(elgg_echo('xspot:menu'), $CONFIG->wwwroot . 'pg/xspot/index/');
}
return true;
}
function xspot_page_handler($page) {
global $CONFIG;
// defines file to be called for the specified URL.
switch ($page[0]) {
case 'index':
include $CONFIG->pluginspath . 'xspot/pages/index.php';
break;
}
return true;
}
register_elgg_event_handler('init','system','xspot_init');
?>
The only line which has changed from the two previous examples is the line in bold. In this line, we register the action file which would handle our form. register_action() has the following syntax
register_action($action, $public = flase, $filename = "", $admin_only = false)
Registers a particular action in memory.
Parameters:
string: $action The name of the action (eg "register", "account/settings/save")
boolean: $public Can this action be accessed by people not logged into the system?
string: $filename Optionally, the filename where this action is located
boolean: $admin_only Whether this action is only available to admin users.
languages/en.php
This is simply a language file for the plugin. It define strings which the plugin can call to print.
<?php
$english = array(
'xspot:menu' => 'Exhanced Spotlight',
'xspot:settings:page:title' => 'Enhanced Spotlight Settings',
'xspot:tabl:title' => 'Settings Summary',
'xspot:tab2:title' => 'Edit Settings',
'xspot:summary:of:plugin:settings' => 'Summary of Plugin Settings'
);
add_translation("en",$english);
?>
The code in bold has been added to the en.php in the previous page.
pages/index.php
<?php
// include the Elgg engine
include_once dirname(dirname(dirname(dirname(__FILE__)))) . "/engine/start.php";
global $CONFIG;
admin_gatekeeper();
set_context('admin');
set_page_owner($_SESSION['guid']);
$tab = isset($_GET['tab']) ? $_GET['tab'] : 'tab1';
$title = elgg_echo('xspot:settings:page:title');
// create content for main column
$content = elgg_view_title($title);
$content .= elgg_view("xspot/admin/xspot", array('tab' => $tab));
// layout the sidebar and main column using the default sidebar
$body = elgg_view_layout('two_column_left_sidebar', '', $content);
// create the complete html page and send to browser
page_draw($title, $body);
?>
The code in bold has been modified from the pages/index.php from the previous page. This file has not changed since the previous example.
views/default/xspot/admin/xspot.php
<?php
global $CONFIG;
// $tab is the tab passed from start.php
$tab = $vars['tab'];
$tab1select = '';
$tab2select = '';
// if a tab is selected, the css class=selected needs to be added to its tag
switch($tab) {
case 'tab1':
$tab1select = 'class="selected"';
break;
case 'tab2':
$tab2select = 'class="selected"';
break;
}
?>
<div class="contentWrapper">
<div id="elgg_horizontal_tabbed_nav">
<ul>
<li <?php echo $tab1sselect; ?>>
<a href="<?php echo $CONFIG->wwwroot . 'mod/xspot/pages/index.php?tab=tab1'; ?>">
<?php echo elgg_echo('xspot:tabl:title'); ?>
</a></li>
<li <?php echo $tab2select; ?>>
<a href="<?php echo $CONFIG->wwwroot . 'mod/xspot/pages/index.php?tab=tab2'; ?>">
<?php echo elgg_echo('xspot:tab2:title'); ?>
</a></li>
</ul>
</div>
<?php
switch($tab) {
case 'one':
echo elgg_view("xspot/admin/tab1");
break;
case 'two':
echo elgg_view("xspot/admin/tab2");
break;
default:
echo elgg_view("xspot/admin/tab1");
break;
}
?>
</div>
This file has not changed since the previous example
views/default/xspot/admin/tab1.php
<?php
$body = elgg_echo("xspot:summary:of:plugin:settings") . '
'
. 'Links to blog help page
'
. get_plugin_setting('xspot_blog_link','xspot');
echo elgg_view('output/longtext', array('value' => $body));
?>
This tab fetches the value of plugin setting variable xspot_blog_link and displays it on the screen with elgg_view("output/longtext",...)
views/default/xspot/admin/tab2.php
<?php
$xspot_blog_link = get_plugin_setting('xspot_blog_link','xspot');
$action = $vars['url'] . 'action/xspot/edit';
$form_body = 'Blog: ';
$form_body .= elgg_view("input/text",array('internalname' => 'xspot_blog_link', 'value' => $xspot_blog_link));
$form_body .= elgg_view('input/submit', array('value' => elgg_echo("save")));
echo elgg_view('input/form', array('action' => $action, 'body' => $form_body));
?>
$action defines the action attribute of the HTML form tag. elgg_view("input/text", ..) creates an HTML form text field. input/submit defines a submit button. input/form create the form.
actions/edit.php
<?php
// for admin only
admin_gatekeeper();
// action protection
action_gatekeeper();
// set context
set_context('admin');
// set title
$title = 'action title';
$body .= get_input('xspot_blog_link');
set_plugin_setting('xspot_blog_link', get_input('xspot_blog_link'), 'xspot');
$content = elgg_view_layout('two_column_left_sidebar', '', $body);
forward("pg/xspot/index/");
?>
We extract the value of xspot_blog_link parameter set in the form with get_input() function. set_plugin_setting() function creates/sets a value for xspot_blog_link for the xspot plugin. Finally, we redirect to the "tab1" we have defined.
Output
To view the page you created,
1. Go to Admin > Tools Administration and enable xspot plugin
2. Click on Enhanced Spotlight link on the left nav bar.
3. Click on the Edit Settings tab
4. Type in a value and click on save.
5. You would be redirected to "Settings Summary" tab showing your value
6. Click on Edit Settings tab and you will see the value pre-filled in the form textfield
If you don't see this, run upgrade.php in your browser.
Plugins are responsible for the rich features and flexibility of Elgg. The order of plugins matters and wrongly ordered plugins could lead to blank screens and other mis-functionalities. Following are a few things every Elgg developer and Elgg admin should know about when and how plugins are called.
When a user clicks on a page, Elgg calls the start.php file of every plugin in the order the plugins are listed in the Tools Administration menu. plugin_init() functions are registered with the register event handler function.
register_elgg_event_handler('init','system','myplugin_init',123);
If you need the start.php of your plugin to execute before any other start.php, order you plugin at the top and for precaution, call your init function directly instead of registering it.
myplugin_init();
instead of
register_elgg_event_handler('init','system','myplugin',123);
This is bad programming practice but it is necessary when writing a plugin to debug or develop plugins. Elgg Developer Tools (elgg_dev_tools) uses this method.
If you need you init function to be the very first init function to call, the Elgg way is to use the following code
register_elgg_event_handler('plugins_boot','system','myplugin);
The fourth, optional integer argument can be used to define the order the plugins are called. If you define a number, the init function would be called in the order of incrementing numbers. If you number your plugins between 1 and 499 inclusive, they would be called before init function which do not specify a number. If you number your plugins between 600 and 9999 inclusive, they would be called after the plugins which did not specify a number. Numbers between 500 and 599 inclusive would place the plugins in between the non-numbered plugins proportional to their numeric weight.
init() functions of plugins are NOT called in the order they are listed in the Tools Adminstration page. You might need to remove numbers from existing plugins register_elgg_event_handler() functions to get some plugins to work together.
Every plugin requires a start.php and a manifest.xml file.
start.php
Every plugin requires start.php file even if the file is empty and it must be located inside the root directory of the plugin. start.php contains code which is loaded into the Elgg engine. It can be used to:
Note that start.php is only called for active plugins.
manfest.xml
manifest.xml describes a plugin. Following is explanation for Elgg 1.7. The format of manifest.xml has changed for Elgg 1.8 and it is not covered here. It uses xml tag attributes to describe author, version, description, website, copyright, license, and elgg version for the plugin. For example:
<?xml version="1.0" encoding="UTF-8"?>
<plugin_manifest>
<field key="author" value="Nazim" />
<field key="version" value="1.0" />
<field key="description" value="Snazzy theme" />
<field key="website" value="http://molecularsciences.org" />
<field key="copyright" value="molecularsciences.org" />
<field key="licence" value="GNU" />
<field key="elgg_version" value="2011030101" />
</plugin_manifest>
elgg_version has the format YYYYMMDDVV, where YYYY is the 4 digit year, MM is the two digit month, DD is the two digit day, and VV are version numbers assigned by the developer.
Converting to Elgg 1.8
At the time of this writing, Elgg 1.8 is still not stable. Since it is plugin based system, you probably wouldn't want to move to Elgg 1.8 before the most important plugins are migrated. This means about a window of 6 - 12 months. Once Elgg 1.8 and most major plugins are ready for production, you would need to migrate your site to Elgg 1.8. To upgrade manifest.xml to 1.8, you would need to do the following. Change
<field key="author" value="Nazim" />
to
<author>"Nazim"<author>
Following is an incomplete list of core functions of Elgg 1.7.x:
get_input
get_input($variable, $default = "", $filter_result = true)
found in /engine/lib/input.php
This function is used to get variables passed in the URL through GET or POST.
get_user_by_username
get_user_by_username($username)
found in /engine/lib/users.php
This function creates an ElggUser object from the username and return this object.
Elgg data model can be difficult for newcomers. It is designed to extendable and be used by infinite number of different plugins. You should refer to the elgg site to learn about the data model. Here, I simple provide a list of queries which help you extract useful information from the database. This is the first step in analytics.
Note: database prefix is assumed to be elgg
Listing types
mysql> SELECT DISTINCT TYPE FROM elggentities; object group user site
No surprise here. Elgg has 4 types. If you want to insert this code in a plugin,
$query = "SELECT DISTINCT TYPE FROM {$CONFIG->dbprefix}entities";
$rt = get_data($query);
foreach ($rt as $row) {
print $row->type;
}
Listing types and subtypes
mysql> SELECT DISTINCT e.type, es.subtype, e.subtype AS subtype_id FROM elggentities e LEFT JOIN elggentity_subtypes es ON e.subtype = es.id; type subtype subtype_id site NULL 0 user NULL 0 object plugin 2 object bookmarks 15 ...
List all types and subtypes used by a user
The user's id in this example is 23.
mysql> SELECT DISTINCT e.type, es.subtype, e.subtype AS subtype_id FROM elggentities e LEFT JOIN elggentity_subtypes es ON e.subtype = es.id WHERE owner_guid =23; type subtype subtype_id group NULL 0 object messages 18 object blog 6 object groupforumtopic 9 ...
Counting entities of a certain type
mysql> SELECT count( * ) AS object_count FROM elggentities e WHERE TYPE = 'object' object_count 57731
Counting entities of a certain type and of a certain user
SELECT count( * ) AS object_count FROM elggentities e WHERE TYPE = 'object' AND owner_guid =23; object_count 3434
Counting entities by type, subtype, and userid
Note that the subtype id is used.
SELECT count( * ) AS object_count FROM elggentities e WHERE TYPE = 'object' AND subtype =6 AND owner_guid =23 object_count 165
Get account creation time for each user
mysql> SELECT DISTINCT (e.guid), min(e.time_created) as time_created, ue.name FROM elggentities e, elggusers_entity ue WHERE e.guid = ue.guid GROUP BY guid guid e.time_created name 2 1263494014 admin 5 1263494488 Brian 8 1263494524 News 9 1263494524 Darlene 10 1263494524 Evan 11 1263494524 Tim ...
All elgg plugins can have access to a global variable $CONFIG. It is an object which encapsulates a wealth of information and data that comes in very handy for plugin development. It contains information on event handlers, hooks, paths, input, translation, configuration information, widgets, views, and handlers:
Following is a simplified print_r() of $CONFIG object.
stdClass Object
(
[events] => Array ()
[hooks] => Array ()
[language_paths] => Array ()
[translations] => Array()
[input] => Array ()
[dbuser] => value
[dbpass] => value
[dbname] => value
[dbhost] => value
[dbprefix] => value
[url] => value
[registered_tag_metadata_names] => Array ()
[widgets] => stdClass Object ()
[path] => value
[viewpath] => value
[pluginspath] => value
[wwwroot] => value
[sitename] => value
[language] => value
[db_installed] => value
[site_id] => value
[site_guid] => value
[site] => ElggSite Object ()
[dataroot] => value
[simplecache_enabled] => value
[viewpath_cache_enabled] => value
[sitedescription] => value
[siteemail] => value
[view] => value
[default_access] => value
[actions] => Array ()
[views] => stdClass Object ()
[view_types] => Array ()
[pluginlistcache] => Array ()
[extender_url_handler] => Array ()
[registers] => Array ()
[registered_entities] => Array ()
[pagehandler] => Array ()
[entity_url_handler] => Array ()
[independents] => Array ()
[servicehandler] => Array ()
[wordblacklist] => Array ()
)
$CONFIG object contains information about events and event handlers.
init events
$CONFIG['events'][init]['system'] array contains a list of event handler functions. These are functions registered to Elgg with the register_elgg_event_handler() function.
register_elgg_event_handler('init',system','notification_init');
Structure in $CONFIG
[events] => Array (
[init] => Array (
[system] => Array (
[0] => notification_init
[1] => users_init
[2] => profile_init
...
)
)
)
boot events
$CONFIG['events']['boot']['system'] array contains a list of event handler functions which are called a elgg boot time. Elgg boot connects to the database, starts the session, and establishes configuration variables and settings. Boot events are inaccessible to plugins because they are triggered before plugins are loaded. These are functions registered to Elgg with the register_elgg_event_handler() function as follows:
register_elgg_event_handler('boot','system','init_db',0);
Structure in $CONFIG
[events] => Array (
[boot] => Array (
[system] => Array (
[0] => init_db
[2] => sites_init
[10] => configuration_init
[20] => session_init
...
)
)
)
'all' events
$CONFIG['events']['all']['all'] array contains a list of event handler functions which are called on every page. For example, system_log_listener is always called to log the action.
register_elgg_event_handler('all','all','system_log_listener', 400);
Structure in $CONFIG
[events] => Array (
[all] => Array (
[all] => Array (
[400] => system_log_listener
[500] => embedvideo_log_listener
)
)
)
pagesetup events
$CONFIG['events']['pagesetup']['pagesetup'] array contains a list of event handlers which are called after the Elgg framework has been loaded but before HTML content is created. These event handlers come in very handy, for example, to add items to a menu or other views-specific functions.
register_elgg_event_handler('pagesetup','system','users_pagesetup',0);
Structure in $CONFIG
[events] => Array (
[pagesetup] => Array (
[system] => Array (
[0] => users_pagesetup
[500] => admin_pagesetup
...
)
)
)
create and update events
$CONFIG['events']['create']['object_type'] array contains a list of event handlers which are called to save something to the elgg database.
$CONFIG['events']['create']['object_type'] array contains a list of event handlers which are called to update something in the elgg database.
object_type has to be an entity such as friend, group, etc. object_type 'all' refer to all entity types.
register_elgg_event_handler('create','all','categories_save');
Structure in $CONFIG
[events] => Array (
[update] => Array (
[all] => Array (
[500] => metadata_update
[501] => categories_save
...
)
[object] => Array (
[500] => file_tree_object_handler
)
)
[create] => Array (
[object] => Array (
[500] => object_notifications
[501] => file_tree_object_handler
)
[friend] => Array (
[500] => relationship_notification_hook
)
[group] => Array (
[500] => groups_create_event_listener
)
[all] => Array (
[500] => categories_save
[501] => marketcategories_save
)
[user] => Array (
[500] => user_create_hook_add_site_relationship
)
)
)
other events
There are many other event handler:
profileupdate: is called what a user updates his/her profile.
register_elgg_event_handler('profileupdate','all','object_notifications');
delete: is called when something is deleted
register_elgg_event_handler('delete', 'group', 'groups_delete_event_listener');
join: is called when a user joins a joinable entity e.g. a group
register_elgg_event_handler('join','group','groups_user_join_event_listener');
leave: is called when a user leaves a joinable entity e.g. a group
register_elgg_event_handler('leave','group','groups_user_leave_event_listener');
annotate: when additional information need to processed
register_elgg_event_handler('annotate','all','group_object_notifications');
[events] => Array (
[profileupdate] => Array (
[all] => Array (
[500] => object_notifications
)
)
[plugins_boot] => Array (
[system] => Array (
[500] => simplepie_init
)
)
[delete] => Array (
[group] => Array (
[500] => groups_delete_event_listener
)
)
[join] => Array (
[group] => Array (
[500] => groups_user_join_event_listener
)
)
[leave] => Array (
[group] => Array (
[500] => groups_user_leave_event_listener
)
)
[annotate] => Array (
[all] => Array (
[500] => group_object_notifications
)
[object] => Array (
[500] => blogwatch_new_comment
)
)
[log] => Array (
[systemlog] => Array (
[999] => system_log_default_logger
)
)
)
If you are trying to install Elgg and getting this error, then this post is NOT for you. If you are developing a plugin on a working Elgg system and getting this error message, then you have come to the right place.
When Elgg is unable to locate the action file, it give the following error message:
The requested action (plugin/file) was not defined in the system
First of all, make sure that your action file is registered in the init function of start.php:
register_action("myplugin/actionfile", false, $CONFIG->pluginspath . "myplugin/actions/actionfile.php", true);
Then make sure that you action file reside in the correct location.
myplugin/actions/actionfile.php
is referenced by
$vars['url'] . 'action/myplugin/actionfile