Using MTML, you can sort assets by label in an entry context like this:

<mt:EntryAssets sort_by="label">
    <!-- asset content here -->
</mt:EntryAssets>

However on the Edit Entry screen the filename for each asset is listed, but the assets are not sorted by filename.

The following steps will update the Edit Entry/Page screen to list assets by asset label…

Three App Templates to Edit

$MT_HOME/tmpl/cms/edit_entry.tmpl

Update the template that produces the Edit Entry/Page screen.

  1. Line 491:

    <mt:var name="asset_name">
    

    Change to:

    <mt:var name="asset_label"> [<mt:var name="asset_name">]
    

$MT_HOME/lib/MT/CMS/Entry.pm

Update the script that collects the assets in the sidebar of the Edit Entry/Page screen.

  1. Line 191:

    $asset_1 = {asset_id => $asset->id, asset_name => $asset->file_name, asset_thumb => $asset->thumbnail_url(Width=>100)};
    

    Change to:

    $asset_1 = {asset_id => $asset->id, asset_name => $asset->file_name, asset_label => $asset->label, asset_thumb => $asset->thumbnail_url(Width=>100)};
    
  2. Line 193:

    $asset_1 = {asset_id => $asset->id, asset_name => $asset->file_name};
    

    Change to:

    $asset_1 = {asset_id => $asset->id, asset_name => $asset->file_name, asset_label => $asset->label};
    
  3. Line 201:

    my $asset_1 = {asset_id => $asset->id, asset_name => $asset->file_name};
    

    Change to:

    my $asset_1 = {asset_id => $asset->id, asset_name => $asset->file_name, asset_label => $asset->label};
    
  4. Line 210:

    $asset_1 = {asset_id => $asset->id, asset_name => $asset->file_name, asset_thumb => $asset->thumbnail_url(Width=>100)};
    

    Change to:

    $asset_1 = {asset_id => $asset->id, asset_name => $asset->file_name, asset_label => $asset->label, asset_thumb => $asset->thumbnail_url(Width=>100)};
    
  5. Line 212:

    $asset_1 = {asset_id => $asset->id, asset_name => $asset->file_name};
    

    Change to:

    $asset_1 = {asset_id => $asset->id, asset_name => $asset->file_name, asset_label => $asset->label};
    
  6. Line 217: This will sort assets by asset_label:

    $param->{asset_loop} = $assets;
    

    Change to:

    $param->{asset_loop} = [ map $_->[1], sort { $a->[0] cmp $b->[0] } map { [ $_->{asset_label}, $_ ] } @$assets ];
    

$MT_HOME/tmpl/cms/dialog/asset_insert.tmpl

Update the script that inserts the asset into the list of assets once selected.

  1. Line43

    myAssetLink.appendChild(document.createTextNode('<mt:AssetLabel encode_js="1"> [<mt:AssetFileName encode_js="1">]'));
    

    Change to:

    myAssetLink.appendChild(document.createTextNode('<mt:AssetFileName encode_js="1">'));
    

Without using a plugin, the best method for user-defined ordering of pages and entries is to sort by authored_on date.

Entries:

<mt:Entries sort_by="authored_on">
    <!-- entry content here -->
</mt:Entries>

Pages:

<mt:Pages sort_by="authored_on">
    <!-- page content here -->
</mt:Pages>

The authored_on date for entries can easily be updated using the “batch edit” functionality in the “More actions…” menu on the Manage Entries listing screen.

Because pages are listed by modified_on the “batch edit” functionality also uses the modified_on date. This is bad because the next time the page is saved, the modified date will be updated. (I submitted a bug about this some time ago.).

So follow along as we make a few changes to two Movable Type application templates to update Manage Pages screen (and the batch edit functionality for pages) use the authored_on date instead of the modified_on date.

Note: We could just update the batch edit mode to use the authored_on date, but it would be more useful to update the Manage Pages screen to also use the authored_on date so that pages will be listed in the same order they will appear in the templates.

These steps were tested in versions MT4.32 and MT4.261 but will work for all versions of MT4.x and MT5.0 as well.

Tip: Always make a backup of a default file before modifying it; I duplicate the file and place a ~ after it:

cp file.mtml file.mtml~

Two App Templates to Edit

$MT_HOME/tmpl/cms/include/entry_table.tmpl

One change repacing the table header label:

  1. Search for (line 79):

    <th class="date"><mt:if name="object_type" eq="page"><__trans phrase="Last Modified"><mt:else><__trans phrase="Created"></mt:if></th>
    

    Replace with:

    <th class="date"><__trans phrase="Created"></th>
    

$MT_HOME/lib/MT/CMS/Entry.pm

Three changes replacing modified_on with authored_on where conditioning based upon $type eq 'page':

  1. Search for (line 547):

    $arg{'sort'} = $type eq 'page' ? 'modified_on' : 'authored_on';
    

    Replace with:

    $arg{'sort'} = 'authored_on';
    
  2. Search for (line 1726):

    $entry->modified_on($ts);
    

    Replace with:

    $entry->authored_on($ts);
    
  3. Search for (lines 1988 and 1989):

    if ( my $ts =
        ( $type eq 'page' ) ? $obj->modified_on : $obj->authored_on )
    

    Replace with:

    if ( my $ts = $obj->authored_on )
    

