So on the topic of distributions (what I am going to call install profiles from now on), some code<br>I recently wrote for <a href="http://drupal.org/node/25745">http://drupal.org/node/25745</a>, that allows you to very easily rip out the variables
<br>configured on the site and store them as defaults.<br><br>function export_defaults() {<br> global $conf;<br><br> foreach ($conf as $name => $value) {<br> $output .= "\$default['$name'] = " . $value . ";\n"; // doesn't work for objects...
<br> }<br> return $output;<br>}<br><br>So that led me to think about what other things we have to import / export for new sites. I also discussed the<br>same with Jaza (who is working on the import/export api.). He has targetted the following things in core
<br>that need to be copied :<br><br><a href="http://basement.greenash.net.au/soc2006/CurrentTodoList">http://basement.greenash.net.au/soc2006/CurrentTodoList</a><br><br>Jaza's system is far more complex than our meagre needs for the distributions right now, plus it won't be ready
<br>in time for 4.8.I also think my proposed approach has a lot of benefits for both our requirements for the distributions<br>(being able to easily build and maintain them), the Drupal API in general and will actually probably make his life easier,
<br>possibly even fast tracking some of his code into core.<br><br>Now my idea (which is very similar to how the views module does it) , is to use a set of functions such as :<br><br>function drupal_export($resultset, $function, $id_field, $objects = TRUE) {
<br> $x = 0;<br> while ($id = db_fetch_array($resultset)) {<br> $object = $function($id[$id_field]);<br> $output .= "\$object[$x] = new stdClass();\n";<br><br> foreach ($object as $field => $value) {
<br> if ($field != $id_field) {<br> if (is_object($value)) {<br> $output .= "\$object[$x]->$field = (object) " . var_export((array) $value, TRUE) . ";\n";<br> }<br> else {
<br> $output .= "\$object[$x]->$field = " . var_export($value, TRUE) . ";\n";<br> }<br> }<br> }<br> $x++;<br> }<br> return $output;<br>}<br><br><br><br>function drupal_import($objects, $function) {
<br> foreach ($objects as $object) {<br> $function($object);<br> }<br>}<br><br>for export :<br>$result = db_query("select nid from node order by nid asc");<br>print drupal_export($result, 'node_load', 'nid')); // or rather save into a file
<br><br>and then on import :<br>include_once 'distributions/default/node.import';<br>drupal_import($objects, 'node_save);<br><br><br>How I see this working is that each module (or thing), will get placed in the distribution/mydistribution/<driver>.import files
<br>which are very simply created, and very simply modified. Since we kind of know what order things need to be imported in<br>we will just recurse through the object and import them.<br><br>These following things are already handled :
<br><br>system table = enabled modules, and themes. Handled by the .distribution file (until we can get dependencies<br> into core that allows them to be configured in the .meta file (ie: requires:theme-bluemarine, blog))
<br>variables (defaults) = handled by the distribution.inc file. see <a href="http://drupal.org/node/25745">http://drupal.org/node/25745</a><br><br>The following things desperately need to be handled, cleanly and easily :
<br><br>profile-fields, users, node types, locale ,vocabularies, terms, blocks, aliases, files (more on this later) nodes , comments and finally menus.<br>(in roughly that order.)<br>I'm unsure about locale in that list. (maybe it should be a setting?)
<br><br>These are optional, but i'd like to see them :<br>aggregator: feeds, items and categories .. could be really awesome for networks of sites.<br>views : it already does this, but could be used as both the basis for the api, and one of the most practical uses of it.
<br>cck : might already do this, but it's important that it does.<br>action/workflow : don't know if it uses it's own table structure or the variable table, but it would be useful for distribution.<br><br>any other contrib module that would benefit from this.
<br><br>What this however requires , is that we have a consistent set of _load and _save functions, which are all equal<br>to node_load. I feel this is something we should have to begin with. Additionally, especially with node_load and block_load, we
<br>will need a way to access the original php code for php filter fields, and not just the output. Also, we need to decide whether<br>initial imports should support revisions (i am not sure they should).<br><br>Perhaps we could even get away with just having a module_import and module_export hook, which could do the
<br>mappings to whatever it's internal functions currently are. This would be a non-invasive way to implement this<br>functionality, and give us a very good idea of what we need to make consisten _save and _load functions for in
<br>future releases. Some of this work is possibly already done as part of jaza's import / export project. Some of the node<br>related code might already be living in publish and subscribe.<br><br>This moves us further away from doing database dumps, and makes distributions a lot easier to create
<br>(you would just run 'scripts/build_distro.php --site <a href="http://mysite.com">mysite.com</a> newdistroname'. And then new sites would<br>use that as their basis. <br><br>One of the more awesome side effects of this all, being we can also distribute each of these as packages on
<a href="http://drupal.org">drupal.org</a>,<br>and teach the install system to install them all. It provides a clean way for modules to distribute views<br>and cck node types etc, perhaps even custom blocks and templates (with the inline template editor i want to write)
<br>There are some issues with this on already running sites, with versioning of all these elements, but i believe<br>the dependencies work will end up helping with this. <br><br>One of the other things I would like to see us do, is to provide variables that have been submitted as part of the
<br>distribution specific form, as variables to the .import files. A perfect example of this is having the first node configured <br>as "welcome to your site $edit[fullname]". Even the creation of the first user (for instance), could be handled via this.
<br><br>Another point I came across, is the files directory. I believe the installer should try and create it, and I also believe the distributions should be able to have default files that are copied to the directory. <br>
<br>An example being that a brochureware distribution might ship with a customised logo/favicon, and possibly an initial node configured and made to be the front page, which has a nice piece of stock photography already present (giving people a presentable front page to work from). It might even ship
<br>with several different templates and allow you to select which one of them you want your front page to look like.<br><br>That's a rather rambling post for what is actually really simple in concept, and if we build the framework within which to do it
<br>and have a developer per import / export object .. we should hopefully still be able to get something like this into 4.8... and<br>then we can watch the distributions bloom =)