Help - Search - Members - Calendar
Full Version: Using Perl Api To Create A Page In A Folder
Movable Type Community Forum > Additional Resources > Plugin Development and Usage
Rob Staveley
I hope this is the right place to post this question.

Using the Perl API to create blog entries is well documented, but creating pages is not.

What I need to do is to generate to create unique page that correlates to some number. The number can be anything from 1 to 10,000,000 and I've been asked to have no more than 1000 files in a directory. So, my approach is to create the page corresponding to 12,345,678 in someblog/12/345/678.html - i.e. use 12/345 as the foldering.

I've figured out how create the foldering in MT 4.1 and I've figured out how to create the page, but... I haven't figured out how to get the page into the folder.

Can some kind soul point me in the right direction?

Here's my code (runs from the tools directory):
CODE
#!/usr/bin/perl -w

use strict;
use Data::Dumper;
use lib '../extlib', '../lib', '../plugins';
use MT;
use base qw/ MT::Folder MT::Page /;

my $mt = MT->new(Config => 'mt.cfg');

my $blog = MT::Blog->load({name => 'demo'}) or die "Unable to load blog: $!";
my $author = MT::Author->load({email => 'rstaveley@blahdiblah.com'}) or die "Unable to load author: $!";

# This is hard-coded for a test
my $v_id = '12345678';

# Get the parent folder
my $parent_directory = int($v_id/1000_000);
my $sub_directory = int($v_id/1000)%1000;
my $title = $v_id % 1000;
my $folder;

# Auto-vivify the foldering

my $parent_id = 0;
for my $basename($parent_directory, $sub_directory) {

        # See if the folder aleady exists
        $folder = MT::Folder->load({
                blog_id  => $blog->id,
                parent   => $parent_id,
                basename => $basename,
        });

        # If it doesn't we create it
        if (!$folder) {
                $folder = MT::Folder->new;
                $folder->blog_id($blog->id);
                $folder->parent($parent_id);
                $folder->basename($basename);
                $folder->label($basename);
                $folder->save or die _fault(MT->translate("Unable to save folder: [_1]", $folder->errstr));
        }

        $parent_id = $folder->id;
}

my $page = new MT::Page;
$page->blog_id($blog->id);
$page->author_id($author->id);
$page->title($title);
$page->text($v_id);
$page->status(MT::Entry::RELEASE());
#$page->folder($folder);  ## <- I get an uninitialised value error in ../lib/MT/Entry.pm line 107 with this
$page->save;
Rob Staveley
Aha... I've figured it out. biggrin.gif

With hindsight it is easier to work through this, with reference to the database tables. I hadn't appreciated that a MT::Placement was needed untill I worked through some pages created on the site and looked at what happens in the database. My code now works nicely. It also fills in a few fields, which probably ought to be routinely filled, when using the Perl API, like the blog ID and author ID fields. I'm leaving entry_convert_breaks, entry_excerpt, entry_keywords, entry_text_more, entry_to_ping_urls NULL, which are populated when you create a page via the UI, but having them NULL doesn't seem to harm. [Famous last words.] I'm now creating a sensible looking mt_placement record as well as mt_entry (used for pages as well as entries) and mt_category (used for folders as well as categories - difference in the category_class).

Here's the code, for the benefit of anyone else, who finds themselves on this journey of discovery:

CODE
#!/usr/bin/perl -w

use strict;
use Data::Dumper;
use lib '../extlib', '../lib', '../plugins';
use MT;
use base qw/ MT::Folder MT::Page /;

my $mt = MT->new(Config => 'mt.cfg');

my $blog = MT::Blog->load({name => 'demo'}) or die "Unable to load blog: $!";
my $author = MT::Author->load({email => 'rstaveley@blahdiblah.com'}) or die "Unable to load author: $!";

my $v_id = '12345678';

# Get the parent folder
my $parent_directory = int($v_id/1000_000);
my $sub_directory = int($v_id/1000)%1000;
my $title = $v_id % 1000;
my $folder;

# Auto-vivify the foldering

my $parent_id = 0;
for my $basename($parent_directory, $sub_directory) {

        # See if the folder aleady exists
        $folder = MT::Folder->load({
                blog_id  => $blog->id,
                parent   => $parent_id,
                basename => $basename,
        });

        # If it doesn't we create it
        if (!$folder) {
                $folder = MT::Folder->new;
                $folder->blog_id($blog->id);
                $folder->author_id($author->id);
                $folder->parent($parent_id);
                $folder->basename($basename);
                $folder->label($basename);
                $folder->save or die _fault(MT->translate("Unable to save folder: [_1]", $folder->errstr));
        }

        $parent_id = $folder->id;
}

my $page = new MT::Page;
$page->blog_id($blog->id);
$page->author_id($author->id);
$page->created_by($author->id);
$page->title($title);
$page->text($v_id);
$page->status(MT::Entry::RELEASE());
$page->allow_comments(1);
$page->allow_pings(0);
$page->save;

my $place = new MT::Placement;
$place->entry_id($page->id);
$place->category_id($folder->id);
$place->is_primary(1);
$place->blog_id($blog->id);
$place->save;

$mt->rebuild_entry(Entry => $page, BuildDependencies => 1);

print "Program terminated normally\n";
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2009 Invision Power Services, Inc.