Thursday, June 23, 2016

Using ASP.NET master pages as templates to create static HTML pages

ASP.NET has the concept of "master pages", which can contain placeholders to be filled in by normal pages. If you aren't actually running any .NET code, there's no reason to make the web server go through the work of rendering the full page from its parts. Since I wanted to get a bunch of static pages instead of ASPX ones, I wrote a PowerShell script today that compiles ASPX documents into standalone HTML pages (and fixes up links):

$template = Get-Content $args[0] | Select -Skip 1 | Out-String
$template = $template.Replace('asp:ContentPlaceHolder ID', 'asp:ContentPlaceHolder id')
$placeholders = $args[1].Split(',')
Get-ChildItem *.aspx | ForEach-Object {
 $text = Get-Content $_ | Select -Skip 1 | Out-String
 $finaltext = $template
 $contentnumber = 1
 $placeholders | ForEach-Object {
  $masterplaceholder = '<asp:ContentPlaceHolder id="' + $_ + '" runat="server"></asp:ContentPlaceHolder>'
  $valueopener = '<asp:Content ID="Content' + $contentnumber + '" ContentPlaceHolderID="' + $_ + '" Runat="Server">'
  $content = (($text -Split $valueopener)[1] -Split '</asp:Content>')[0]
  $finaltext = $finaltext.Replace($masterplaceholder, $content)
  $contentnumber++
 }
 $finaltext = $finaltext.Replace('.aspx', '.html')
 $newname = $_.Name.Replace('.aspx', '.html')
 $finaltext | Out-File $newname
 Remove-Item $_
}
Get-ChildItem *.vb | Remove-Item
Get-ChildItem *.config | Remove-Item
Remove-Item $args[0]

It assumes that your Content elements are named sequentially. The script takes two arguments: the name of the master page and a comma-separated list of placeholder IDs. For example:

.\compile.ps1 example.master title,text

The script blows away ASPX pages, VB code files, configuration files, and the master page. Therefore, you should copy your site into a different folder before running it. (I had it clean the folder for ease of uploading the site.)

No comments:

Post a Comment