FAHNZ

MODE

Jan 25 2010

Website Launch GO! Dance Project Saint Louis Gets a New Look

Dance Project Saint Louis

After working on it off-and-on for …what? Over a year? We have finally launched the new website for my wife’s dance studio: Dance Project Saint Louis. Design by Ken, code by me, content by Dance Project.

It’s running WordPress and took me longer than expected to get all the little things worked out. That just might have something to do with the fact that I’m not terribly familiar with advanced WordPress development, nor am I very well-versed in PHP. I did learn a lot on the way though and I kept as much [traditionally] dynamic content as possible. Although I will admit I hard-coded a few items. One big one being the primary navigation.

Hard-coding the primary nav has it’s benefits though. I like being able to use lengthier, more descriptive names on those pages while keeping the primary nav link text nice and short.

Also started using MailChimp as our email list management service, thanks to their generous “Forever Free” accounts. Up to 500 subscribers and 3000 sends per month should do us well for quite some time. I was having trouble getting their code to work in the new site, but their customer support (via chat) was very responsive and helpful. The person on the other end was knowledgeable(!) even with my technical questions. Ended up being some kind of conflict with other jQuery code, so the help he (or she) could provide was limited, but like Simple Motives, I’m always impressed by good customer service and by knowledgeable support staff.

So, please, check it out. If you’re in St. Louis, sign up your daughters. If you’re a fellow dev, then constructive criticism is welcome.


Oct 26 2009

My Test ASP.NET Email Page

I need to test out this kind of functionality all the time. I’ve found it helpful to post this file to the web server that I need to be able to send email from and then tell the person who has control over the configuration of the email server to use this page to test with.

What follows is a self-contained ASP.NET page that allows the user to input all the information needed to configure how the email parameters are handled in the code in order to send a test message from the web server. This was recently (and quickly) converted from an ancient version in VB.NET and could use some serious tweaking; I’ll update the code here if I get around to it.  ;-)

<%@ Page Language="c#" Strict="false" %>
<%@ Import Namespace="System.Net.Mail" %>
<script language="c#" runat="server">
private string _mailServer;
private int _mailServerPort = 0;
private string _username;
private string _password;

private string _toAddress;
private string _fromAddress;
private string _subject;
private string _body;

private void btnSubmit_Click(Object sender, EventArgs e)
{
if (Page.IsValid)
{
_mailServer = txtMailServer.Text;
_username = txtUsername.Text;
_password = txtPassword.Text;

if (!string.IsNullOrEmpty(txtMailServerPort.Text)) { _mailServerPort = int.Parse(txtMailServerPort.Text); }

_toAddress = txtMailTo.Text;
_fromAddress = txtMailFrom.Text;
_subject = txtSubject.Text;
_body = txtBody.Text;

MailMessage message = new MailMessage(_fromAddress, _toAddress);

message.Headers.Add("Reply-To", _fromAddress);
message.Subject = _subject;
message.Body = GetResponse(_body);

SmtpClient mailer = new SmtpClient(_mailServer);
if (_mailServerPort > 0) { mailer.Port = _mailServerPort; }
if (!string.IsNullOrEmpty(_username)) { mailer.Credentials = new System.Net.NetworkCredential(_username, _password); }
mailer.EnableSsl = chkEnableSsl.Checked;

try
{
mailer.Send(message);
lblResponse.Text = CleanHtml(GetResponse("Email message appeared to send successfully."));
}

catch (Exception ex)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("There was an error sending the email message:");
sb.Append("\r\n");
sb.Append("\r\n");

sb.Append(ex.Message);
sb.Append("\r\n");
sb.Append("\r\n");

sb.Append(ex.StackTrace);

lblResponse.Text = CleanHtml(GetResponse(sb.ToString()));
}
}
}

private string GetResponse(string msg)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append(msg);
sb.Append("\r\n");
sb.Append("\r\n");

sb.Append("Mail Server: ");
sb.Append(_mailServer);
if (_mailServerPort > 0) { sb.Append(":" + _mailServerPort.ToString()); }
sb.Append("\r\n");

if (!string.IsNullOrEmpty(_username))
{
sb.Append("Logon Username: ");
sb.Append(_username);
sb.Append("\r\n");
}

sb.Append("Enable SSL: ");
sb.Append(chkEnableSsl.Checked.ToString());
sb.Append("\r\n");
sb.Append("\r\n");

sb.Append("To Address: ");
sb.Append(_toAddress);
sb.Append("\r\n");

sb.Append("From Address: ");
sb.Append(_fromAddress);
sb.Append("\r\n");

sb.Append("Subject: ");
sb.Append(_subject);
sb.Append("\r\n");

sb.Append("Body: ");
sb.Append(_body);
sb.Append("\r\n");

return sb.ToString();
}

public enum ConvertHtml
{
GtLt = 1,
SpecialSingleCharacters = 2,
CrLfToBr = 4,
BrToCrLf = 8,

ForHtmlEmail = 6,
ForWeb = 7
}

public static string CleanHtml(string original)
{
return CleanHtml(original, ConvertHtml.ForWeb);
}

