This approach does not parse html like php, razer, but generates markup on the fly. That affects very well on performance. Does this approach have a place to be? After all, if you write everything in this, for me, so comfortable style, as far as I understand you can fly to StackOverflow
Page Code
public AdminLoginPageWrong() { Add( new HeadTag { new MetaTag(new NameAtt("description"), new ContentAtt("Вход в админ панель")), new MetaTag(new NameAtt("author"), new ContentAtt("Alay")), new MetaTag(new NameAtt("viewport"), new ContentAtt("width=device-width, initial-scale=1.0")), new TitleTag{new Svt("Вход в админ панель") }, //new BaseTag(new HrefAtt("http://localhost:8080/")) }, new BodyTag(new ClassAtt("gray-bg")) { new DivTag(new ClassAtt("middle-box text-center loginscreen animated fadeInDown")) { new DivTag { new DivTag().Add(new H2Tag(new ClassAtt("logo-name")).Add(new Svt("WGS"))) }, new H3Tag().Add(new Svt("Добро пожаловать на форму авторизации администратора WGS")), new PTag { new Svt("WGS - Лучшая CMS полностью написаная на C# без использования .net asp."), new BrTag(), new Svt("Скорость реакции в десятки раз превосходит остальные веб серверы и сам asp"), }, new PTag().Add(new Svt("Авторизуйтесь, чтобы пороникнуться возможностями WGS")), new DivTag(new ClassAtt("alert alert-danger")) { new Svt("Пользователь или пароль не верны.") }, new FormTag(new ClassAtt("mt"), new RoleAtt(RoleAtt.Mark.Form), new MethodAtt(MethodAtt.Mark.Post), new ActionAtt("adminAuth")) { new DivTag(_classFormGroup) { new InputTag(new NameAtt("login"), new InputTypeAtt(InputTypeAtt.Mark.Email), _classFormControl, new PlaceHolderAtt("Login"), new RequiredAtt()) }, new DivTag(_classFormGroup) { new InputTag(new NameAtt("pass"), new InputTypeAtt(InputTypeAtt.Mark.Password), _classFormControl, new PlaceHolderAtt("Pwd"), new RequiredAtt()) }, new ButtonTag(new InputTypeAtt(InputTypeAtt.Mark.Submit), new ClassAtt("btn btn-primary block full-width mb")).Add(new Svt("Вход")) }, new PTag(new ClassAtt("mt")).Add(new SmalTag().Add(new Svt("WGS - World Global Sharper based on Bootstrap 3 and .net framework 4.6.1 © 2017"))) }, new LinkTag(new RelAtt("stylesheet"), new HrefAtt("admin/css/bootstrap.min.css")), new LinkTag(new RelAtt("stylesheet"), new HrefAtt("admin/font-awesome/css/font-awesome.min.css")), new LinkTag(new RelAtt("stylesheet"), new HrefAtt("admin/css/animate.css")), new LinkTag(new RelAtt("stylesheet"), new HrefAtt("admin/css/style.css")), new ScriptTag(new SrcAtt("admin/js/jquery-3.1.1.min.js")), new ScriptTag(new SrcAtt("admin/js/bootstrap.min.js"), new AsyncAtt()) } ); Render(null); } Abstract tag code
private bool _isRendered; private string _data; private readonly string _name; private readonly List<AbstractAtt> _attributes; private readonly List<IHtmlRendable> _innerTags; private readonly bool _needToBeClosed; private readonly bool _hasAttributes; private bool _hasInnerTags; public delegate IHtmlRendable[] EntryFunc(); protected AbstractTag(string name, bool needToBeClosed, params AbstractAtt[] attributes) { _name = name; _needToBeClosed = needToBeClosed; _attributes = new List<AbstractAtt>(attributes); _innerTags = new List<IHtmlRendable>(); if (attributes.Length > 0) _hasAttributes = true; } public IHtmlRendable Add(params IHtmlRendable[] tags) { if (!_needToBeClosed) return this;//Если тег не закрывающийся, то и контент в него добавить нельзя. _innerTags.AddRange(tags); _hasInnerTags = true; return this; } public IHtmlRendable Add(EntryFunc func) { if (!_needToBeClosed) return this;//Если тег не закрывающийся, то и контент в него добавить нельзя. _innerTags.AddRange(func()); _hasInnerTags = true; return this; } public void Render(StringBuilder sb) { if (!_isRendered) { var enterPoint = sb.Length; sb.Append("<").Append(_name); if (_hasAttributes) { sb.Append(" "); foreach (var att in _attributes) { att.Render(sb); sb.Append(" "); } sb.Remove(sb.Length - 1, 1); //Удаляем последний пробел } if (!_needToBeClosed && !_hasInnerTags) { sb.Append("/>"); } else { sb.Append(">"); foreach (var tag in _innerTags) tag.Render(sb); sb.Append("</").Append(_name).Append(">"); } var exitPoint = sb.Length; var length = exitPoint - enterPoint; _data = sb.ToString(enterPoint, length); _isRendered = true; } else sb.Append(_data); } public IEnumerator<IHtmlRendable> GetEnumerator() => _innerTags.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => _innerTags.GetEnumerator(); Abstract attribute
protected AbstractAtt(string name, string value) { _name = name; _value = value; _hasValue = true; } protected AbstractAtt(string name) { _name = name; } public void Render(StringBuilder sb) { if (_hasValue) sb.Append(_name).Append("=\"").Append(_value).Append("\""); else sb.Append(_name); } 