Basic password protection with custom fields and PHP
One of the recurring issues with Movable Type is that it does not offer even rudimentary password protection for entries out of the box. However, implementing the sort of basic password protection that WordPress uses is not hard at all. It just requires you to use the Custom Fields feature from Movable Type Professional.
This tutorial assumes that you have configured Movable Type to publish its files as PHP files. If you are unfamiliar with this, you will need to change the main index to be published as a PHP file, and you will need to go into the publishing preferences and change the archive file extension. Any file that you want to display the password field will need to be a PHP file in order to make this work. If you are using JSP, ASP.NET, ColdFusion or another dynamic page system, the PHP is simple and straight-forward for converting into those formats.
The first step, is to create two new custom fields, Entry Password and Page Password. Create them on entry and page objects respectively, as single-line text fields. Use the following screenshots as an example if you get confused. Make sure that the tag names for the fields are EntryPassword and PagePassword respectively.
The second step is to replace references to <mt:EntryBody> and other tags which print entry/page content with some PHP code that will interact with these custom fields. Open your individual entry archives, and look for the following template markup:
<mt:If tag="EntryBody">
<div class="asset-body">
<$mt:EntryBody$>
</div>
</mt:If>
<mt:If tag="EntryMore" convert_breaks="0">
<div id="more" class="asset-more">
<$mt:EntryMore$>
</div>
</mt:If>
Replace that block with the following block of PHP code and Movable Type template markup:
<?php
$password = "<mt:EntryPassword encode_sha1="1"/>";
if ( (isset($password) && sha1($_POST["password"]) == $password) ||
(!isset($password)) ) {
?>
<mt:If tag="EntryBody">
<div class="asset-body">
<$mt:EntryBody$>
</div>
</mt:If>
<mt:If tag="EntryMore" convert_breaks="0">
<div id="more" class="asset-more">
<$mt:EntryMore$>
</div>
</mt:If>
<?php
} else {
?>
<form action="<mt:EntryPermalink/>" method="post">
<table>
<tbody>
<tr>
<td>
<p>This post is password protected. To read it, enter the password now.</p>
<p><input type="password" name="password"/></p>
<p><input type="submit" value="Log In"/></p>
</td>
</tr>
</tbody>
</table>
</form>
<?php
}
?>
Add the following code to the HTML Header template module:
<?php
$passwords = array();
?>
Now, go through the index template, monthly, category and other listing archives, and replace the <mt:EntryBody> references with the following code:
<?php
$passwords[entry_<mt:EntryId/>] = "<mt:EntryPassword encode_sha1="1"/>";
if ( (isset($passwords[entry_<mt:EntryId/>]) && sha1($_POST["password"]) == $passwords[entry_<mt:EntryId/>]) ||
(!isset($passwords[entry_<mt:EntryId/>])) ) {
?>
<mt:EntryBody/>
<?php
} else {
?>
<form action="<mt:EntryPermalink/>" method="post">
<table>
<tbody>
<tr>
<td>
<p>This post is password protected. To read it, enter the password now.</p>
<p><input type="password" name="password"/></p>
<p><input type="submit" value="Log In"/></p>
</td>
</tr>
</tbody>
</table>
</form>
<?php
}
?>
In a typical installation of Movable Type 4, that will be needed in the main index, monthly archives, author archives and calendar archives (if you are using those two). To password protect pages, you can reuse the code from the individual archive listing with one modification. Change the password variable line to read:
$password = "<mt:PagePassword encode_sha1="1"/>";
News feeds will, by default, publish password protected content, so what you will need to do there is to put a <mt:If> statement around the content inside the <mt:Entries> loop. Use this for entries:
<mt:If tag="EntryPassword" eq=""></mt:If>
That will prevent password protected entries from being published in those archives.
This is admittedly just a stop-gap measure until Movable Type gets a more robust authentication system for use outside of the CMS. However, it should be good enough for most people for now. Leave a comment if you have any issues implementing this.

Hi Mike,
Thanks for this tutorial - got it up and running in 5 mins. And it works :)
Some feedback:
1) The password field is initially defaulted to "********" even when you encounter the field for the first time
2) More importantly, you have to enter the password in each time you visit the page (or confirm it if you allow browser to remember it)
3) Instructions above - you might want to amend 'Add the following code to the HTML Header template module:' to 'Add the following code to the Header global template module:' - a little confusing at first as I was looking for an 'HTML Header'
1) and 3) are very minor - the code works fine but with the key limitation of 2). I know it's a bit more of a problem getting round this but I thought it was worth giving the feedback in case you develop further - not sure if I'm going to use code or not for this reason...
Thanks for the tutorial though.
Cheers,
firebrandyouth