refactoring

This commit is contained in:
Hamid Reza Mohammadi 2026-07-18 13:51:04 +03:30
parent 17938fb2bb
commit 68315aa4aa
11 changed files with 159 additions and 402 deletions

View File

@ -13,65 +13,7 @@
}
else
{
<div id="hdr2" class="clearfix">
<h1><a href="/" title="گنجور"><img src="/image/gdapk.png" alt="گنجور" /></a></h1>
<div class="actionbox">
<form action="/search" method="get" id="searchform">
<input type="text" name="s" id="s" class="inputText" value="" placeholder="جستجو" />
<input type="hidden" name="es" id="es" value="1" />
<select name="author" id="author" onchange="onSelectedPoetChanged()">
@{
if (Model.PoetId != 0)
{
<option value="0">در آثار همهٔ سخنوران</option>
}
else
{
<option value="0" selected>در آثار همهٔ سخنوران</option>
}
if (Model.Poets != null)
{
foreach (RMuseum.Models.Ganjoor.ViewModels.GanjoorPoetViewModel poet in Model.Poets)
{
if (poet.Id == Model.PoetId)
{
<option value="@poet.Id" selected>@poet.Nickname</option>
}
else
{
<option value="@poet.Id">@poet.Nickname</option>
}
}
}
}
</select>
@{
if (Model.Poet != null)
{
<select name="cat" id="cat" style="width:150px">
<option value="0" selected>در همهٔ بخشها</option>
@{
foreach (var gran in Model.Poet.Cat.Ancestors)
{
<option value="@gran.Id">@gran.Title</option>
}
<option value="@Model.Poet.Cat.Id">@Model.Poet.Cat.Title</option>
foreach (var child in Model.Poet.Cat.Children)
{
<option value="@child.Id">@child.Title</option>
}
}
</select>
}
}
<input type="submit" value="بیاب" />
</form>
</div><!-- .actionbox -->
</div>
<partial name="_SearchHeaderPartial" model="@(new _SearchHeaderPartialModel(){ Poets = Model.Poets, SelectedPoetId = Model.PoetId, CurrentCategory = Model.Poet?.Cat })" />
<!-- #hdr2 -->
@ -117,7 +59,6 @@ else
</div>
<script src="/js/vaabd.js?version=10"></script>
@if (ViewData["TrackingScript"] != null && !string.IsNullOrEmpty(ViewData["TrackingScript"].ToString()))
{

View File

@ -9,30 +9,7 @@
}
else
{
<div id="hdr2" class="clearfix">
<h1><a href="/" title="گنجور"><img src="/image/gdapk.png" alt="گنجور" /></a></h1>
<div class="actionbox">
<form action="/search" method="get" id="searchform">
<input type="text" name="s" id="s" class="inputText" value="" placeholder="جستجو" />
<input type="hidden" name="es" id="es" value="1" />
<select name="author" id="author" onchange="onSelectedPoetChanged()">
@{
<option value="0">در آثار همهٔ سخنوران</option>
if (Model.Poets != null)
{
foreach (RMuseum.Models.Ganjoor.ViewModels.GanjoorPoetViewModel poet in Model.Poets)
{
<option value="@poet.Id">@poet.Nickname</option>
}
}
}
</select>
<input type="submit" value="بیاب" />
</form>
</div><!-- .actionbox -->
</div>
<partial name="_SearchHeaderPartial" model="@(new _SearchHeaderPartialModel(){ Poets = Model.Poets })" />
<!-- #hdr2 -->
@ -91,7 +68,6 @@ else
</div>
<script src="/js/vaabd.js?version=10"></script>
@if (ViewData["TrackingScript"] != null && !string.IsNullOrEmpty(ViewData["TrackingScript"].ToString()))
{

View File

@ -113,7 +113,6 @@ else if (Model.ReadOnlyMode)
</p>
</div>
}
<script src="/js/vaabd.js?version=10"></script>
@if (Model.IsPoemPage)
{
if (Model.GanjoorPage != null && Model.GanjoorPage.Poem.Recitations.Length > 0)
@ -201,66 +200,12 @@ else if (Model.ReadOnlyMode)
{
return;
}
<div id="hdr2" class="clearfix">
<h1><a href="/" title="گنجور"><img src="/image/gdapk.png" alt="گنجور"></a></h1>
<div class="actionbox">
<form action="/search" method="get" id="searchform">
<input type="text" name="s" id="s" class="inputText" value="" placeholder="جستجو">
<input type="hidden" name="es" id="es" value="1">
<select name="author" id="author" onchange="onSelectedPoetChanged()">
@{
if (Model.GanjoorPage != null && Model.GanjoorPage.PoetOrCat != null)
{
<option value="0">در آثار همهٔ سخنوران</option>
}
else
{
<option value="0" selected>در آثار همهٔ سخنوران</option>
}
if (Model.Poets != null)
{
foreach (RMuseum.Models.Ganjoor.ViewModels.GanjoorPoetViewModel poet in Model.Poets)
{
if (Model.GanjoorPage.PoetOrCat != null && poet.Id == Model.GanjoorPage.PoetOrCat.Poet.Id)
{
<option value="@poet.Id" selected>@Html.Raw(poet.Nickname)</option>
}
else
{
<option value="@poet.Id">@Html.Raw(poet.Nickname)</option>
}
}
}
}
</select>
@{
if (!Model.IsPoetPage && Model.GanjoorPage != null && Model.GanjoorPage.PoetOrCat != null)
{
<select name="cat" id="cat">
<option value="0">در همهٔ بخشها</option>
@{
foreach (var gran in Model.GanjoorPage.PoetOrCat.Cat.Ancestors)
{
<option value="@Html.Raw(gran.Id)">@Html.Raw(gran.Title)</option>
}
<option value="@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Id)" selected>@Html.Raw(Model.GanjoorPage.PoetOrCat.Cat.Title)</option>
foreach (var child in Model.GanjoorPage.PoetOrCat.Cat.Children)
{
<option value="@Html.Raw(child.Id)">@Html.Raw(child.Title)</option>
}
}
</select>
}
}
<input type="submit" value="بیاب">
</form>
</div><!-- .actionbox -->
</div><!-- #hdr2 -->
<partial name="_SearchHeaderPartial" model="@(new _SearchHeaderPartialModel(){
Poets = Model.Poets,
SelectedPoetId = Model.GanjoorPage?.PoetOrCat?.Poet?.Id ?? 0,
CurrentCategory = (!Model.IsPoetPage && Model.GanjoorPage?.PoetOrCat != null) ? Model.GanjoorPage.PoetOrCat.Cat : null,
WideCategorySelect = false
})" /><!-- #hdr2 -->
<div id="fa">

View File

@ -10,65 +10,7 @@
}
else
{
<div id="hdr2" class="clearfix">
<h1><a href="/" title="گنجور"><img src="/image/gdapk.png" alt="گنجور" /></a></h1>
<div class="actionbox">
<form action="/search" method="get" id="searchform">
<input type="text" name="s" id="s" class="inputText" value="" placeholder="جستجو" />
<input type="hidden" name="es" id="es" value="1" />
<select name="author" id="author" onchange="onSelectedPoetChanged()">
@{
if (Model.PoetId != 0)
{
<option value="0">در آثار همهٔ سخنوران</option>
}
else
{
<option value="0" selected>در آثار همهٔ سخنوران</option>
}
if (Model.Poets != null)
{
foreach (RMuseum.Models.Ganjoor.ViewModels.GanjoorPoetViewModel poet in Model.Poets)
{
if (poet.Id == Model.PoetId)
{
<option value="@poet.Id" selected>@poet.Nickname</option>
}
else
{
<option value="@poet.Id">@poet.Nickname</option>
}
}
}
}
</select>
@{
if (Model.Poet != null)
{
<select name="cat" id="cat" style="width:150px">
<option value="0" selected>در همهٔ بخشها</option>
@{
foreach (var gran in Model.Poet.Cat.Ancestors)
{
<option value="@gran.Id">@gran.Title</option>
}
<option value="@Model.Poet.Cat.Id">@Model.Poet.Cat.Title</option>
foreach (var child in Model.Poet.Cat.Children)
{
<option value="@child.Id">@child.Title</option>
}
}
</select>
}
}
<input type="submit" value="بیاب" />
</form>
</div><!-- .actionbox -->
</div>
<partial name="_SearchHeaderPartial" model="@(new _SearchHeaderPartialModel(){ Poets = Model.Poets, SelectedPoetId = Model.PoetId, CurrentCategory = Model.Poet?.Cat })" />
<!-- #hdr2 -->
@ -300,7 +242,6 @@ else
</div>
<script src="/js/vaabd.js?version=10"></script>
@if (ViewData["TrackingScript"] != null && !string.IsNullOrEmpty(ViewData["TrackingScript"].ToString()))
{

View File

@ -40,7 +40,6 @@ else if (Model.ReadOnlyMode)
</p>
</div>
}
<script src="/js/vaabd.js?version=10"></script>
@if (!string.IsNullOrEmpty(Model.LastError))
{

View File

@ -9,45 +9,7 @@
}
else
{
<div id="hdr2" class="clearfix">
<h1><a href="/" title="گنجور"><img src="/image/gdapk.png" alt="گنجور" /></a></h1>
<div class="actionbox">
<form action="/search" method="get" id="searchform">
<input type="text" name="s" id="s" class="inputText" value="" placeholder="جستجو" />
<input type="hidden" name="es" id="es" value="1" />
<select name="author" id="author" onchange="onSelectedPoetChanged()">
@{
if (Model.Poet != null)
{
<option value="0">در آثار همهٔ سخنوران</option>
}
else
{
<option value="0" selected>در آثار همهٔ سخنوران</option>
}
if (Model.Poets != null)
{
foreach (RMuseum.Models.Ganjoor.ViewModels.GanjoorPoetViewModel poet in Model.Poets)
{
if(Model.Poet != null && Model.Poet.Id == poet.Id)
{
<option value="@poet.Id" selected>@poet.Nickname</option>
}
else
{
<option value="@poet.Id">@poet.Nickname</option>
}
}
}
}
</select>
<input type="submit" value="بیاب" />
</form>
</div><!-- .actionbox -->
</div>
<partial name="_SearchHeaderPartial" model="@(new _SearchHeaderPartialModel(){ Poets = Model.Poets, SelectedPoetId = Model.Poet?.Id ?? 0 })" />
<!-- #hdr2 -->
@ -165,7 +127,6 @@ else
</div>
<script src="/js/vaabd.js?version=10"></script>
@if (ViewData["TrackingScript"] != null && !string.IsNullOrEmpty(ViewData["TrackingScript"].ToString()))
{

View File

@ -14,100 +14,7 @@
}
else
{
<div id="hdr2" class="clearfix">
<h1><a href="/" title="گنجور"><img src="/image/gdapk.png" alt="گنجور" /></a></h1>
<div class="actionbox">
<form action="/search" method="get" id="searchform">
<input type="text" name="s" id="s" class="inputText" value="@Model.Query" placeholder="جستجو" />
@if (Model.ExactSearch)
{
<input type="hidden" name="es" id="es" value="1" />
}
<select name="author" id="author" onchange="onSelectedPoetChanged()">
@{
if (Model.PoetId != 0)
{
<option value="0">در آثار همهٔ سخنوران</option>
}
else
{
<option value="0" selected>در آثار همهٔ سخنوران</option>
}
if (Model.Poets != null)
{
foreach (RMuseum.Models.Ganjoor.ViewModels.GanjoorPoetViewModel poet in Model.Poets)
{
if (poet.Id == Model.PoetId)
{
<option value="@poet.Id" selected>@poet.Nickname</option>
}
else
{
<option value="@poet.Id">@poet.Nickname</option>
}
}
}
}
</select>
@{
if (Model.Poet != null)
{
<select name="cat" id="cat" style="width:150px">
@if (Model.CatId == 0)
{
<option value="0" selected>در همهٔ بخشها</option>
}
else
{
<option value="0">در همهٔ بخشها</option>
}
@{
foreach (var gran in Model.Poet.Cat.Ancestors)
{
@if (Model.CatId == gran.Id)
{
<option value="@gran.Id" selected>@gran.Title</option>
}
else
{
<option value="@gran.Id">@gran.Title</option>
}
}
@if (Model.CatId == Model.Poet.Cat.Id)
{
<option value="@Model.Poet.Cat.Id" selected>@Model.Poet.Cat.Title</option>
}
else
{
<option value="@Model.Poet.Cat.Id">@Model.Poet.Cat.Title</option>
}
foreach (var child in Model.Poet.Cat.Children)
{
@if (Model.CatId == child.Id)
{
<option value="@child.Id" selected>@child.Title</option>
}
else
{
<option value="@child.Id">@child.Title</option>
}
}
}
</select>
}
}
<input type="submit" value="بیاب" />
</form>
</div><!-- .actionbox -->
</div>
<partial name="_SearchHeaderPartial" model="@(new _SearchHeaderPartialModel(){ Poets = Model.Poets, SelectedPoetId = Model.PoetId, SearchQuery = Model.Query, ShowExactSearchHiddenField = Model.ExactSearch, CurrentCategory = Model.Poet?.Cat, SelectedCategoryId = Model.CatId })" />
<!-- #hdr2 -->
@ -247,7 +154,6 @@ else
</div>
<script src="/js/vaabd.js?version=10"></script>
@if (ViewData["TrackingScript"] != null && !string.IsNullOrEmpty(ViewData["TrackingScript"].ToString()))
{

View File

@ -17,6 +17,12 @@
// deliberately (or at least currently) skipped on error pages. A layout can't see each page's
// own LastError state, so centralizing this would make tracking fire on error pages that
// previously suppressed it. Each page keeps rendering its own TrackingScript block as before.
//
// vaabd.js WAS centralized below (confirmed byte-identical and unconditional across every main
// page). One minor, functionally-inert reordering: it used to render right before each page's
// own TrackingScript block; now it renders right after @RenderBody() finishes, which is after
// TrackingScript on any page that has one. The two scripts are unrelated (word-tooltip widget vs
// analytics), so this shouldn't matter, but flagging it since it's a real order change.
}
<!DOCTYPE html>
<html lang="fa-IR" dir="rtl">
@ -41,6 +47,8 @@
<body>
@RenderBody()
<script src="/js/vaabd.js?version=10"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@ -0,0 +1,92 @@
@model GanjooRazor.Pages._SearchHeaderPartialModel
<div id="hdr2" class="clearfix">
<h1><a href="/" title="گنجور"><img src="/image/gdapk.png" alt="گنجور" /></a></h1>
<div class="actionbox">
<form action="/search" method="get" id="searchform">
<input type="text" name="s" id="s" class="inputText" value="@Model.SearchQuery" placeholder="جستجو" />
@if (Model.ShowExactSearchHiddenField)
{
<input type="hidden" name="es" id="es" value="1" />
}
<select name="author" id="author" onchange="onSelectedPoetChanged()">
@{
if (Model.SelectedPoetId != 0)
{
<option value="0">در آثار همهٔ سخنوران</option>
}
else
{
<option value="0" selected>در آثار همهٔ سخنوران</option>
}
if (Model.Poets != null)
{
foreach (var poet in Model.Poets)
{
if (poet.Id == Model.SelectedPoetId)
{
<option value="@poet.Id" selected>@Html.Raw(poet.Nickname)</option>
}
else
{
<option value="@poet.Id">@Html.Raw(poet.Nickname)</option>
}
}
}
}
</select>
@if (Model.CurrentCategory != null)
{
<select name="cat" id="cat" style="@(Model.WideCategorySelect ? "width:150px" : "")">
@{
var effectiveSelectedCatId = Model.SelectedCategoryId ?? Model.CurrentCategory.Id;
if (effectiveSelectedCatId == 0)
{
<option value="0" selected>در همهٔ بخشها</option>
}
else
{
<option value="0">در همهٔ بخشها</option>
}
foreach (var gran in Model.CurrentCategory.Ancestors)
{
if (effectiveSelectedCatId == gran.Id)
{
<option value="@gran.Id" selected>@Html.Raw(gran.Title)</option>
}
else
{
<option value="@gran.Id">@Html.Raw(gran.Title)</option>
}
}
if (effectiveSelectedCatId == Model.CurrentCategory.Id)
{
<option value="@Model.CurrentCategory.Id" selected>@Html.Raw(Model.CurrentCategory.Title)</option>
}
else
{
<option value="@Model.CurrentCategory.Id">@Html.Raw(Model.CurrentCategory.Title)</option>
}
foreach (var child in Model.CurrentCategory.Children)
{
if (effectiveSelectedCatId == child.Id)
{
<option value="@child.Id" selected>@Html.Raw(child.Title)</option>
}
else
{
<option value="@child.Id">@Html.Raw(child.Title)</option>
}
}
}
</select>
}
<input type="submit" value="بیاب" />
</form>
</div><!-- .actionbox -->
</div><!-- #hdr2 -->

View File

@ -0,0 +1,47 @@
using RMuseum.Models.Ganjoor.ViewModels;
using System.Collections.Generic;
namespace GanjooRazor.Pages
{
/// <summary>
/// Model for the shared #hdr2 search-form + poet/category dropdown header used by GanjoorPage,
/// Search, Simi, Quotes, Hashieha, Contribs, and FAQ. Before this, each page carried its own
/// copy of this block - identical in 3 cases (Simi/Hashieha/Contribs), and varying in specific,
/// explainable ways in the other 4 (see each page's own model-construction code for the mapping).
/// </summary>
public class _SearchHeaderPartialModel
{
public List<GanjoorPoetViewModel> Poets { get; set; }
/// <summary>0 marks the "all poets" option as selected.</summary>
public int SelectedPoetId { get; set; }
public string SearchQuery { get; set; } = "";
/// <summary>
/// Whether the hidden "es" (exact search) field renders at all. Its value is always "1" when
/// shown - only Search.cshtml ties this to a real toggle; every other page always shows it
/// unconditionally.
/// </summary>
public bool ShowExactSearchHiddenField { get; set; } = true;
/// <summary>Null (default) hides the category dropdown entirely.</summary>
public GanjoorCatViewModel CurrentCategory { get; set; }
/// <summary>
/// Null means "always mark CurrentCategory as selected" (GanjoorPage/Simi/Hashieha/Contribs
/// behavior - these never let you pick a different category than the one you're already
/// looking at). A value means "mark whichever ancestor/current/child matches this id instead"
/// (Search's behavior, where the category filter is independent of what you're looking at).
/// </summary>
public int? SelectedCategoryId { get; set; }
/// <summary>
/// GanjoorPage's category select is missing the inline width style the other 6 pages have -
/// preserved here rather than silently unified, since it may be an intentional visual
/// difference (or CSS already handles #cat's width and the inline style is redundant on the
/// other pages - not something to guess at).
/// </summary>
public bool WideCategorySelect { get; set; } = true;
}
}

View File

@ -54,65 +54,7 @@
}
else
{
<div id="hdr2" class="clearfix">
<h1><a href="/" title="گنجور"><img src="/image/gdapk.png" alt="گنجور" /></a></h1>
<div class="actionbox">
<form action="/search" method="get" id="searchform">
<input type="text" name="s" id="s" class="inputText" value="" placeholder="جستجو" />
<input type="hidden" name="es" id="es" value="1" />
<select name="author" id="author" onchange="onSelectedPoetChanged()">
@{
if (Model.PoetId != 0)
{
<option value="0">در آثار همهٔ سخنوران</option>
}
else
{
<option value="0" selected>در آثار همهٔ سخنوران</option>
}
if (Model.Poets != null)
{
foreach (RMuseum.Models.Ganjoor.ViewModels.GanjoorPoetViewModel poet in Model.Poets)
{
if (poet.Id == Model.PoetId)
{
<option value="@poet.Id" selected>@poet.Nickname</option>
}
else
{
<option value="@poet.Id">@poet.Nickname</option>
}
}
}
}
</select>
@{
if (Model.Poet != null)
{
<select name="cat" id="cat" style="width:150px">
<option value="0" selected>در همهٔ بخشها</option>
@{
foreach (var gran in Model.Poet.Cat.Ancestors)
{
<option value="@gran.Id">@gran.Title</option>
}
<option value="@Model.Poet.Cat.Id">@Model.Poet.Cat.Title</option>
foreach (var child in Model.Poet.Cat.Children)
{
<option value="@child.Id">@child.Title</option>
}
}
</select>
}
}
<input type="submit" value="بیاب" />
</form>
</div><!-- .actionbox -->
</div>
<partial name="_SearchHeaderPartial" model="@(new _SearchHeaderPartialModel(){ Poets = Model.Poets, SelectedPoetId = Model.PoetId, CurrentCategory = Model.Poet?.Cat })" />
<!-- #hdr2 -->
@ -393,7 +335,6 @@
</div>
<script src="/js/vaabd.js?version=10"></script>
@if (ViewData["TrackingScript"] != null && !string.IsNullOrEmpty(ViewData["TrackingScript"].ToString()))
{