Once these edits have been made, login to Movable Type and view the Manage Pages screen. All pages will be listed by created_on date.

That’s it!

Previously, I wrote about how to add Edit Links to Entry and Page templates.

This guide uses the mt_user cookie set when logging into Movable Type to condition content (links to screens in MT) on entries and pages published by Movable Type.

Also provides an option to use a non-MT cookie to do the same thing.

Advanced Breadcrumb Navigation

| 2 Comments

I needed a flexible system to append crumbs to an array… potentially remove items from the array, then output the array on the final template as a breadcrumb navigation. This was my solution using Movable Type template tags.

I used the Var function attribute to push, shift, unshift items on an array variable and then used mt:loop to output the items in the array into a list of breadcrumbs. This was used in a Movable Type install with 20 blogs.

In a “global config” template module (included in the first line of every template) set the top level of the breadcrumbs:

<mt:SetVarBlock name="breadcrumbs" function="push">
    <a href="<$mt:BlogURL$>"><$mt:BlogName$></a>
</mt:SetVarBlock>

On an Entry archive template, add crumb to Category archive, Daily archive, and then add the Entry title:

<mt:IfArchiveTypeEnabled archive_type="Category">
    <mt:If tag="EntryCategory">
        <mt:SetVarBlock name="breadcrumbs" function="push">
            <a href="<$mt:EntryLink type="Category"$>"><$mt:EntryCategory$></a>
        </mt:SetVarBlock>
    </mt:If>
</mt:IfArchiveTypeEnabled>
<mt:IfArchiveTypeEnabled archive_type="Daily">
    <mt:SetVarBlock name="breadcrumbs" function="push">
    <a href="<$mt:EntryLink type="Daily"$>"><$mt:EntryDate format="%B %d, %Y"$></a>
    </mt:SetVarBlock>
</mt:IfArchiveTypeEnabled>
<mt:SetVarBlock name="breadcrumbs" function="push">
    <$mt:EntryTitle$>
</mt:SetVarBlock>

On an Entry Listing archive template for a blog with Monthly archives enabled, add crumb for Archive Index page and for the current page.

<mt:IfArchiveTypeEnabled archive_type="Monthly">
    <mt:SetVarBlock name="breadcrumbs" function="push">
        <a href="<$mt:Link template="archive_index"$>">Archives</a>
    </mt:SetVarBlock>
</mt:IfArchiveTypeEnabled>
<mt:SetVarBlock name="breadcrumbs" function="push">
    <$mt:ArchiveTitle$>
</mt:SetVarBlock>

In index templates (such as the Archive Index), add current page as the last crumb to the end of the array:

<mt:SetVarBlock name="breadcrumbs" function="push">
    Archives
</mt:SetVarBlock>

To replace the first crumb if the BlogID is “1”, use the “shift” function to remove and the “unshift” function to prepend a crumb (I added this to a “blog config” template module which is included just after the “global config” template module in the first two lines of each template):

<mt:If tag="BlogID" eq="1">
    <$mt:GetVar name="breadcrumbs" function="shift" setvar="removed_value"$>
    <mt:SetVarBlock name="breadcrumbs" function="unshift">
        <a href="/foo/">Foo</a>
    </mt:SetVarBlock>
</mt:If>

On the main index template for each blog I didn’t want to show breadcrumbs, so I’d set this boolean value:

<$mt:Var name="show_breadcrumbs" value="0"$>

To output the crumbs, use the mt:loop tag:

<mt:If name="show_breadcrumbs">
<div class="breadcrumbs">
    <ol>
    <mt:Loop name="breadcrumbs">
        <li<mt:If name="__last__"> class="last"</mt:If>><$mt:Var name="__value__" trim="1"$></li>
    </mt:Loop>
    </ol>
</div>
</mt:If>

With large volumes of code… sometimes it’s useful to place comments in the code to document what the code does.

In html, developers often use a html comment on a closing div tag to note which tag is being closed.

<div id="main-content">
    ...many lines of code here...
</div><!-- end of #main-content -->

Once the page is being published in the production environment, these comments are no longer necessary and just add to the weight of the file.

There are many ways to condition these links in Movable Type:

  • Create a Global Config template module and then set a variable in that template. Include this template module in all your templates and use the value to condition code.

    Global Config (use a value of 1 to show, 0 to hide)

    <mt:Var name="display_coments" value="0">
    

    Index Template

    <$mt:Include module="Global Config"$>
    <div id="main-content">
        ...many lines of code here...
    </div>
    <mt:If name="display_commnts">
        <!-- end of #main-content -->
    </mt:If>
    
  • Use configuration directives in your template. There are a bunch of useful Configuration Directives for Movable Type. Use the value of config directives in your templates as conditionals.

    In the mt-config.cgi file add config directives:

    # Config Directives
    ## Required
    CGIPath /cgi-bin/branch-hanson/
    Database mt_db
    DBUser foo
    DBPassword bar
    DBHost localhost
    
    
    ## Optional
    DebugMode 1  # See http://movabletype.org/config/DebugMode
    FooBar 3     # Made up config directive
    

    Use the DebugMode config directive:

    <mt:If name="config.DebugMode">
        <!-- comment here -->
    </mt:If>
    

    Or make up your own and use the value such as FooBar:

    <mt:If name="config.FooBar" eq="1">
        <!-- condition 1 comment here -->
    <mt:If name="config.FooBar" eq="2">
        <!-- condition 2 comment here -->
    <mt:Else>
        <!-- condition <$mt:Var name="config.FooBar"$> comment here -->
    </mt:If>
    

