受欢迎的博客标签

NopCommerce 4.x - Microdata(only product)

Published

 

step 1. Enable Microdata in Admin

src/Libraries/Nop.Core/Domain/Seo/SeoSettings.cs

using System.Collections.Generic;
using Nop.Core.Configuration;

namespace Nop.Core.Domain.Seo
{
    /// <summary>
    /// SEO settings
    /// </summary>
    public class SeoSettings : ISettings
    {
     /// <summary>
        /// A value indicating whether Microdata tags should be generated
        /// </summary>
        public bool MicrodataEnabled { get; set; }
    }
}

step 2: only product

src/Presentation/Nop.Web/Views/Product/_Microdata.cshtml

<!--Microdata-->
<div @if (ViewData.ContainsKey("isAccessoryOrSparePartFor")) { <text>itemprop="isAccessoryOrSparePartFor"</text> } itemscope itemtype="http://schema.org/Product">
    <meta itemprop="name" content="@Model.Name"/>
    <meta itemprop="sku" content="@Model.Sku"/>
    <meta itemprop="gtin" content="@Model.Gtin"/>
    <meta itemprop="mpn" content="@Model.ManufacturerPartNumber"/>
    <meta itemprop="description" content="@Model.ShortDescription"/>
    <meta itemprop="image" content="@Model.DefaultPictureModel.ImageUrl"/>
    @foreach (var manufacturer in Model.ProductManufacturers)
    {
        <meta itemprop="brand" content="@manufacturer.Name"/>
    }
    @if (@Model.ProductReviewOverview.TotalReviews > 0)
    {
        <div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
            @{
                var ratingPercent = 0;
                if (Model.ProductReviewOverview.TotalReviews != 0)
                {
                    ratingPercent = ((Model.ProductReviewOverview.RatingSum * 100) / Model.ProductReviewOverview.TotalReviews) / 5;
                }
                var ratingValue = ratingPercent / (decimal)20;
            }
            <meta itemprop="ratingValue" content="@ratingValue.ToString("0.0", new CultureInfo("en-US"))"/>
            <meta itemprop="reviewCount" content="@Model.ProductReviewOverview.TotalReviews"/>
        </div>
    }    
    <div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
        <meta itemprop="url" content="@Url.RouteUrl("Product", new { SeName = Model.SeName }, webHelper.CurrentRequestProtocol).ToLowerInvariant()"/>
        <meta itemprop="price" content="@Model.ProductPrice.PriceValue.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)"/>
        <meta itemprop="priceCurrency" content="@Model.ProductPrice.CurrencyCode"/>
        <meta itemprop="priceValidUntil" content="@Model.AvailableEndDate"/>
        @if (Model.ManageInventoryMethod == ManageInventoryMethod.ManageStock || Model.ManageInventoryMethod == ManageInventoryMethod.ManageStockByAttributes)
        {
            @if (Model.StockAvailability.Contains(@T("Products.Availability.InStock").ToString(), StringComparison.InvariantCultureIgnoreCase) || 
                Model.StockAvailability.Contains(@T("Products.Availability.InStockWithQuantity").ToString(), StringComparison.InvariantCultureIgnoreCase))
            {
                <meta itemprop="availability" content="http://schema.org/InStock"/>
            }
            else
            {
                <meta itemprop="availability" content="http://schema.org/OutOfStock"/>
            }
        }        
    </div>
    <div itemprop="review" itemscope itemtype="http://schema.org/Review">
        <meta itemprop="author" content="ALL"/>
        <meta itemprop="url" content="@Url.RouteUrl("ProductReviews", new { productId = Model.ProductReviewOverview.ProductId })"/>
    </div>
    @foreach (var product in Model.AssociatedProducts)
    {
        var dataAccociatedType = new ViewDataDictionary(ViewData);
        dataAccociatedType.Add("isAccessoryOrSparePartFor", "true");
        @await Html.PartialAsync("_Microdata", product, dataAccociatedType)        
    }
</div>