سلام دوستان این مطلب در اصل برمیگرده به razor engine و هم در mvc core و هم در razor pages ، حتی mvc 5 (تا حدودی) کاربرد دارد.
در razor pages و همینطور mvc برای یک قالب اصلی که بقیه صفحاتمان از آن پیروی کنند باید کد های html در فایل با نام قراردادی _Layout.cshtml قرار بدیهم و برای اینکه کد های صفحاتی که از این قالب پیروق میکنند را درون آن قرار دهیم باید از
@RenderBody()
استفاده کنیم (که اصلا این بخش کد اجباری اگر نگذارید با error مواجه میشوید). توسط کد بالا ، محتوای تمام صفحات پیروی کرده در این قسمت (RenderBody) قرار میگیرند. ولی ممکنه در صفحه ای بخواهیم قسمتی به قالب اصلی (_Layout.cshtml) اضافه کنم یا سفارشی کنیم .موتور razor این قابلیت برای ما فراهم میکند که بخش های مختلفی را به قالب اصلی اضافه کنیم و در صورت نیاز در صفحات پیرو (منظورم صفحاتی که از قالب اصلی پیروی میکنند) آن ها را ویرایش کنیم. برای این کار میتوانیم از کد زیردر قالب اصلی استفاده کنیم:
RenderSection("NameOfSection", RequiredOrNot)
این کد 2 پارامتر میگیرد 1 نام 2 اجباری بودن یا خیر. پارامتر اول که نام قسمت (Section) هست که برای صدا زدن در صفحات پیرو استفاده میشود. پارامتر دوم یک مقدار true/false هست که میگوید آیا این قسمت باید در تمامی صفحات پیرو استفاده شود یا خیر اگر این پارامتر را true یا آن را خالی بگذارید (مقدار پیشفرض true هست) در صورتی که در صفحات پیرو این قسمت را صدا نزنید با خطا مواجه می شوید.پس اگر ture باشد حتی اگر خالی هم باشد باید حتما صدا زده شود.ولی اگر false باشد اختیاری میباشد و اگر صدا زده نشود هم مشکلی ندارد.
حالا فرض کنید من در قالب اصلی یک section اختیاری با نام Title نوشته ام:
@RenderSection("Title", false)
و در صفحه پیرو آن را صدا زدم و کد زیر رو درونش صدا زدم:
@section Title { <h2 class="title">My Favorite Recipes</h2> <a asp-page="/Admin/AddEditRecipe" class="add-recipe btn btn-primary">Add Recipe</a> }
حالا وقتی وارد صفحه بشوم این قسمت بدرستی کار میکند و مشکلی ندارد (نحوه صدا زدن و استفاده از آن گفتم). حالا فرض کنید من یک صفحه پیرو دیگری دارم که نیاز به یک title ساده دارد و نیازی به سفارشی کردن و کد های قبلی ندارد، اگر ما قسمت Title صدا نزنیم جای آن بخش خالی می ماند و قالب ما بهم میریزد. برای حل این مشکل میشود دوباره قسمت title صدا بزنیم و یک title ساده در آن قرار دهیم مثلا
@section Title { <h2 class="title">Simple Title</h2> }
ولی اگر تعداد بیشتری بصفحع پیرو داشته باشیم چی ؟ برای قشنگی کار بهتر یک مقدار پیشفرض قرار بدهیم تا اگر قسمت title صدا نزدیم مقدار پیشفرض آن نمایش داده شود.(این همه داستانسرای کردم که بگم می شه برای section ها مقدار پیشفرض هم قرار داد!) برای این کار لازمه در قالب اصلی کدی با فرمت کد زیر را بنویسیم:
@if (IsSectionDefined("Title")) { @RenderSection("Title", false) } else { <h2 class="title">Default Title</h2> }
با دستور IsSectionDefied("SectionNAME") میگیم اگر همچین قسمتی تعریف شده بود که مقدار تعریف شده را قرار بده اگر نه بجاش مقدار پیشفرض قرار بده.
این که در صفحات پیرو همش یک متن ثابت قرار بدهیم زیاد قشنگ نیست آیا میشه مقدار پیش فرض را پویا کرد ؟ باید بگم بله !
برای قرار دادن مقداری از صفحه پیرو به قالب اصلی باید از ViewData استفاده کرد
برای مثال ما میخواهیم مقدار پیشفرض درقالب اصلی رو برای صفحه پیرو پویا کنیم و بجای متن ثابت پراپرتی name مدلمان در صفحه پیرو را نمایش دهیم.
برای اینکار در صفحه پیرو یک ViewData با نام Title و مقدار دلخواه می نویسیم:
ViewData["Title"] = recipe.Name;
و در قالب اصلی همین ویو دیتا را میگیرم:
@if (IsSectionDefined("Title")) { @RenderSection("Title", false) } else { <h2 class="title">@ViewData["Title"]< /h2> }
از این طریق ما از صفحه پیرو مقداری را در قالب اصلی پاس دادیم ! بهمین سادگی
یک نکته که یادم رفت بگویم اینکه برای استفاده از قالب اصلی در صفحه پیرو باید در بالای صفحه این کد را اضافه کنیم:
@ { Layout = "_Layout"; //این کد پایین برای ارسال ویودیتا به قالب اصلی به جای مقدار پیشفرض متن ثابت ViewData["Title"] = recipe.Name; }
از حالا به بعد اگر section title صدا نزنید به جای آن recipe.Name در آن قرار میگیرد .