Hope either of these may be useful.

Heading Anchors via jQuery

| No Comments

Markdown is my text markup of choice… but one thing it doesn’t have is the ability to add classes or id elements to any of the html. Because what I wanted to do wasn’t critical without JavaScript enabled, I used jQuery to implement the same solution that the HeadingAnchors plugin does… but in JavaScript. This also creates a navigation menu using all the H2 tag heading text.

Code

Requires dirify function and dirify_table.

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load("jquery", "1.3.2");

    // When the document is ready for javascript fun...
    google.setOnLoadCallback(function() {
        // initalize variable
        var $menu = '';
        // select all the page headings, assuming that h1 is only used once (for the main page title)
        $("h2, h3, h4, h5, h6").each(function () {
            // Dirity heading text to create the anchor
            $anchor = dirify($(this).text());
            // If heading is h2, add list item to menu
            if ("H2" == $(this)[0].nodeName) {
                $menu += '<li><a href="#' + $anchor + '">' + $(this).text() + '</a></li>';
            };
            // Append anchor to heading
            $(this).append('<a title="Link to this section" class="anchor" href="#' + $anchor + '"> ¶</a>').attr('id', $anchor);
        });
        // Add menu to sidebar
        $('.sidebar').prepend('<div class="tag-menu"><h3>Tag Types</h3><ul>' + $menu + '</ul></div>');
    });
</script>

Dirify Function in Javascript

| 2 Comments

Was messing around with JavaScript and jQuery and needed a dirify function… found one in the Movable Type core JavaScript file. Thought I’d post it here for the value of all vis-à-vis Google as the first results weren’t as useful as I hope this is.

And I added two features to the default code in MT:

  1. I like to use ampersands in my titles because they look spiffy, so I added ampersands to the dirify_table such that “&” is now dirified to “and”.

    dirify("Me & Ed's Pizza");
    // result: me_and_eds_pizza
    
  2. Sometimes you want dashes instead of underscores. This dirify function takes a second parameter that is the default separator.

    dirify("What the Duck?", "-");
    // result: what-the-duck
    

Examples

Place these examples in html <body>:

<script type="text/javascript">
var foo = "You & Me";
var bar = dirify(foo);
document.write('"' + foo + '" dirified is "' + bar + '"');

document.write('<br />');

// dirify on on one line
document.write(dirify("Me & Ed's Pizza"));

document.write('<br />');

// Use a dash
document.write(dirify("¿Is Open-Source is the bomb'd?", "-"));
</script>

Dirify Code

Place the dirify function and the dirify_table in the <head> of the html page… or in the referenced JavaScript file:

