I have code like this. Is there a way to make it easier to write and maintain? Using C# .NET 3.5.
string header(string title)
{
StringWriter s = new Stri
You could use some third party open-source libraries to generated strong typed verified (X)HTML, such as CityLizard Framework or Sharp DOM.
Update For example
html
[head
[title["Title of the page"]]
[meta_(
content: "text/html;charset=UTF-8",
http_equiv: "Content-Type")
]
[link_(href: "css/style.css", rel: "stylesheet", type: "text/css")]
[script_(type: "text/javascript", src: "/JavaScript/jquery-1.4.2.min.js")]
]
[body
[div
[h1["Test Form to Test"]]
[form_(action: "post", id: "Form1")
[div
[label["Parameter"]]
[input_(type: "text", value: "Enter value")]
[input_(type: "submit", value: "Submit!")]
]
]
[div
[p["Textual description of the footer"]]
[a_(href: "http://google.com/")
[span["You can find us here"]]
]
[div["Another nested container"]]
]
]
];
I wrote these classes which served me well. It's simple yet pragmatic.
public class HtmlAttribute
{
public string Name { get; set; }
public string Value { get; set; }
public HtmlAttribute(string name) : this(name, null) { }
public HtmlAttribute(
string name,
string @value)
{
this.Name = name;
this.Value = @value;
}
public override string ToString()
{
if (string.IsNullOrEmpty(this.Value))
return this.Name;
if (this.Value.Contains('"'))
return string.Format("{0}='{1}'", this.Name, this.Value);
return string.Format("{0}=\"{1}\"", this.Name, this.Value);
}
}
public class HtmlElement
{
protected List<HtmlAttribute> Attributes { get; set; }
protected List<object> Childs { get; set; }
public string Name { get; set; }
protected HtmlElement Parent { get; set; }
public HtmlElement() : this(null) { }
public HtmlElement(string name, params object[] childs)
{
this.Name = name;
this.Attributes = new List<HtmlAttribute>();
this.Childs = new List<object>();
if (childs != null && childs.Length > 0)
{
foreach (var c in childs)
{
Add(c);
}
}
}
public void Add(object o)
{
var a = o as HtmlAttribute;
if (a != null)
this.Attributes.Add(a);
else
{
var h = o as HtmlElement;
if (h != null && !string.IsNullOrEmpty(this.Name))
{
h.Parent = this;
this.Childs.Add(h);
}
else
this.Childs.Add(o);
}
}
public override string ToString()
{
var result = new StringBuilder();
if (!string.IsNullOrEmpty(this.Name))
{
result.Append(string.Format("<{0}", this.Name));
if (this.Attributes.Count > 0)
{
result.Append(" ");
foreach (var attr in this.Attributes)
{
result.Append(attr.ToString());
result.Append(" ");
}
result = new StringBuilder(result.ToString().TrimEnd(' '));
}
if (this.Childs.Count == 0)
{
result.Append(" />");
}
else
{
result.AppendLine(">");
foreach (var c in this.Childs)
{
var cParts = c.ToString().Split('\n');
foreach (var p in cParts)
{
result.AppendLine(string.Format("{0}", p));
}
}
result.Append(string.Format("</{0}>", this.Name));
}
}
else
{
foreach (var c in this.Childs)
{
var cParts = c.ToString().Split('\n');
foreach (var p in cParts)
{
result.AppendLine(string.Format("{0}", p));
}
}
}
var head = GetHeading(this);
var ps = result.ToString().Split('\n');
return string.Join("\r\n", (from p in ps select head + p.TrimEnd('\r')).ToArray());
}
string GetHeading(HtmlElement h)
{
if (h.Parent != null)
return " ";
else
return string.Empty;
}
}
I know you asked about C#, but if you're willing to use any .Net language then I highly recommend Visual Basic for this exact problem. Visual Basic has a feature called XML Literals that will allow you to write code like this.
Module Module1
Sub Main()
Dim myTitle = "Hello HTML"
Dim myHTML = <html>
<head>
<title><%= myTitle %></title>
</head>
<body>
<h1>Welcome</h1>
<table>
<tr><th>ID</th><th>Name</th></tr>
<tr><td>1</td><td>CouldBeAVariable</td></tr>
</table>
</body>
</html>
Console.WriteLine(myHTML)
End Sub
End Module
This allows you to write straight HTML with expression holes in the old ASP style and makes your code super readable. Unfortunately this feature is not in C#, but you could write a single module in VB and add it as a reference to your C# project.
Writing in Visual Studio also allows proper indentation for most XML Literals and expression wholes. Indentation for the expression holes is better in VS2010.
It really depends what you are going for, and specifically, what kind of performance you really need to offer.
I've seen admirable solutions for strongly-typed HTML development (complete control models, be it ASP.NET Web Controls, or similar to it) that just add amazing complexity to a project. In other situations, it is perfect.
In order of preference in the C# world,
You can use ASP.NET to generate your HTML outside the context of web pages. Here's an article that shows how it can be done.
return string.Format(@"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01//EN"" ""http://www.w3.org/TR/html4/strict.dtd"">
<html>
<title>{0}</title>
<link rel=""stylesheet"" type=""text/css"" href=""style.css"">
</head>
<body>
", title);