Стилизация контента интернет-магазина
174ASP.NET --- Интернет магазин --- Стилизация контента
Исходный код проектаМы построили значительную часть инфраструктуры интернет-магазина, и приложение действительно готово к сборке воедино, но пока не было уделено какое-то внимание его внешнему виду. Хотя данное руководство не посвящено веб-дизайну или CSS, внешний вид приложения GameStore настолько примитивен, что это умаляет его технические достоинства. В этой статье мы постараемся исправить ситуацию.
Мы собираемся реализовать классическую компоновку, содержащую два столбца и верхний заголовок. В качестве примера вы можете посмотреть схожую компоновку реального интернет-магазина мебели Mebelas - «Удобная мебель для детского сада», который содержит схожий макет с нашим магазином.
Установка пакета Bootstrap
Для предоставления стилей CSS, которые будут применены к приложению, мы планируем воспользоваться пакетом Bootstrap. Чтобы установить пакет Bootstrap, выберите пункт Package Manager --> Package Manager Console в меню Tools среды Visual Studio. Откроется окно командной строки NuGet. Введите следующую команду и нажмите клавишу <Enter>:
Install-Package -version 3.0.0 bootstrap -projectname GameStore.WebUI
Это базовая команда NuGet для добавления пакета Bootstrap с дополнительным аргументом projectname, который обеспечивает добавление инструментом NuGet файлов в правильный проект. Пакет Bootstrap будет использоваться без описания деталей предлагаемых им функциональных CSS- и JS-средств.
Применение стилей Bootstrap к компоновке
При создании представления List.cshtml для контроллера Game было предложено отметить флажок Use a layout page (Использовать страницу компоновки), но оставить пустым поле, в котором указывается компоновка. Это обеспечивает использование компоновки, заданной в файле Views/_ViewStart.cshtml, который Visual Studio создает автоматически наряду с представлением. Содержимое файла запуска представления показано в примере ниже:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
Значение свойства Layout указывает, что представления будут использовать в качестве компоновки файл Views/Shared/_Layout.cshtml, если только не будет явно задана альтернатива. Содержимое файла _Layout.cshtml было сброшено ранее, чтобы удалить то, что добавил шаблон Visual Studio, а в примере ниже можно видеть, что мы вернулись к этому файлу с целью добавления CSS-файла Bootstrap и применения ряда определенных в нем стилей CSS:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="~/Content/bootstrap.css" rel="stylesheet" />
<link href="~/Content/bootstrap-theme.css" rel="stylesheet" />
<title>@ViewBag.Title</title>
</head>
<body>
<div class="navbar navbar-inverse" role="navigation">
<a class="navbar-brand" href="#">GameStore - магазин компьютерных игр</a>
</div>
<div class="row panel">
<div id="categories" class="col-xs-3">
Сюда добавим контент позже
</div>
<div class="col-xs-8">
@RenderBody()
</div>
</div>
</body>
</html>
В компоновку были добавлены файлы bootstrap.css и bootstrap-theme.css с использованием элементов link и применены разнообразные классы Bootstrap. Необходимо также изменить файл List.cshtml, как показано в примере ниже:
@using GameStore.WebUI.Models
@using GameStore.WebUI.HtmlHelpers
@model GamesListViewModel
@{
ViewBag.Title = "Товары";
}
@foreach (var p in @Model.Games)
{
<div class="well">
<h3>
<strong>@p.Name</strong>
<span class="pull-right label label-primary">@p.Price.ToString("# руб")</span>
</h3>
<span class="lead">@p.Description</span>
</div>
}
<div class="btn-group pull-right">
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x }))
</div>
Запустив приложение, вы увидите, что его внешний вид улучшился - во всяком случае, немного:

Проблема со стилизацией элементов
Элементы HTML, генерируемые приложением MVC, поступают из разнообразных источников (статическое содержимое, выражения Razor, вспомогательные методы HTML и т.д.), поэтому классы стилей оказываются разбросанными по всему проекту. Если такое положение вещей начинает вызывать беспокойство, то в этом вы не одиноки. Смешивание стилей CSS с генерацией элементов - не особо удачная затея, которая противоречит принципу разделения несвязанной функциональности, присущему архитектурному шаблону MVC.
Ситуацию можно улучшить за счет назначения классов, отличных от Bootstrap, элементам на основе их роли в приложении и последующего использования библиотеки, подобной jQuery или LESS, для отображения ваших специальных классов на классы Bootstrap.
Чтобы упростить приложение, мы примем подход с внедрением классов Bootstrap повсеместно в приложении, даже с учетом того, что это затруднит изменение стилей в будущем. В реальном проекте это бы не делалось, но в рассматриваемом примере приложения такой подход вполне уместен, т.к. фаза сопровождения для него не планируется.
Создание частичного представления
В качестве завершающего штриха в этой статье мы проведем рефакторинг приложения, чтобы упростить представление List.cshtml. Для этого будет создано частичное представление (partial view), являющееся фрагментом содержимого, которое можно внедрить в другое представление подобно шаблону. Частичные представления содержатся внутри собственных файлов и могут многократно использоваться различными представлениями, что способствует уменьшению дублирования, особенно в случае, когда требуется визуализировать однородные данные в нескольких местах приложения.
Чтобы добавить частичное представление, щелкните правой кнопкой мыши на папке /Views/Shared в проекте GameStore.WebUI и выберите в контекстном меню пункт Add --> View (Добавить --> Представление). В поле View Name (Имя представления) введите GameSummary, в списке Template (Шаблон) укажите Empty (Пустой), в раскрывающемся списке Model Class (Класс модели) выберите Game и отметьте флажок Create As A Partial View (Создать как частичное представление), как показано на рисунке ниже:

Щелкните на кнопке Add и Visual Studio создаст файл частичного представления по имени Views/Shared/GameSummary.cshtml. Частичное представление похоже на обычное представление за исключением того, что оно порождает фрагмент HTML-разметки, а не полный HTML-документ. Если открыть представление GameSummary, легко заметить, что оно содержит только директиву @model, в которой установлен класс модели предметной области по имени Game.
Внесите в файл GameSummary.cshtml изменения, показанные в примере ниже:
@model GameStore.Domain.Entities.Game
<div class="well">
<h3>
<strong>@Model.Name</strong>
<span class="pull-right label label-primary">@Model.Price.ToString("# руб")</span>
</h3>
<span class="lead">@Model.Description</span>
</div>
Теперь необходимо модифицировать файл Views/Games/List.cshtml, чтобы в нем применялось частичное представление. Изменение можно видеть в примере ниже:
@using GameStore.WebUI.Models
@using GameStore.WebUI.HtmlHelpers
@model GamesListViewModel
@{
ViewBag.Title = "Товары";
}
@foreach (var p in @Model.Games)
{
@Html.Partial("GameSummary", p)
}
<div class="btn-group pull-right">
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x }))
</div>
Мы взяли код разметки, который ранее размещался в цикле foreach в представлении List.cshtml, и переместили его в новое частичное представление. Вызов частичного представления осуществляется с применением вспомогательного метода Html.Partial(). В качестве параметров ему передаются имя представления и объект модели представления. Подобного рода переход на частичное представление является рекомендуемым приемом, и он не изменяет внешнего вида приложения.