Last active
August 29, 2015 14:21
-
-
Save Implem/30e486bc60954a1b1551 to your computer and use it in GitHub Desktop.
c#のラムダ式などを使って閉じ忘れのないhtmlビルダーを作りたい ref: http://qiita.com/Implem/items/a141e57607edcebd5ff2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Linq; | |
using System.Text; | |
namespace Implem.Sample | |
{ | |
public static class Extensions | |
{ | |
// 連続Append用拡張メソッド | |
public static void Append(this StringBuilder stringBuilder, params string[] strings) | |
{ | |
strings.ForEach(str => stringBuilder.Append(str)); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace Implem.Sample | |
{ | |
public class HtmlBuilder | |
{ | |
private StringBuilder html = new StringBuilder(); | |
private List<string> closeTagCollection = new List<string>(); | |
private enum AttributePropertyTypes : int | |
{ | |
Name = 0, | |
Value = 1 | |
} | |
// タグ追加 | |
public HtmlBuilder Append(string tag, int closeLevel = 0, params string[] attributes) | |
{ | |
html.Append("<", tag); | |
attributes | |
.Select((o, i) => new { Value = o, PropertyType = (AttributePropertyTypes)(i % 2) }) | |
.ForEach(data => | |
{ | |
switch (data.PropertyType) | |
{ | |
case AttributePropertyTypes.Name: | |
// 偶数はプロパティ名 | |
html.Append(" " + data.Value); break; | |
case AttributePropertyTypes.Value: | |
// 奇数は値 | |
html.Append("=\"", data.Value, "\"");break; | |
} | |
}); | |
if (closeLevel > 0) | |
{ | |
html.Append(" />"); | |
if (closeLevel >= 2) | |
{ | |
AppendCloseTagCollection(closeLevel - 1); | |
} | |
} | |
else | |
{ | |
html.Append(">"); | |
closeTagCollection.Insert(0, "</" + tag + ">"); | |
} | |
return this; | |
} | |
// 属性付きタグ追加の間に別の処理 | |
public HtmlBuilder Append(string tag, string[] attributes, Action action) | |
{ | |
Append(tag, attributes: attributes); | |
action(); | |
AppendClose(); | |
return this; | |
} | |
// タグ追加の間に別の処理 | |
public HtmlBuilder Append(string tag, Action action) | |
{ | |
Append(tag, attributes: new string[] { }); | |
action(); | |
AppendClose(); | |
return this; | |
} | |
// id, class属性付きタグ追加の間に別の処理 | |
public HtmlBuilder Append(string tag, string controlId, string cssClass, Action action) | |
{ | |
Append(tag, attributes: new string[] { "id", controlId, "class", cssClass }); | |
action(); | |
AppendClose(); | |
return this; | |
} | |
// class属性付きタグ追加の間に別の処理 | |
public HtmlBuilder Append(string tag, string cssClass, Action action) | |
{ | |
Append(tag, attributes: new string[] { "class", cssClass }); | |
action(); | |
AppendClose(); | |
return this; | |
} | |
// テキスト追加とクローズ | |
public HtmlBuilder AppendText(string str, int closeLevel = 0) | |
{ | |
html.Append(str); | |
AppendCloseTagCollection(closeLevel); | |
return this; | |
} | |
// クローズ | |
public HtmlBuilder AppendClose(int closeLevel = 1) | |
{ | |
AppendCloseTagCollection(closeLevel); | |
return this; | |
} | |
// 全部クローズ | |
public HtmlBuilder AppendCloseAll() | |
{ | |
AppendCloseTagCollection(-1); | |
return this; | |
} | |
// 全部クローズしてHtml出力 | |
public override string ToString() | |
{ | |
// html出力前に閉じ忘れしないよう全部クローズ | |
AppendCloseTagCollection(); | |
return html.ToString(); | |
} | |
// クローズ処理 | |
private void AppendCloseTagCollection(int closeLevel = -1) | |
{ | |
if (closeTagCollection.Count() > 0) | |
{ | |
if (closeLevel == -1) | |
{ | |
// -1 : 全部閉じる | |
html.Append(string.Join("", closeTagCollection)); | |
closeTagCollection.Clear(); | |
} | |
else | |
{ | |
// n : n個閉じる | |
html.Append(string.Join(string.Empty, closeTagCollection.Take(closeLevel))); | |
closeTagCollection = closeTagCollection.Skip(closeLevel).ToList<string>(); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div><p class="content">hoge</p></div> | |
<div><a id="hoge" class="fuga" href="http://qiita.com/">foo</a></div> | |
<table><tr><th>1-1</th><th>1-2</th></tr><tr><td>2-1</td><td>2-2</td></tr></table> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
namespace Implem.Sample | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// 使用例1 | |
var htmlBuilder1 = new HtmlBuilder(); | |
Console.WriteLine( | |
htmlBuilder1.Append("div", () => | |
htmlBuilder1.Append("p", "content", () => | |
htmlBuilder1.AppendText("hoge")))); | |
// 使用例2 | |
var htmlBuilder2 = new HtmlBuilder(); | |
Console.WriteLine( | |
htmlBuilder2.Append("div", () => | |
htmlBuilder2.Append("a", new string[] | |
{ | |
"id", "hoge", | |
"class", "fuga", | |
"href", "http://qiita.com/" | |
}, | |
() => | |
htmlBuilder2.AppendText("foo")))); | |
// 使用例3 | |
var htmlBuilder3 = new HtmlBuilder(); | |
Console.WriteLine( | |
htmlBuilder3.Append("table", () => | |
Enumerable.Range(1, 2).ForEach(x => | |
htmlBuilder3.Append("tr", () => | |
Enumerable.Range(1, 2).ForEach(y => | |
{ | |
if (x == 1) | |
{ | |
htmlBuilder3.Append("th", () => | |
htmlBuilder3.AppendText(x + "-" + y)); | |
} | |
else | |
{ | |
htmlBuilder3.Append("td", () => | |
htmlBuilder3.AppendText(x + "-" + y)); | |
} | |
}))))); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment