howto
Archived Posts from this Category
Archived Posts from this Category
Posted by Greg on 10 Mar 2008 | Tagged as: ORVSD, howto, learning management systems, planetosl, sysadmin
When I first started working with Moodle servers, one of the things that bugged me was the fact that it required a complete install of the code for every site hosted on the system. While that’s fine for most circumstances, it really did not work well in our environment where we’re looking at potentially hosting hundreds of Moodle instances. So, in the fine open source tradition of scratching an itch by finding something someone else has done, modifying it, and then sharing it with the world … I give you shared-code Moodle, OSL-style.
First, though, credit where credit is due. Martin Langhoff posted almost all of what we needed to do here. All I needed to do is expand upon it to fit our needs.
Second, what the modified code actually does:
1) config.php looks in Moodle dirroot/multisite_config for an ini file matching the server name. I.E.: fqdn.domain.org.ini
2) If found, the ini file is parsed and used to populate the Moodle $CFG
On to the code!
1) Create a directory in your Moodle wwwroot named multisite_config and make sure it’s readable by the web server
2) Create a moodledata_shared directory to hold the various sites’ moodledata directories
3) Modify the wwwroot/config.php file to look like:
<?php /// Moodle Configuration File
unset($CFG);
$CFG->dirroot = '/var/www/moodle_shared';
// Determine hostname
$hostname = $_SERVER['HTTP_HOST'];
if (isset($_ENV['HTTP_HOST'])){ // this is to support cronjobs on a per-host basis
$hostname = $_ENV['HTTP_HOST'];
}
// Load multi-site configs
$multisite_config_filename = "$CFG->dirroot/multisite_config/$hostname.ini";
if (file_exists($multisite_config_filename)) {
$sites_array = parse_ini_file($multisite_config_filename);
} else {
// Whoops! No ini found, fall back to a default Moodle host
$URL="http://default-moodle.domain.org";
header ("Location: $URL");
die("<pre>Unable to open site configuration file for '$hostname'. Has the config file been created?\n</pre>");
}
$CFG->dbtype = 'mysql';
$CFG->dbhost = $sites_array[dbhost];
$CFG->dbname = $sites_array[dbname];
$CFG->dbuser = $sites_array[dbuser];
$CFG->dbpass = $sites_array[dbpass];
$CFG->dbpersist = false;
$CFG->prefix = 'mdl_';
$CFG->wwwroot = $sites_array[wwwroot];
$CFG->dataroot = '/var/www/moodledata_shared/'.$hostname;
$CFG->admin = 'admin';
4) Create an ini file for each Moodle instance you want to host and place it in the Moodle dirroot/multisite_config/ directory. An example ini file for a fictitious template.domain.org Moodle instance:
; multisite_config.ini
[template]
dbhost = localhost
dbname = template_db_name
dbuser = template_user
dbpass = dbpassword
wwwroot = http://template.domain.org/moodle
5) Create a moodledata_shared/hostname directory for the moodledata stuff.
I have a canned mysqldump file I use to create new Moodle sites instead of using the GUI (along with an automated system to create the databases and generate the ini files, but that’s a topic for another post another time). Since I wanted to avoid creating a vhost for every Moodle instance and having to bounce Apache every time I add a new one, I set up a wildcard domain to point at the moodle_shared webroot. But this should work equally well with explicitly-defined Apache vhosts.
Todo:
1) Modify the GUI config to have it write the ini files directly.
2) Look into having site-specific modules. As it stands right now, all sites get the same modules. So far we haven’t run into module conflicts or sites wanting customized versions of modules, but I expect it’s only a matter of time.
3) Performance and scaling testing. This seems to work well enough with the approximately 50 low traffic sites I’m running now, but I’m not sure how much of a penalty the reading and parsing of the ini file imposes. It may not scale well on high traffic sites.
3a) Not sure how well this might be adapted to a multi-server or clustered environment.
Posted by Greg on 15 Jul 2006 | Tagged as: drupal, howto, openlaszlo, planetosl
New job, new tools, new fun!
Being relatively new to the OSL, I have been gleefully learning some new tools. Specifically, Drupal and OpenLaszlo. In fact, I’m having so much fun with them I feel the need to share. So, with that in mind …
The problem. Well, OK, it’s not really a problem. Let’s call it a “challenge”. Drupal, for reasons too in-depth to go into right now, does not allow page authors to embed JavaScript directly into the body of a page. OpenLaszlo, on the other hand, uses JavaScript to embed applications in pages.
Hmm. So how does one embed an application developed in OpenLaszlo in a Drupal site?
Well, after a bit of head-scratching, this is what I learned:
Drupal has two handly little tools - drupal_add_js() and drupal_call_js() - to help. drupal_add_js() allows you to add external JavaScript files to the page header, and drupal_call_js() allows you to call the functions in the external scripts.
Normally, to embed an OpenLaszlo application you add the following code to the desired page:
<script src="/lps-3.3/lps/includes/embed.js" type="text/javascript"> </script>
<script type="text/javascript">
lzEmbed({url: 'AppName.lzx?lzt=swf', bgcolor: '#ffffff', width: '900', height: '600'});
</script>However (hah! You should have known it wasn’t going to be quite that easy), there are some small issues that need to be dealt with before it will work properly. First of all, the script assumes it is being run from the Laszlo server directly, rather than the Drupal server. So we need to copy the Laszlo embed.js resource script from the Laszlo server over to the Drupal server and turn that JavaScript into something Drupal-compatible using drupal_add_js():
drupal_add_js('/drupal/path/to/embed.js');And we need to drop the rest of the JavaScript into a file (we’ll call it laszloapp.js) that we can load using drupal_add_js() and save it to the Drupal server filesystem:
function load() {
lzEmbed({url: 'http://laszloserver.org:8080/AppName.lzx?lzt=swf', bgcolor: '#ffffff', width: '900', height: '600'});
}To load the script into the Drupal page, we call it thusly:
drupal_add_js('/drupal/path/to/laszloapp.js');Notice we have put the lzEmbed() function inside a load() function. This is because the drupal_add_js() function inserts the JavaScript (and therefore the Laszlo object) into the page head, above the rest of the page content. So to control where the Laszlo object is embedded in the page, we need to use the drupal_call_js() function to call the load() function from laszloapp.js. At the point in the page where you want to insert the Laszlo object:
<div id="laszlo_object">
<?php
$js = drupal_call_js(load);
return $js;
?>Et voila! The Laszlo application loads within the “laszlo_object” div.
In a nutshell:
embed.js file from the Laszlo server to the Drupal serverlaszloapp.js file containing the following:
function load() {
lzEmbed({url: 'http://laszloserver.org:8080/AppName.lzx?lzt=swf', bgcolor: '#ffffff', width: '900', height: '600'});
}<?php
drupal_add_js('http://newosl.osuosl.org/themes/newosl/embed.js');
drupal_add_js('http://newosl.osuosl.org/themes/newosl/oslmon.js');
?>
<div id="laszlo_object">
<?php
$js = drupal_call_js(load);
return $js;
?></div>