Note: This is for Drupal 5.x and views 1.6. You can find a tutorial for Views 2 here.
Panels 2 comes with a nifty exporter that will dump all your panels related stuff (pages, views panes, mini panels, etc) into one export file set up to work as a module. It's a really useful feature for moving them from site to site or simply keeping them in code for outside the database backups.
Views 1, being a much older module, doesn't have quite as nice of an exporter. It does allow you to export your views one at a time but using that export in a module takes a bit more work. This article will show you one way of doing it. There are other ways, such as putting all the views in one file, but I find this method easier to maintain.
Step 1: Create a module.
If you already have a site specific module, you can just use that. If not, you'll need to create a module. It's not hard. All you need is a .info and a .module. You can find more information in this tutorial.
Add this function to the module:
<?php
function MODULENAME_views_default_views() {
$views = array();
$path = drupal_get_path('module', 'MODULENAME') . '/views';
$files = drupal_system_listing('.inc$', $path, 'name', 0);
foreach($files as $file) {
include_once $file->filename;
}
return $views;
}
?>
Be sure to replace MODULENAME with the name of your module, in lower case.
Step 2: Create a views directory.
In your module's directory, create a subdirectory called "views". This is where we will be storing the views include files.
Step 3: Export your views.
On the views administration page, every non-default view has an option to export. For each one, export the view and copy the results into its own text file. At the top, add the line <?php so Drupal recognizes it as code. Save each text file as SOMETHING.inc into the views directory from step 2. What you call them doesn't matter, but I recommend using the name of the view to keep them straight.
Step 4: Let views know what you did.
Enable your module if you haven't already done so. On the views admin page is a tab called "tools". Go there and you'll see an option to clear the views cache. Do so. Now go back to the listing page. All the views you exported will be in the "default" views section and labeled overridden. If you don't need to make any more changes to the views, you can safely delete the database version (labeled "existing views") and just run off the ones in the .inc files. The usual disclaimers about backing up your database first apply here. :)
That's it. You now have all your views running off of code. You can take this module to another site, turn it on, and there are your views. (Assuming, of course, that any modules the views rely on are enabled at the new site.)
If you need to change a view, just override it, change it, re-export it, and overwrite the corresponding .inc file.
If you have comments on this technique or you've spotted an error, feel free to leave a message. But please no "how do I make a module" type questions.
Thanks to merlinofchaos for the code to pull in the views as well as for the awesome views module to begin with. :)
Yes, this is definitely a recommended way of moving Views from being stored in the DB to being in code, where it can be versioned and easily moved between sites.
Should apply to CCK content type definitions, too, although programmatically creating / updating CCK types is a bit trickier.
This is a great suggestion and I've seen something similar done, but I like the way you accomplished it because each view can now be placed in it's own file. Mix this with some version control and it's a great answer to people who ask me how to keep a history of view revisions.
Just include the file instead of file_get_contents and eval. It's faster and cleaner. As the included file runs in the scope of the function the include is in, it should just work.
Boris: I wish CCK was this easy. Unfortunately, content copy is pretty flaky. I'm hoping it will be better in D6.
Dave: I don't use revision control myself but it should work for that. I like it because it makes it so easy to move views from live to dev. I also use a similar technique to load the views in Advanced Profile.
chx: You're right, of course. :) I did have to add the opening php tag to the top of all the files otherwise it just prints the code on the screen. I made the change to the original article as well. Thanks for the tip!
Michelle
Try to follow your article with drupal 6 and views 2.
Had to alter the import function to look like (from the import of OG).
<?phpfunction reports_views_default_views() {
$views = array();
$path = drupal_get_path('module', 'reports') . '/views';
$files = drupal_system_listing('.inc$', $path, 'name', 0);
foreach($files as $file) {
include_once $file->filename;
}
return $views;
}
?>
Importing a .inc file from the views folder of my module results in a view in the views pane.
When trying to open or edit the view I get a access denied message.
If I use the same php import code and import it using the "import" UI the view is created ok.
Anyone who have experienced the same problem?
This article is for Drupal 5.x and views 1.6. Views 2 is completely re-written.
Michelle
Thanks for your great tutorial, it help a lot, i am using Panels 2 and i try to make the same thing to have panels in files, seems not to work for me as you say :
Panels 2 comes with a nifty exporter that will dump all your panels related stuff (pages, views panes, mini panels, etc) into one export file set up to work as a module.
Any help or tutorials to make panels 2 as module
Thanks
I don't have a tutorial on it but you can look at the advanced profile kit module for example code.
Michelle
In your code snippet above you have missed a line that populates the $views array you are returning.
<?phpforeach($files as $file) {
include_once $file->filename;
$views[$view->name] = $view; // Needs this line to work
}
return $views;
?>
=) Hope that clarifies for anyone who is still using views 1
@thegreat: That line is already part of the views export, so there's no need to add it again.
Michelle
Oops sorry Michelle, I missed that.
Thanks for the tip.
Tom
No problem. :)
Michelle