عنوان:

‫معرفی DNTBreadCrumb


نویسنده: وحید نصیری
تاریخ: ۱۳۹۵/۰۱/۰۱ ۸:۵
آدرس: www.dntips.ir
سال نو مبارک! با آرزوی بهترین‌ها برای تمام همراهان سایت.

فرصتی پیدا شد تا قالب سایت، با بوت استرپ 3 انطباق داده شود و در این بین یکی از کمبودهایی که احساس می‌شد، نبود bread crumb و مشخص نبودن عمق صفحه‌ی جاری مورد مطالعه، در قسمت‌های مختلف سایت بود:


پس از بررسی نمونه‌های bread crumbs موجود، مشکلی که اکثر آن‌ها داشتند یا استفاده از سشن جهت تشکیل لیست آیتم‌ها (سشن در سایت جاری غیرفعال است) و یا بیش از اندازه پیچیده بودن آن‌ها بود. به همین جهت یک نمونه‌ی ساده‌تر و سبک‌تر تهیه شد که در ذیل نحوه‌ی نصب و استفاده‌ی آن‌را بررسی خواهیم کرد.


نصب DNTBreadCrumb

برای نصب این bread crumb مبتنی بر بوت استرپ 3، تنها کافی است دستور ذیل را در کنسول پاورشل نیوگت صادر کنید:
 PM> install-package DNTBreadCrumb


تنظیمات اولیه‌ی DNTBreadCrumb

پس از نصب، علاوه بر فایل اسمبلی DNTBreadCrumb، فایل جدید Views\Shared\_BreadCrumb.cshtml نیز به پروژه‌ی شما اضافه می‌شود. این فایل، لیست نهایی آیتم‌های تنظیم شده‌ی توسط اکشن متدها را به صورت یک bread crumb رندر می‌کند. مزیت کار کردن با فایل‌های cshtml (بجای HTML Helperها)، امکان سفارشی سازی نهایی آن‌ها توسط استفاده کننده‌است.
بنابراین برای نمایش لیست bread crumb تنها کافی است یک سطر ذیل را به فایل layout برنامه اضافه کنید:
 @{Html.RenderPartial("_BreadCrumb");}


طراحی یک bread crumb سه سطحی

