There have been a few documented ways to migrate MT entries to textpattern. One of the issues has been preserving existing links to entries. Here is one way to do it.
Archives: December 1999
SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed FROM nucleus_item as i, nucleus_member as m, nucleus_category as c WHERE i.iblog=1 and i.iauthor=m.mnumber and i.icat=c.catid and i.idraft=0 and i.itime<="2008-12-05 04:05:14" AND i.iblog = 1 AND i.inumber IN (39,40,41,42) ORDER BY i.itime DESC LIMIT 1,5
stdClass Object
(
[itemid] => 41
[title] => TXP Hack: preserving MT archive links...
[body] => There have been a few documented ways to migrate MT entries to textpattern. One of the issues has been preserving existing links to entries. Here is one way to do it.
[author] => erin
[authorname] => Erin Schnabel
[itime] => 2005-03-06 11:45:00
[more] => [Based on Textpattern 1.0rc1]
- Find a way to preserve the MT entry id in the custom_10 field in the textpattern table.
- You can do this manually using an SQL query, or you could hack the migration script to stash the entry value while it's copying entries over.
- Create a file
archives (archives.php if you have content negotiation enabled), just like you would for using clean-urls. This file will map the MT-style archives URL to a new textpattern URL.
Contents of archives:
<?php
include "./textpattern/config.php";
include $txpcfg['txpath']."/publish.php";
global $pfr, $url_mode;
if ( preg_match("|archives/(d+).php|", $_SERVER['REQUEST_URI'], $matches) )
{
$id = intval($matches[1]);
$row = safe_row("*", "textpattern", "custom_10 = $id");
$url = formatPermLink($row['ID'], $row['Section']);
if ( $url_mode==1 )
$url .= ( $row['url_title'] ? $row['url_title'] : stripSpace($row['Title']) );
header('Location: http://'.$_SERVER['HTTP_HOST'].$url, TRUE, 301);
exit;
}
header("HTTP/1.0 404 Not Found");
exit;
?>
[authorid] => 1
[authormail] => erinschnabel@gmail.com
[authorurl] => http://ebullientworks.com/
[category] => General
[catid] => 1
[closed] => 1
)
stdClass Object
(
[itemid] => 40
[title] => TXP Hack: Using TXP Excerpts like MT
[body] => One of the things I used heavily in MT was the body/extended body trick. I wanted to continue that with Textpattern, but it involved some hacks to how TXP handles excerpts.
[author] => erin
[authorname] => Erin Schnabel
[itime] => 2005-03-06 10:16:00
[more] => [Based on Textpattern 1.0rc1]
- Add an additional column, Excerpt_html, to the textpattern table so that Excerpt has the same behavior as the body (original textile is saved, with the html result in the _html column).
- Change to
txpsql.php:
--- txpsql.php 23 Jan 2005 02:40:40 -0000 1.1
+++ txpsql.php 6 Feb 2005 17:44:33 -0000 1.2
@@ -19,6 +19,7 @@
`Body` text NOT NULL,
`Body_html` text NOT NULL,
`Excerpt` mediumtext NOT NULL,
+ `Excerpt_html` mediumtext NOT NULL,
`Image` varchar(255) NOT NULL default '',
`Category1` varchar(128) NOT NULL default '',
`Category2` varchar(128) NOT NULL default '',
- Change to
_update.php:
--- _update.php 23 Jan 2005 02:40:40 -0000 1.1
+++ _update.php 6 Feb 2005 17:43:05 -0000 1.2
@@ -50,6 +50,10 @@
if (!in_array('Excerpt',$txp)) {
safe_alter("textpattern", "add `Excerpt` mediumtext not null after `Body_html`");
}
+
+ if (!in_array('Excerpt',$txp)) {
+ safe_alter("textpattern", "add `Excerpt_html` mediumtext not null after `Excerpt`");
+ }
- In order to have _update.php run (to add the column to an existing textpattern table), temporarily change
$thisversion in textpattern/index.php to '0'. _update.php will run the next time you do anything with textpattern/index.php. Once it runs, return $thisversion to its original value.
- Make
textpattern/include/txp_article.php store the raw textile text and the html formatted text separately. Also, since I am used to writing the excerpt and then the body, I moved the excerpt box above the body box on the entry form.
This diff is a little more involved, I've attached it here.
- Finally, we need to make
textpattern/publish.php display Excerpt_html instead of Excerpt. The diff is here.
For the full article display, use <txp:excerpt /> and <txp:body />. To show just the excerpt, use <txp:excerpt />.
I selectively show a "[more]" link based on whether or not there is additional body text. If an entry is really short, sometimes there is only an excerpt. I created my own plugin to do this, and it looks like this:
function elh_article_more($atts)
{
global $thisarticle;
if (is_array($atts)) extract($atts);
$body = $thisarticle['body'];
if ( !preg_match("/w/", $body) )
return '';
$link = '<a href="'.$thisarticle['permlink'].'">more</a>';
return '<div class="more">['.$link.']</div>';
}
Have Fun!
[authorid] => 1
[authormail] => erinschnabel@gmail.com
[authorurl] => http://ebullientworks.com/
[category] => General
[catid] => 1
[closed] => 1
)
One of the things I used heavily in MT was the body/extended body trick. I wanted to continue that with Textpattern, but it involved some hacks to how TXP handles excerpts.
stdClass Object
(
[itemid] => 39
[title] => TXP Hack: MT-Macro like function in textpattern
[body] => This is a simple hack to add one of my favorite MT-plugins, Brad Choate's MTMacros [bradchoate.com], to textpattern.
Granted, I didn't pull the entire kaboodle. This doesn't do fun container logic and acronym matching, etc. But it does do simple string replacement, which is what I used it for (e.g. smilies and pretty attributions).
[author] => erin
[authorname] => Erin Schnabel
[itime] => 2005-02-23 23:35:00
[more] => [Based on Textpattern 1.0rc1]
Using macros with original lib/classTextile.php
I add one method to lib/classTextile.php (either the original, or the modified version provided by Colin Brown1 that provides extended blocks, escaped blocks, and better handling of <pre> tags).
/**
* Performs string replacement based on a provided
* array containing 'pattern' => 'replacement' pairs.
*
* @parameter string $text Text to process
* @parameter string $list Name of global variable containing
* array of pattern/replacement pairs.
*/
function customMacros($text, $list)
{
$macros = $GLOBALS[$list];
if ( isset($macros) && is_array($macros) )
{
$patterns = array_keys($macros);
$replace = array_values($macros);
$text = str_replace($patterns, $replace, $text);
}
return $text;
}
I added two calls to this method within the TextileThis method of lib/classTextile.php.
The first is just after we mark that text which should not be textiled:
$text = $this->customMacros($text, 'pre_macros');
This expands macros before other textile substitutions.
The second is just before the <notextile> tags are replaced (it could also be just after):
$text = $this->customMacros($text, 'post_macros');
The second parameter passed to the textileMacros method is the name of a global environment variable holding an array of macro definitions (e.g. pre_macros or post_macros). You can change these names to suit, but the array declaration (given what is above) should look something like this:
global $pre_macros, $post_macros;
$pre_macros = array(
'=)' => '<img src="/cheesy.gif" />',
'</z>' => ' </q>',
);
$post_macros = array(
'<z>' => '<span class="attribute">[',
' </q>' => ']</span>',
);
I use a custom tag to generate formatted attribution text, e.g. <z>"link.com":http://link.com</z> generates <span class="attribute>[<a href="link.com">link.com<a>]</span>.
The combination of pre/post tags adjusts spacing to allow textpattern to properly work around my custom tag.
Using macros with original TextilePHP
This also works with TextilePHP [jimandlissa.com].
I made the following updates to their class:
- Added
TextileThis, as others have done2, to make it TXP compatible. - Added
customMacrosmethod, as above, with two calls for pre-textile processing, and post-textile processing.$str = $this->customMacros($str, 'pre_macros');
'pre_macros' are used just before the check for disabled html$out = $this->customMacros($str, 'post_macros');
'post_macros' are used just before the cleanup to
restore preserved blocks.
/**
* Wrapper function for compatibility with TXP
*/
function TextileThis($text, $lite='', $encode='', $noimage='', $strict='')
{
if (get_magic_quotes_gpc())
$text = stripslashes($text);
if ( $encode )
return $this->encode_html_basic($text);
if ( $lite )
$this->disable_html(true);
return $this->process($text);
} // function TextileThis
Footnotes
1 Unofficial Textile 2.0 beta [solarorange.com], from this thread [forum.textpattern.com].
2 TextilePHP for TXP [greenrift.textdrive.com], as mentioned in this thread [forum.textpattern.com].
[authorid] => 1 [authormail] => erinschnabel@gmail.com [authorurl] => http://ebullientworks.com/ [category] => General [catid] => 1 [closed] => 1 )This is a simple hack to add one of my favorite MT-plugins, Brad Choate's MTMacros [bradchoate.com], to textpattern.
Granted, I didn't pull the entire kaboodle. This doesn't do fun container logic and acronym matching, etc. But it does do simple string replacement, which is what I used it for (e.g. smilies and pretty attributions).