<script type="text/javascript">
function dirify (s,d) {
    if (!d)
        d = "_";
    s = s.replace(/<[^>]+>/g, '');
    for (var p in dirify_table)
        if (s.indexOf(p) != -1)
            s = s.replace(new RegExp(p, "g"), dirify_table[p]);
    s = s.toLowerCase();
    s = s.replace(/&[^;\s]+;/g, '');
    s = s.replace(/[^-a-z0-9_ ]/g, '');
    s = s.replace(/\s+/g, '_');
    s = s.replace(/_+$/, '');
    s = s.replace(/_+/g, d);
    return s;
}
var dirify_table = {
    "\u0026": 'and',  // ampersand
    "\u00C0": 'A',    // A`
    "\u00E0": 'a',    // a`
    "\u00C1": 'A',    // A'
    "\u00E1": 'a',    // a'
    "\u00C2": 'A',    // A^
    "\u00E2": 'a',    // a^
    "\u0102": 'A',    // latin capital letter a with breve
    "\u0103": 'a',    // latin small letter a with breve
    "\u00C6": 'AE',   // latin capital letter AE
    "\u00E6": 'ae',   // latin small letter ae
    "\u00C5": 'A',    // latin capital letter a with ring above
    "\u00E5": 'a',    // latin small letter a with ring above
    "\u0100": 'A',    // latin capital letter a with macron
    "\u0101": 'a',    // latin small letter a with macron
    "\u0104": 'A',    // latin capital letter a with ogonek
    "\u0105": 'a',    // latin small letter a with ogonek
    "\u00C4": 'A',    // A:
    "\u00E4": 'a',    // a:
    "\u00C3": 'A',    // A~
    "\u00E3": 'a',    // a~
    "\u00C8": 'E',    // E`
    "\u00E8": 'e',    // e`
    "\u00C9": 'E',    // E'
    "\u00E9": 'e',    // e'
    "\u00CA": 'E',    // E^
    "\u00EA": 'e',    // e^
    "\u00CB": 'E',    // E:
    "\u00EB": 'e',    // e:
    "\u0112": 'E',    // latin capital letter e with macron
    "\u0113": 'e',    // latin small letter e with macron
    "\u0118": 'E',    // latin capital letter e with ogonek
    "\u0119": 'e',    // latin small letter e with ogonek
    "\u011A": 'E',    // latin capital letter e with caron
    "\u011B": 'e',    // latin small letter e with caron
    "\u0114": 'E',    // latin capital letter e with breve
    "\u0115": 'e',    // latin small letter e with breve
    "\u0116": 'E',    // latin capital letter e with dot above
    "\u0117": 'e',    // latin small letter e with dot above
    "\u00CC": 'I',    // I`
    "\u00EC": 'i',    // i`
    "\u00CD": 'I',    // I'
    "\u00ED": 'i',    // i'
    "\u00CE": 'I',    // I^
    "\u00EE": 'i',    // i^
    "\u00CF": 'I',    // I:
    "\u00EF": 'i',    // i:
    "\u012A": 'I',    // latin capital letter i with macron
    "\u012B": 'i',    // latin small letter i with macron
    "\u0128": 'I',    // latin capital letter i with tilde
    "\u0129": 'i',    // latin small letter i with tilde
    "\u012C": 'I',    // latin capital letter i with breve
    "\u012D": 'i',    // latin small letter i with breve
    "\u012E": 'I',    // latin capital letter i with ogonek
    "\u012F": 'i',    // latin small letter i with ogonek
    "\u0130": 'I',    // latin capital letter with dot above
    "\u0131": 'i',    // latin small letter dotless i
    "\u0132": 'IJ',   // latin capital ligature ij
    "\u0133": 'ij',   // latin small ligature ij
    "\u0134": 'J',    // latin capital letter j with circumflex
    "\u0135": 'j',    // latin small letter j with circumflex
    "\u0136": 'K',    // latin capital letter k with cedilla
    "\u0137": 'k',    // latin small letter k with cedilla
    "\u0138": 'k',    // latin small letter kra
    "\u0141": 'L',    // latin capital letter l with stroke
    "\u0142": 'l',    // latin small letter l with stroke
    "\u013D": 'L',    // latin capital letter l with caron
    "\u013E": 'l',    // latin small letter l with caron
    "\u0139": 'L',    // latin capital letter l with acute
    "\u013A": 'l',    // latin small letter l with acute
    "\u013B": 'L',    // latin capital letter l with cedilla
    "\u013C": 'l',    // latin small letter l with cedilla
    "\u013F": 'l',    // latin capital letter l with middle dot
    "\u0140": 'l',    // latin small letter l with middle dot
    "\u00D2": 'O',    // O`
    "\u00F2": 'o',    // o`
    "\u00D3": 'O',    // O'
    "\u00F3": 'o',    // o'
    "\u00D4": 'O',    // O^
    "\u00F4": 'o',    // o^
    "\u00D6": 'O',    // O:
    "\u00F6": 'o',    // o:
    "\u00D5": 'O',    // O~
    "\u00F5": 'o',    // o~
    "\u00D8": 'O',    // O/
    "\u00F8": 'o',    // o/
    "\u014C": 'O',    // latin capital letter o with macron
    "\u014D": 'o',    // latin small letter o with macron
    "\u0150": 'O',    // latin capital letter o with double acute
    "\u0151": 'o',    // latin small letter o with double acute
    "\u014E": 'O',    // latin capital letter o with breve
    "\u014F": 'o',    // latin small letter o with breve
    "\u0152": 'OE',   // latin capital ligature oe
    "\u0153": 'oe',   // latin small ligature oe
    "\u0154": 'R',    // latin capital letter r with acute
    "\u0155": 'r',    // latin small letter r with acute
    "\u0158": 'R',    // latin capital letter r with caron
    "\u0159": 'r',    // latin small letter r with caron
    "\u0156": 'R',    // latin capital letter r with cedilla
    "\u0157": 'r',    // latin small letter r with cedilla
    "\u00D9": 'U',    // U`
    "\u00F9": 'u',    // u`
    "\u00DA": 'U',    // U'
    "\u00FA": 'u',    // u'
    "\u00DB": 'U',    // U^
    "\u00FB": 'u',    // u^
    "\u00DC": 'U',    // U:
    "\u00FC": 'u',    // u:
    "\u016A": 'U',    // latin capital letter u with macron
    "\u016B": 'u',    // latin small letter u with macron
    "\u016E": 'U',    // latin capital letter u with ring above
    "\u016F": 'u',    // latin small letter u with ring above
    "\u0170": 'U',    // latin capital letter u with double acute
    "\u0171": 'u',    // latin small letter u with double acute
    "\u016C": 'U',    // latin capital letter u with breve
    "\u016D": 'u',    // latin small letter u with breve
    "\u0168": 'U',    // latin capital letter u with tilde
    "\u0169": 'u',    // latin small letter u with tilde
    "\u0172": 'U',    // latin capital letter u with ogonek
    "\u0173": 'u',    // latin small letter u with ogonek
    "\u00C7": 'C',    // ,C
    "\u00E7": 'c',    // ,c
    "\u0106": 'C',    // latin capital letter c with acute
    "\u0107": 'c',    // latin small letter c with acute
    "\u010C": 'C',    // latin capital letter c with caron
    "\u010D": 'c',    // latin small letter c with caron
    "\u0108": 'C',    // latin capital letter c with circumflex
    "\u0109": 'c',    // latin small letter c with circumflex
    "\u010A": 'C',    // latin capital letter c with dot above
    "\u010B": 'c',    // latin small letter c with dot above
    "\u010E": 'D',    // latin capital letter d with caron
    "\u010F": 'd',    // latin small letter d with caron
    "\u0110": 'D',    // latin capital letter d with stroke
    "\u0111": 'd',    // latin small letter d with stroke
    "\u00D1": 'N',    // N~
    "\u00F1": 'n',    // n~
    "\u0143": 'N',    // latin capital letter n with acute
    "\u0144": 'n',    // latin small letter n with acute
    "\u0147": 'N',    // latin capital letter n with caron
    "\u0148": 'n',    // latin small letter n with caron
    "\u0145": 'N',    // latin capital letter n with cedilla
    "\u0146": 'n',    // latin small letter n with cedilla
    "\u0149": 'n',    // latin small letter n preceded by apostrophe
    "\u014A": 'N',    // latin capital letter eng
    "\u014B": 'n',    // latin small letter eng
    "\u00DF": 'ss',   // double-s
    "\u015A": 'S',    // latin capital letter s with acute
    "\u015B": 's',    // latin small letter s with acute
    "\u0160": 'S',    // latin capital letter s with caron
    "\u0161": 's',    // latin small letter s with caron
    "\u015E": 'S',    // latin capital letter s with cedilla
    "\u015F": 's',    // latin small letter s with cedilla
    "\u015C": 'S',    // latin capital letter s with circumflex
    "\u015D": 's',    // latin small letter s with circumflex
    "\u0218": 'S',    // latin capital letter s with comma below
    "\u0219": 's',    // latin small letter s with comma below
    "\u0164": 'T',    // latin capital letter t with caron
    "\u0165": 't',    // latin small letter t with caron
    "\u0162": 'T',    // latin capital letter t with cedilla
    "\u0163": 't',    // latin small letter t with cedilla
    "\u0166": 'T',    // latin capital letter t with stroke
    "\u0167": 't',    // latin small letter t with stroke
    "\u021A": 'T',    // latin capital letter t with comma below
    "\u021B": 't',    // latin small letter t with comma below
    "\u0192": 'f',    // latin small letter f with hook
    "\u011C": 'G',    // latin capital letter g with circumflex
    "\u011D": 'g',    // latin small letter g with circumflex
    "\u011E": 'G',    // latin capital letter g with breve
    "\u011F": 'g',    // latin small letter g with breve
    "\u0120": 'G',    // latin capital letter g with dot above
    "\u0121": 'g',    // latin small letter g with dot above
    "\u0122": 'G',    // latin capital letter g with cedilla
    "\u0123": 'g',    // latin small letter g with cedilla
    "\u0124": 'H',    // latin capital letter h with circumflex
    "\u0125": 'h',    // latin small letter h with circumflex
    "\u0126": 'H',    // latin capital letter h with stroke
    "\u0127": 'h',    // latin small letter h with stroke
    "\u0174": 'W',    // latin capital letter w with circumflex
    "\u0175": 'w',    // latin small letter w with circumflex
    "\u00DD": 'Y',    // latin capital letter y with acute
    "\u00FD": 'y',    // latin small letter y with acute
    "\u0178": 'Y',    // latin capital letter y with diaeresis
    "\u00FF": 'y',    // latin small letter y with diaeresis
    "\u0176": 'Y',    // latin capital letter y with circumflex
    "\u0177": 'y',    // latin small letter y with circumflex
    "\u017D": 'Z',    // latin capital letter z with caron
    "\u017E": 'z',    // latin small letter z with caron
    "\u017B": 'Z',    // latin capital letter z with dot above
    "\u017C": 'z',    // latin small letter z with dot above
    "\u0179": 'Z',    // latin capital letter z with acute
    "\u017A": 'z'     // latin small letter z with acute
};
</script>