public static string CleanHtml(string original, ConvertHtml convertFormat)
{
System.Text.StringBuilder cleaned = new System.Text.StringBuilder();
cleaned.Append(original);

if ((convertFormat & ConvertHtml.GtLt) == ConvertHtml.GtLt)
{
cleaned = cleaned.Replace("<", "&lt;");
cleaned = cleaned.Replace(">", "&gt;");
}

if ((convertFormat & ConvertHtml.SpecialSingleCharacters) == ConvertHtml.SpecialSingleCharacters)
{
cleaned = cleaned.Replace(" & ", " &amp; ");
cleaned = cleaned.Replace("\"", "&quot;");
}

if ((convertFormat & ConvertHtml.BrToCrLf) == ConvertHtml.BrToCrLf)
{
cleaned = cleaned.Replace("<br>", "\r\n");
}

if ((convertFormat & ConvertHtml.CrLfToBr) == ConvertHtml.CrLfToBr)
{
cleaned = cleaned.Replace("\r\n", "<br>");
cleaned = cleaned.Replace("\r", "<br>");
cleaned = cleaned.Replace("\n", "<br>");
}

return cleaned.ToString();
}
</script>
<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server" id="Head1">
<title>Test ASP.NET Email</title>
<style type="text/css">
body { font: 76% verdana; }
.tbl { border-collapse: collapse; }
.tbl td { border: solid 1px #ccc; padding: 5px; }
.tb { width: 300px; }
</style>
</head>

<body>
<form id="form1" runat="server">
<div>
<h1>Test ASP.NET Email</h1>
<p><asp:label id="lblResponse" runat="server" forecolor="Red"></asp:label></p>
<table>
<tr>
<td>Mail Server*</td>
<td><asp:textbox id="txtMailServer" runat="server" CssClass="tb"></asp:textbox><asp:requiredfieldvalidator id="rfvMailServer" runat="server" errormessage="required" controltovalidate="txtMailServer" Display="Dynamic"></asp:requiredfieldvalidator></td>
</tr>
<tr>
<td>Mail Server Port</td>
<td><asp:textbox id="txtMailServerPort" runat="server" CssClass="tb"></asp:textbox></td>
</tr>
<tr>
<td>Logon Username</td>
<td><asp:TextBox runat="server" ID="txtUsername" CssClass="tb"></asp:TextBox></td>
</tr>
<tr>
<td>Logon Password</td>
<td><asp:TextBox runat="server" ID="txtPassword" TextMode="Password" CssClass="tb"></asp:TextBox></td>
</tr>
<tr>
<td></td>
<td><asp:CheckBox runat="server" ID="chkEnableSsl" Text="Enable SSL" /></td>
</tr>
<tr>
<td colspan="2">&nbsp;</td>
</tr>

<tr>
<td>Mail To*</td>
<td><asp:textbox id="txtMailTo" runat="server" CssClass="tb"></asp:textbox><asp:requiredfieldvalidator id="rfvMailTo" runat="server" errormessage="required" controltovalidate="txtMailTo" Display="Dynamic"></asp:requiredfieldvalidator></td></tr>
<tr>
<td>Mail From*</td>
<td><asp:textbox id="txtMailFrom" runat="server" CssClass="tb"></asp:textbox><asp:requiredfieldvalidator id="rfvMailFrom" runat="server" errormessage="required" controltovalidate="txtMailFrom" Display="Dynamic"></asp:requiredfieldvalidator></td></tr>
<tr>
<td>Subject*</td>
<td><asp:textbox id="txtSubject" runat="server" CssClass="tb">Test Message</asp:textbox><asp:requiredfieldvalidator id="rfvSubject" runat="server" errormessage="required" controltovalidate="txtSubject" Display="Dynamic"></asp:requiredfieldvalidator></td></tr>
<tr>
<td>Body*</td>
<td><asp:textbox id="txtBody" runat="server" textmode="MultiLine" rows="6" CssClass="tb">This is a test message.</asp:textbox><asp:requiredfieldvalidator id="rfvBody" runat="server" errormessage="required" controltovalidate="txtBody" Display="Dynamic"></asp:requiredfieldvalidator></td></tr>
<tr>
<td colspan="2">&nbsp;</td></tr>
<tr>
<td></td>
<td><asp:button id="btnSubmit" runat="server" text="Send" onclick="btnSubmit_Click"></asp:button></td></tr>
</table>
</div>
</form>
</body>
</html>

Jul 8 2009

WordPress Default (Kubrick) Template Reference

In modifying the default “Kubrick” theme for WordPress, I didn’t find a concise reference for all the files in the theme directory, so I put one together:

WIDE (SINGLE) COLUMN PAGES
404.php            wide-column standard "Not Found" error page
archives.php        wide-column archives listing page, by month and by category
comments-popup.php    full-page used for when the option to have comments area popup in a new window (not turned on by default) (http://codex.wordpress.org/FAQ_Working_with_WordPress#Can_I_have_popup_comments.3F)
image.php        wide-column page used for viewing a "linked-to" image resource (supercedes generic attachement.php)
links.php        wide-column links (bookmarks) listing page (ignores page content if chosed as the template to use in the admin section)
single.php        wide-column page used to display a single post with comments area

NARROW (TWO) COLUMN PAGES
archive.php        narrow-column archive view page, shows filtered archive view (ex: by month or category)
index.php        narrow-column root template file, used for everything if other page templates are not present
page.php        narrow-column page used for "pages" created in the admin section
search.php        narrow-column page used to display search results

INCLUDES
comments.php        used for inserting comments area and functionality into pages, present in image.php, index.php, single.php
footer.php        global footer (includes closing tags started in header.php)
header.php        global header (includes opening tags closed in footer.php)
searchform.php        optional include that will be used for search form template, used in sidebar and on search.php
sidebar.php        global right-side column, includes search form and list-based navigation elements

OTHER
functions.php        optional global PHP functions automatically loaded by WordPress if present

This is probably out there somewhere already, but hopefully this will come in handy for someone else as well.