اگر به فایل Views\Shared\_BreadCrumb.cshtml مراجعه کنید، مشاهده خواهید کرد که سطح اول bread crumb یا همان نمایش Home، به صورت پیش فرض قرار داده شده‌است و در اینجا اگر می‌خواهید نام دیگری را بجای Home (مثلا خانه) تنظیم کنید، به سادگی قابل انجام است.
دو سطح بعدی یک bread crumb، نام کنترلر و سپس نام اکشن متد خواهند بود:
    [BreadCrumb(Title = "News Root", UseDefaultRouteUrl = true, RemoveAllDefaultRouteValues = true,
        Order = 0, GlyphIcon = "glyphicon glyphicon-link")]
    public class NewsController : Controller
    {
        [BreadCrumb(Title = "Main index", Order = 1)]
        public ActionResult Index(string id)
        {
            if (!string.IsNullOrWhiteSpace(id))
            {
                this.SetCurrentBreadCrumbTitle(id);
            }

            return View();
        }
در این مثال، از ویژگی جدید BreadCrumb بر روی کنترلر و سپس یک اکشن متد مدنظر، استفاده شده‌است.
کار با تنظیم Title یا همان عناوینی که در لینک‌های bread crumb ظاهر می‌شوند، شروع خواهد شد. سپس اگر علاقمند بودید، می‌توانید یک گلیف آیکن را نیز در اینجا مشخص کنید تا در bread crumb نهایی، کنار عنوان مشخص شده، رندر شود.
هر ویژگی BreadCrumb دارای خاصیت Url نیز هست. اما با توجه به اینکه می‌توان از طریق مسیریابی‌های پیش فرض، این آدرس‌ها را پیدا کرد، نیازی به ذکر آن‌ها نیست. برای مثال تنظیم UseDefaultRouteUrl در BreadCrumb یک کنترلر، مقدار Url مرتبط با آن‌را به صورت خودکار از مسیریابی پیش فرض آن دریافت و محاسبه می‌کند. خاصیت RemoveAllDefaultRouteValues به این معنا است که اگر در اکشن متد index، مقدار id تنظیم شده بود، نیازی نیست تا حین تشکیل آدرس ریشه‌ی کنترلر، این مقدار نیز لحاظ شود.

و ... همین مقدار تنظیم، برای کار با این سیستم کافی است.


موارد تکمیلی

- نیاز است عنوان bread crumb به صورت پویا تنظیم شود. چگونه این‌کار را انجام دهیم؟
برای اینکار می‌توانید از متد الحاقی SetCurrentBreadCrumbTitle استفاده کنید. برای نمونه تصویر ابتدای مطلب نیز به همین ترتیب تولید شده‌است. در اینجا عنوان پویای مقاله، توسط متد SetCurrentBreadCrumbTitle بجای Title پیش فرض bread crumb تنظیم شده‌است.

- چگونه می‌توان بیش از سه سطح را تعریف کرد؟
برای تعریف بیش از سه سطح پیش فرض خانه/کنترلر/اکشن متد، می‌توانید از متد الحاقی AddBreadCrumb استفاده کنید:
        [BreadCrumb(Title = "News Archive", Order = 2)]
        public ActionResult Archive(int? id)
        {
            if (id != null)
            {
                this.SetCurrentBreadCrumbTitle(string.Format("News item {0}", id.Value));
                this.AddBreadCrumb(new BreadCrumb
                {
                    Title = "News Archive",
                    Order = 1,
                    Url = Url.Action("Archive", "News", routeValues: new { id = "" })
                });
            }

            return View();
        }
در اینجا به هر تعدادی که نیاز است می‌توانید AddBreadCrumb را انجام دهید. فقط باید دقت داشت که تقدم و تاخر این‌ها بر اساس خاصیت Order انجام می‌شود. بنابراین اگر پس از رندر شدن مشاهده کردید که لینک تولیدی، پس یا پیش از آیتم مدنظر شما است، فقط کافی است Orderها را صحیح مقدار دهی کنید.


سورس کامل مثال‌های مطرح شده‌ی در این مطلب را در پروژه‌ی MVCBreadCrumbTest می‌توانید مشاهده کنید.

نظرات

  • احمد نواصری در ۱۳۹۵/۰۱/۰۶ ۱۳:۲۶
    با تشکر از مطلب خوبتون. آقای نصیری آیا میتوان با استفاده از امکانات reflection، اقدام به تولید breadCrumb کرد؟ مثلا کل کنترلرها و اکشن‌ها را بدست بیاریم و بعد از اون با استفاده از ViewBag.Title عنوان رو به اونها انتصاب داد؟ و در آخر اونها رو در layOut رندر کنیم؟
    • وحید نصیری در ۱۳۹۵/۰۱/۰۶ ۱۴:۷
      تقدم و تاخر، مسایل چندسطحی، اضافه کردن لینک‌هایی که الزاما در سطح کنترلر جاری نیستند و همچنین گلیف‌آیکن‌های سفارشی را به این شکل از دست خواهید داد.
  • وحید نصیری در ۱۳۹۵/۰۷/۰۷ ۱۲:۳۷
    جهت اطلاع
    این کتابخانه برای ASP.NET Core نیز بازنویسی شد: DNTBreadCrumb.Core  
  • مهدی ملائیان در ۱۳۹۶/۱۰/۱۱ ۱۳:۱۰
    باتشکر. امکان تنظیم آدرس برای خصوصیتی که به کنترلر اعمال می‌شود وجود دارد؟ من کنترلر مورد استفادم در Area هست. البته مقدار URL رو در خصوصیت اعمالی بر روی Controller تنظیم کردم؛ ولی باز هم موفق نشدم به صفحه مورد نظر هدایت کنم.
    • وحید نصیری در ۱۳۹۶/۱۰/۱۱ ۱۳:۳۳
      اگر یکی از UseDefaultRouteUrl و یا UseCurrentRouteUrl به true تنظیم شده باشند، از خاصیت Url استفاده نخواهد شد.
      • مهدی ملائیان در ۱۳۹۶/۱۰/۱۱ ۱۷:۲۷
        بله مشکل حل شد. در حالت هایی مثل اکشن create که 2 حالت post و get داریم ، من خصوصیت‌  عمق مطلب رو برای متد Get اعمال می‌کنم و در هنگام فراخوانی متد get همه چیز بدرستی اجرا می‌شود  ولی زمانی که فرم رو به سمت سرور ارسال می‌کنم و خطای اعتبار سنجی رخ می‌دهد بخش bread crumb   بطور کامل حذف می‌شود. آیا باید این خصوصیت به هر دو متد اعمال شود ؟
        • وحید نصیری در ۱۳۹۶/۱۰/۱۱ ۲۰:۳۰
          به هر قسمتی که در نهایت Get دارد و خروجی را ارائه می‌دهد، باید اعمال شود.
  • اختیاری در ۱۳۹۷/۰۳/۰۳ ۶:۲۵
    من از هلپر FriendlyUrlHelper جهت تولید Url مناسب استفاده می‌کنم و در کنارش از BreadCrumb. در url من آدرس https://localhost:44355/product/2/productname رو دارم و در بخش breadcrumb هم آدرس home/category/procut/2/productname رو دارم که کلمه categoty و کلمه productname متغیر و کلمه product ثابت هستند. با این قطعه کد:
     this.AddBreadCrumb(new BreadCrumb
                    {
                        Title = categoryname.Title,
                        Order = 1,
                        Url = Url.Action("Index", "ProductList", new { catid = categoryname.Id }),
                        ForceUrl = true
                    });
    
                    this.AddBreadCrumb(new BreadCrumb
                    {
                        Title = result.Title,
                        Order = 2,
                        ForceUrl = false
                    });
    آیا امکان تغیر عنوان breadcrumb به فرمت زیر هست؟ ( که کلمه category و productname از کنترلر پر بشن )
    home/category/productname
    • وحید نصیری در ۱۳۹۷/۰۳/۰۳ ۹:۱۵
      الان با این تعاریفی که انجام دادید چه مشکلی هست؟
      • اختیاری در ۱۳۹۷/۰۳/۰۳ ۱۳:۳
        ادرس در breadcrumb  به صورت  home/category/procut/2/productname است که می‌خوام به home/category/productname  تبدیل بشه اما ظاهرا یا تعاریف من مشکل داره یا بخش url friendly ایجاد اخلال می‌کنه .
        راهنمایی خواستم که بدونم برای تولید ادرس دوم چه تعریفی باید ست کنم ؟
        • وحید نصیری در ۱۳۹۷/۰۳/۰۳ ۱۳:۱۷
          شما بجای استفاده از url friendly یا هر افزونه‌ی ثالثی، فقط باید مسیریابی متناظری را تعریف کنید، تا این آدرس‌ها به صورت استاندارد و قابل استفاده‌ی در تمام قسمت‌های برنامه تولید شوند. MVC نیازی به افزونه‌های url friendly ندارد؛ چیزی شبیه به این و یا مثال «سازگار کردن لینک‌های قدیمی یک سایت با ساختار جدید آن در ASP.NET MVC»:
          routes.MapRoute(
              "category_route", // Route name
              "MyControllerName/{category}/{productname}", // URL with parameters
              new { controller = "MyControllerName", action = "MyActionName",
                       category = UrlParameter.Optional, productname = UrlParameter.Optional, area = "" }
          );
  • محمد احمدی نیا در ۱۳۹۷/۰۷/۱۰ ۱۵:۷
    اگر بخواهیم نام کنترلر جاری از BreadCrumb حذف شود، یعنی فقط نام کنترلر پیش فرض HomeController یا Area جاری و بعد از آن نام Action نمایش داده شود. به چه روشی انجام می‌پذیرد؟
    • وحید نصیری در ۱۳۹۷/۰۷/۱۰ ۱۵:۲۷
      اگر ویژگی BreadCrumb به قسمتی اعمال شود، در لیست نهایی وجود خواهد داشت و یا برعکس اگر بر روی قسمتی اعمال نشود، در لیست نهایی ذکر نمی‌شود.
  • لاله ت در ۱۳۹۸/۰۱/۰۶ ۱۵:۱۹
    سلام؛ اگر بخواهیم بالای یک صفحه چند بردکرامب رو قرار بدیم چطور میتونیم از این پکیج استفاده کنیم ؟
    بعضی از محصولات در چند دسته بندی هستند و  در بالای این محصول تمام مسیرها می‌تونه نوشته بشه .مانند مثال زیر :
    Home/Cat1/product1
    Home/Cat2/Product1
    Home/Cat3/Product1 
    • وحید نصیری در ۱۳۹۸/۰۱/۰۶ ۱۷:۳۹
      متد  this.AddBreadCrumb را در صفحه‌ی جاری جستجو کنید.