Stumbled across another way to Add Custom Styles for a Single Entry in Movable Type from the entry Individual Style on Khoi Vinh’s Subtraction.com.

  1. Create a css file using the same basename as your entry, but with a .css extension
  2. Place this bit of PHP in the <head> element next to your other stylesheet links:

    <?php
    // check to see if a css file with the same name as the permalink exists,
    // if so print a link to it
    if (file_exists("<$MTEntryPermalink$>.css")) {
        print '<link rel="stylesheet" type="text/css" href="<$MTEntryPermalink$>.css" />';
    }
    ?>
    

This is great if there are many rules to add and/or if there is a need to edit the css independently from the publishing of the entry.

For just a few simple rules I’d still add the rules inline. This has the benefit of keeping the styles directly associated to the content being styled.

Edit Links for Entry and Pages

| 3 Comments

Update: Advanced version using cookies to condition “edit” links

Add an edit links to your Movable Type entries and pages.

This guide will take you through the steps to install the necessary software to turn your Mac into a server with the required software to run Movable Type and then walk you though installing Movable Type.

You will need the following:

  • A Mac! - this installation was tested on a Mac Mini, an iMac, and a MacBook Pro both running Mac OS 10.5.5
  • Administrator user account on the Mac
  • Xcode Tools instaler on the Mac OS X Install DVD or available as a download from Apple.com
  • internet connection …well I guess you have one if you’re reading this!
  • Terminal.app - find this in your Utilities folder (from the Finder: Go > Utilities). You should be comfortable using the command line when proceeding with the following steps.

