モノレールとnvelocityでネストされたviewcomponentsを作成する方法は?
-
03-10-2019 - |
質問
私たちが維持しているウェブサイトでメニューを更新するように求められました。このウェブサイトでは、キャッスルウィンダーモノレールとnVelocityをテンプレートとして使用しています。メニューは現在、Li要素をレンダリングするViewComponentのカスタムメイドのサブクラスを使用してレンダリングされています。現時点では、1つの(水平)レベルしかないため、現在のメカニズムは問題ありません。
既存のメニューの一部にドロップダウンメニューを追加するように求められました。モノレールとnvelocityを見たのはこれが初めてなので、少し迷っています。
現在存在するもの:
<ul>
#component(MenuComponent with "title=Home" "hover=autoselect" "link=/")
#component(MenuComponent with "title=Videos" "hover=autoselect")
#component(MenuComponent with "title=VPS" "hover=autoselect" "link=/vps")
#component(MenuComponent with "title=Add-Ons" "hover=autoselect" "link=/addons")
#component(MenuComponent with "title=Hosting" "hover=autoselect" "link=/hosting")
#component(MenuComponent with "title=Support" "hover=autoselect" "link=/support")
#component(MenuComponent with "title=News" "hover=autoselect" "link=/news")
#component(MenuComponent with "title=Contact Us" "hover=autoselect" "link=/contact-us")
</ul>
ネストされたメヌコンポネント(または新しいサブメヌクコンポーネント)を使用することは可能ですか?
<ul>
#component(MenuComponent with "title=Home" "hover=autoselect" "link=/")
#component(MenuComponent with "title=Videos" "hover=autoselect")
#blockcomponent(MenuComponent with "title=VPS" "hover=autoselect" "link=/vps")
#component(SubMenuComponent with "title="Plans" "hover=autoselect" "link=/vps/plans")
#component(SubMenuComponent with "title="Operating Systems" "hover=autoselect" "link=/vps/os")
#component(SubMenuComponent with "title="Supported Applications" "hover=autoselect" "link=/vps/apps")
#end
#component(MenuComponent with "title=Add-Ons" "hover=autoselect" "link=/addons")
#component(MenuComponent with "title=Hosting" "hover=autoselect" "link=/hosting")
#component(MenuComponent with "title=Support" "hover=autoselect" "link=/support")
#component(MenuComponent with "title=News" "hover=autoselect" "link=/news")
#component(MenuComponent with "title=Contact Us" "hover=autoselect" "link=/contact-us")
</ul>
Menucomponentでオーバーライドされたレンダリング方法内にサブメニュー(ULおよびLI要素)を描画する必要があるため、ネストされたViewComponentデリバティブを使用することは機能しない場合があります。可能であれば、メニューを作成するための基本的に宣言的な方法を保持したいと思います。
編集:Context.RenderBody()を使用してネストされたViewComponent Derivitivesをレンダリングできますが、親の前でレンダリングされています。サブメニューの低下は、親と同じ出力に何らかの形で接続する必要があると思いますか?
解決
私の元のレンダリング方法のように見えました
public override void Render()
{
var buffer = new StringBuilder();
var extraClass = _hoverState == MenuHoverState.Selected ? "class=\"Selected\"" : "";
// Menu Item Start
buffer.Append("<li><a href=\"" + ComponentParams["link"] + "\"" + extraClass + ">");
// Menu Text
buffer.Append(ComponentParams["title"]);
// Menu Item End
buffer.Append("</a></li>");
RenderText(buffer.ToString());
}
Context.Writerに接続する必要がありました:
public override void Render()
{
var buffer = new StringBuilder();
var extraClass = _hoverState == MenuHoverState.Selected ? "class=\"Selected\"" : "";
// Menu Item Start
buffer.Append("<li><a href=\"" + ComponentParams["link"] + "\"" + extraClass + ">");
// Menu Text
buffer.Append(ComponentParams["title"]);
// Menu Item End
buffer.Append("</a><ul class=\"subMenu\" style=\"display:none;\">");
Context.Writer(buffer.ToString());
Context.RenderBody(Context.Writer);
Contet.Writer("</ul></li>");
}
他のヒント
context.renderbody()を使用して、ネストされたviewcomponent derivitivesをレンダリングできます
レンダリング方法でオーバーライドすると、次のようなものを使用できます
RenderView("header");
RenderBody();
RenderView("footer");
そして、コンポーネントを使用するテンプレートからいくつかの部分をオーバーライドできるようにレンダリングを使用することが有用かもしれません
if(HasSection("header")){
RenderSection("header");
} else {
RenderView("header");
}
また、コンテキストをitterateして変更することも可能です。
for(var item in this.SubItems){
PropertyBag["item"] = item;
if(HasSection("item")){
RenderSection("item");
} else {
RenderView("item");
}
}
これらすべてのソリューションは派手ですが、私は一般的に、目的の特定のビューモデル(hierarchicalmenuviewmodelなど)をパラメーターとして取得するビューコンポーネントを持つことを好み、テンプレートロジックをシンプルに保ちます。
少なくとも単純なコントロールの場合(それは、ビューエンジンに応じてマクロまたは部分的にのみに値する場合があります)。
最終的に、上記のViewComponentの概念は、より多くのカスタマイズが必要なコントロールを行うときに、まだ素晴らしいことです。アドバイスは、レンダリングロジックの文書化またはシンプルに保つことです(<= 10行でレンダリング方法)