We’ll first install the following server software:

  • Xcode Tools
  • MySQL
  • PHP5
  • Perl modules:
    • DBD::mysql
    • Crypt::DSA
    • IPC::Run
    • Crypt::SSLeay
    • IO::Uncompress::Gunzip
    • IO::Compress::Gzip
    • Mail::Sendmail
  • Image Magick and required image libraries:
    • LibJPEG
    • Libpng
    • Libiff

Then we’ll perform the steps specific to setting up a site and installing Movable Type:

  • create a file structure for a site
  • create a default apache config
  • download Movable Type
  • create a MySQL database
  • configure Movable Type

Install Server Software

Installing these 8 software libraries takes about 45 minutes. As I completed the step, I noted the running time.

  1. Install Xcode Tools

    Double-click “XcodeTools” from the DVD that came with your mac.

    Find it on the DVD in the following folder chain: Mac OS X Install DVD/ Optional Installs/ Xcode Tools/ XcodeTools

    (running time: 8 min)

  2. Install MySQL

    1. Go here: http://dev.mysql.com/downloads/mysql/5.1.html#macosx-dmg
    2. Download Mac OS X 10.5 (x86)

      Note: After choosing a mirror, you are prompted to register. No need, click the link under the registration and sign in boxes: “No thanks, just take me to the downloads!”

    3. Install (double-click) all the following items in the bundle:

      • mysql-5.1.34-osx10.5-x86.pkg (or newer version)
      • MySQLStartupItem.pkg
      • MySQL.prefPane
    4. After installing MySQL.prefPane, the preference pane will be displayed. Click the Start MySQL Server button and be sure the checkbox for Automatically Start MySQL Server on Startup is checked.

    (running time: 12 min)

  3. Install PHP

    PHP 5.x is pre-installed in Mac OS 10.5.x. Edit the apache config:

    $ sudo vi /private/etc/apache2/httpd.conf
    

    Remove the “#” from the beginning of this line to enable PHP:

    #LoadModule php5_module        libexec/apache2/libphp5.so
    

    (running time: 14 min)

  4. Install Perl modules

    Install the below modules via Terminal app. Each may take a few minutes to install. If installation seems to stall but you get no errors, then assume all is going well. If necessary, go make a sandwich and come back a little while later.

    While installing, if prompted:

    • enter the admin user password when prompted: type the password and hit “return”.
    • manual configuration: type “n” and hit “return” to use default configuration.
    • optional modules: type “n” and hit “return” to not install these.
    • mandatory modules: type “y” and hit “return” to install these.
    • select the default option when otherwise prompted: hit “return”.

    Install be below Perl modules one-by-one (running time listed below):

    $ sudo cpan DBD::mysql
    $ sudo cpan IPC::Run
    $ sudo cpan Crypt::SSLeay
    $ sudo cpan IO::Uncompress::Gunzip
    $ sudo cpan IO::Compress::Gzip
    $ sudo cpan Mail::Sendmail
    $ sudo cpan Crypt::DSA
    

    sudo cpan DBD::mysql (running time: 15 min)
    sudo cpan IPC::Run (running time: 16 min)
    sudo cpan Crypt::SSLeay (running time: 17 min)
    sudo cpan IO::Uncompress::Gunzip (running time: 18 min)
    sudo cpan IO::Compress::Gzip (running time: 19 min)
    sudo cpan Mail::Sendmail (running time: 20 min)
    sudo cpan Crypt::DSA (running time: 22 min)

    We’ll check to ensure all these modules are installed correctly using the mt-check.cgi script after installing Movable Type.

  5. Install ImageMagick

    We’ll install three image libraries and then ImageMagic itself.

    1. Create a temp directory

      This directory will be used for the downloaded software used in the following steps. Create it then change to that directory:

      $ mkdir ~/Desktop/mt_install;
      $ cd ~/Desktop/mt_install;
      
    2. Install image libraries

      There are three prerequisite libraries for the version of ImageMagick we’ll be installing.

      The below steps assume that you’re downloading files to the “Downloads” in the user’s home directory; modify the installation commands as necessary if your browser downloads the files to other locations.

      • Install LibJPEG

        1. Download LibJPEG. Grab the most recent tar.gz file from www.ijg.org
        2. Issue the following commands (replacing the name of the tar.gz below with file name below “jpegsrc.v6b.tar.gz”):

          $ cd ~/Desktop/mt_install;
          $ mv ~/Downloads/jpegsrc.v6b.tar.gz .;
          $ tar xfv jpegsrc.v6b.tar.gz;
          $ cd jpeg-6b;
          $ ln -s `which glibtool` ./libtool
          $ MACOSX_DEPLOYMENT_TARGET=10.5;
          $ export MACOSX_DEPLOYMENT_TARGET;
          $ ./configure --enable-shared;
          $ make;
          $ sudo mkdir /usr/local/include /usr/local/lib /usr/local/bin /usr/local/man /usr/local/man/man1;
          $ sudo make install;
          

          (running time: 25 min)

      • Install libpng

        1. Go the the libpng site: http://www.libpng.org/pub/png/libpng.html.
        2. Scroll to the “Source code” section and click the “.tar.gz” link under “with config script” heading.
        3. Issue the following commands:

          $ cd ~/Desktop/mt_install;
          $ mv ~/Downloads/libpng-1.2.35.tar.gz .;
          $ tar xfv libpng-1.2.35.tar.gz
          $ cd libpng-1.2.35;
          $ ./configure --enable-shared;
          $ make;
          $ sudo make install;
          

        (running time: 29 min)

      • Install libtiff

        1. Download tiff-3.8.2.tar.gz from http://dl.maptools.org/dl/libtiff/ (which is the download mirror site of http://www.libtiff.org/)
        2. Issue the following commands:

          $ cd ~/Desktop/mt_install;
          $ mv ~/Downloads/tiff-3.8.2.tar.gz .;
          $ tar xfv tiff-3.8.2.tar.gz;
          $ cd tiff-3.8.2;
          $ ./configure --enable-shared;
          $ make;
          $ sudo make install;
          

          (running time: 32 min)

    3. install ImageMagick

      1. Download ImageMagic via FTP

        $ cd ~/Desktop/mt_install;
        $ ftp ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick.tar.gz
        $ tar xfvz ImageMagick.tar.gz;
        
      2. List the contents of the current directory to find the version of ImageMagick which was downloaded:

        $ ls
        
      3. Change to the ImageMagick directory. If you downloaded ImageMagick-6.5.2-2, then continue with the steps below, otherwise the next line to contain the correct version number. (Note: the “make” command takes about 5-8 min to complete)

        $ cd ImageMagick-6.5.2-2;
        $ LDFLAGS="-L/usr/local/lib" ./configure --with-jpeg=/usr/local/ --with-tiff=/usr/local --with-png=/usr/local;
        $ make;
        $ sudo make install;
        

      (running time: 43 min)

Movable Type Specific Install

  1. Create the file structure for local website

    This command will set up the basic structure of the _live directory in the ~/Sites directory as described below:

    $ mkdir ~/Sites/_live ~/Sites/_live/cgi ~/Sites/_live/docs ~/Sites/_live/html;
    

    The below file structure is how I setup the sites I develop locally on my Mac. I’m never actively developing one site at a time so I have a single webroot which I move the active site into; site1.com is the currently active site. (I have a script that I use to switch sites in and out of the web root which I may post about at a later date.)

    ~/Sites/
        _live/
            cgi/
                mt              <-- symlink to current MT directory (created in a later step)
                MT-4.25-en/     <-- MT app directory, aka $MT_HOME (created in a later step)
            docs/
                httpd.conf      <-- custom apache config (created in a later step)
            html/               <-- this will be the web-root
                mt-static/      <-- symlink to dir in $MT_HOME (created in a later step)
                index.html       
        site1.com/              <-- random site (currently disabled)
            docs/
                httpd.conf
            html/
                index.html
        site1.com/              <-- site currently active in the _live directory
        site2.com/              <-- random site (currently disabled)
            docs/
                httpd.conf
            html/
                index.html
    
  2. Configure the Apache web server

    1. Create the user apache configuration file (~/etc/httpd/httpd.conf) and directories:

      $ mkdir ~/etc/ ~/etc/httpd/;
      $ vi ~/etc/httpd/httpd.conf;
      
    2. Use the following code as the contents of the file, replacing “beau” and “sweetness” (name of my computer) with your own variables. (Set your computer’s name on the System Preferences -> Sharing Pane)

      <VirtualHost *:80>
          ServerName sweetness.local
          ServerAlias *.sweetness.local
          ServerAlias localhost
          DocumentRoot /Users/beau/Sites/_live/html
          DirectoryIndex index.php index.html
          # Include custom apache configuration from live site directory.
          include /Users/beau/Sites/_live/docs/*httpd.conf
          <Directory /Users/beau/Sites/_live>
              Order allow,deny
              Allow from all
              AllowOverride All
              Options Indexes FollowSymLinks MultiViews
              AddHandler application/x-httpd-php .php .html
          </Directory>
      </VirtualHost>
      

      Not all of this config file is crucial, but it’s all useful!

    3. Alias the user apache config file into the directory which the main apache config includes other config files.

      In the Terminal app create a symlink using the following command (replace “beau” with your username)

      $ sudo ln -s ~/etc/httpd/httpd.conf /private/etc/apache2/other/beau.conf
      

      The main apache config file (located here: /private/etc/apache2/httpd.conf) contains the line Include /private/etc/apache2/other/*.conf which will include all file ending in “.conf” which are placed in the /private/etc/apache2/other/ directory.

    4. Create site apache config file

      Create the file:

      $ vi ~/Sites/_live/docs/httpd.conf
      

      Add the following content:

      ScriptAlias /cgi/ /Users/beau/Sites/_live/cgi/
      Alias /mt-static/ /Users/beau/Sites/_live/cgi/mt/mt-static/
      AllowEncodedSlashes On  # required for MTConnect plugin
      <Directory "/Users/beau/Sites/_live/cgi">
          AllowOverride All
          Options None
          Order allow,deny
          Allow from all
          Options FollowSymLinks
      </Directory>
      <Directory "/Users/beau/Sites/_live/html">
          AllowOverride All
          Options +Indexes
          Order allow,deny
          Allow from all
          Options FollowSymLinks
      </Directory>
      SetEnv MAGICK_HOME /usr/local/ImageMagick-6.4.0
      SetEnv DYLD_LIBRARY_PATH /usr/local/ImageMagick-6.4.0/lib
      
    5. Restart Apache

      $ sudo apachectl graceful
      

      This is the same as unchecking and then checking the “Web Sharing” checkbox in the System Preferences -> Sharing preference pane

  3. Download Movable Type

    Filenames may be different if using different version of Movable Type.

    1. Download

      http://www.movabletype.com/downloads/download.php

    2. Uncompress the downloaded file

      $ unzip ~/Downloads/MT-4.25-en.zip
      
    3. Move MT to the live directory’s cgi folder

      $ mv ~/Downloads/MT-4.25-en ~/Sites/_live/cgi/
      
    4. Create symlink aliasing mt to the current version of MT.

      $ ln -s ~/Sites/_live/cgi/MT-4.25-en ~/Sites/_live/cgi/mt
      

      Note: This step will ease future upgrades. When upgrading in the future, use a modified version of this code to remove the symlink then replace it with a symlink to the new version:

      $ rm ~/Sites/_live/cgi/mt; ln -s ~/Sites/_live/cgi/NEW_MT_VERSION ~/Sites/_live/cgi/mt
      
  4. Create MySQL database

    1. Login to MySQL via the Terminal.app

      $ sudo /usr/local/mysql/bin/mysql
      

      Optional: Instead of entering the full path to MySQL /usr/local/mysql/bin/mysql, you can add the mysql location to your PATH. After doing the following you can simply enter sudo mysql. After updating .bash_profile you will need to open a new terminal window to reload bash profile settings. Minimally, .bash_profile should contain the following:

      PATH=$PATH:/usr/local/mysql/bin/
      export PATH
      
    2. Create database for Movable Type

      mysql> create database movabletype;
      

      Note: Instead of using movabletype you may want to create one database per version of Movable Type or per project/site.

    3. Set permissions on the database.

      mysql> grant all on movabletype.* to ''@'localhost' identified by '';
      

      Note: this command uses no username or password. This can make installation simper on a local machine, however it is recommended that a password be used on any shared machine.

  5. Configure Movable Type

    Create MT config file ~/Sites/_live/cgi/mt/mt-config.cgi and include the necessary variables. At a minimum this file should include:

    CGIPath /cgi/mt/
    StaticWebPath /mt-static
    
    
    ##### MYSQL #####
    ObjectDriver DBI::mysql
    Database movabletype
    # DBUser DATABASE_USERNAME     # unnecessary unless a username was set in the previous step
    # DBPassword DATABASE_PASSWORD # unnecessary unless a password was set in the previous step
    DBHost localhost
    
  6. Access Movable Type “MT Check” script

    http://localhost/cgi/mt/mt-check.cgi (or http://sweetness.local/cgi/mt/mt-check.cgi)

    Note: Everything on this check list should be green except for the non-MySQL database drivers and GD (Image Magic is better integrated with Movable Type than GD is.)

    If mt-check.cgi shows that various modules are not installed, attempt to re-install using the steps above.

  7. Install Movable Type

    Access this URL and follow the steps to create your first blog.

    http://localhost/cgi/mt/mt.cgi (or http://sweetness.local/cgi/mt/mt.cgi)

  8. Blog!

Done!

Recent Comments

  • cameraboys: Thanks a lot for the informative and interesting publication first read more
  • asset management: I just don’t know why my MT powered post are read more
  • guild wars 2 gold: That’s crazy! I remember this being an issue when MT4 read more
  • A Man: A zillion thanks for this ! read more
  • Mike Geary Review: This is entirely above my head. And here I thought read more
  • elkins.myid.net: This plugin has been so unbelievably useful to me. I read more
  • guide de jeux: Wow, it’s to complicated for me but I share for read more
  • guide de jeux: Thank you again for this article, I really think this read more
  • gercheq: I have been poking around to find something similar to read more
  • James: Yup…totally awesome advice. Thanks for that tidbit!! read more

Recent Assets

  • hack-category-order.jpg
  • mie-archives.gif
  • Anil Archives
  • Firefox MT Docs Bookmark Shortcut

Find recent content on the main index or look in the archives to find all content.

OpenID accepted here Learn more about OpenID
Powered by Movable Type 4.32-en