Автор: Сумит Харче
Эта статья была обновлена до версии 4 автором Mark Munyaka.
Узнайте, как создать простое, но невероятно быстрое приложение для блога с помощью Blazor WebAssembly, Tailwind CSS и Strapi. Вы будете использовать Strapi, ведущую безголовую CMS с открытым исходным кодом, для хранения ваших сообщений и Blazor для создания внешнего интерфейса.
Предпосылки
Прежде чем вы сможете перейти к этому контенту, вам необходимо иметь общее представление о следующем:
- Страпи — начнем здесь.
- Node.js
- Блейзор
- C#
- Шелл (Баш)
Должен быть установлен следующий софт:
- .NET SDK. Версия 6 на момент написания
- Узел v14.x.x или v16.x.x. Узел загрузки из раздела Загрузить | Страница Node.js. Я использовал Node v16.14.2.
- npm или yarn. npm поставляется с вашей установкой Node. Если вы предпочитаете пряжу, установите ее как пакет npm. Отметьте Установка | Пряжа.
Полный список требований, необходимых для запуска приложения Strapi, см. в разделе Требования к оборудованию и программному обеспечению.
Введение
Что такое Блазор?
Blazor — это веб-фреймворк от Microsoft, который позволяет создавать веб-приложения с использованием C# и HTML. Если вы разработчик, использующий C#, и хотите создать молниеносно быстрое веб-приложение, вам следует проверить Blazor.
Согласно документам Blazor:
Blazor — это бесплатная веб-инфраструктура с открытым исходным кодом, которая позволяет разработчикам создавать веб-приложения с использованием C# и HTML.
Blazor позволяет создавать интерактивные веб-интерфейсы с помощью C# вместо JavaScript. Приложения Blazor состоят из многократно используемых компонентов веб-интерфейса, реализованных с помощью C#, HTML и CSS.
И клиентский, и серверный код написаны на C#, что позволяет вам совместно использовать код и библиотеки. Blazor может запускать код C# на стороне клиента непосредственно в браузере с помощью WebAssembly. Поскольку это настоящая .NET, работающая на WebAssembly, вы можете повторно использовать код и библиотеки из серверных частей вашего приложения.
В этой статье вы будете использовать Blazor Web Assembly для создания клиентской части приложения блога.
Что такое Страпи?
Strapi — это ведущая безголовая CMS с открытым исходным кодом, основанная на Node.js для разработки и управления контентом с использованием Restful API и GraphQL.
С помощью Strapi мы можем быстрее формировать наш API и использовать контент через API, используя любой клиент HTTP RESTful или внешний интерфейс с поддержкой GraphQL.
Настройка серверной части
Шаг 1: Создание проекта Strapi
Откройте свой терминал и создайте пустой каталог проекта для хранения вашего проекта. Эта папка будет служить корневой папкой. Внешний и внутренний код будут храниться в подкаталогах. Я назову каталог своего проекта Purplerhino.
$ mkdir purplerhino
Измените каталог на каталог проекта Purplerhino.
$ cd purplerhino
Включите систему управления версиями для вашего проекта, инициализировав репозиторий git.
/purplerhino $ git init
Создайте приложение Strapi.
/purplerhino $ npx create-strapi-app backend --quickstart
Приведенная выше команда создаст новый проект Strapi в каталоге с именем backend
. Флаг quickstart
настраивает ваше приложение Strapi с базой данных SQLite.
После успешной установки приложение Strapi запускается автоматически. Откройте интерфейс Регистрация администратора Strapi в веб-браузере по адресу localhost:1337/admin. Создайте пользователя-администратора для своего приложения Strapi и нажмите Начать.
Шаг 2. Создайте коллекцию сообщений
Далее мы создадим тип контента, в котором будут храниться сведения о каждом сообщении.
Мы создадим тип контента с именем posts
, содержащий следующие поля: title
, content
, author
и image
.
- Нажмите Конструктор типов контента в левой части страницы.
- Выберите + Создать новый тип подборки в левой части страницы и введите Post в качестве отображаемого имени.
- Нажмите Продолжить, чтобы создать новую коллекцию Post.
Нам нужно заполнить коллекцию Post большим количеством данных записей. Этого можно добиться двумя способами: с помощью пользовательского интерфейса администратора и API, созданного Strapi.
Мы будем использовать пользовательский интерфейс администратора для создания сообщения.
- Нажмите Продолжить, после чего откроется другое окно для выбора полей для вашего Типа коллекции.
- Выберите
Text
и введитеtitle
в текстовом поле. - Нажмите на
+ Add another field
, выберитеRich Text
и назовите егоcontent
. - Нажмите на
+ Add another field
и выберите полеMedia
и назовите егоimage
. - Выберите
+ Add another field
еще раз, выберите полеText
и назовите егоauthor
. - После добавления всех необходимых полей нажмите ✓ Сохранить, чтобы сохранить коллекцию и дождаться перезапуска сервера Strapi.
- Нажмите Диспетчер контента в левой части панели инструментов. В разделе ТИПЫ СБОРНИКОВ выберите Опубликовать.
- Затем нажмите + Создать новую запись и добавьте несколько сообщений в свою коллекцию Сообщения. Нажмите Сохранить и ✓ Опубликовать для каждого добавляемого сообщения.
Шаг 3. Сделайте Strapi API общедоступным
После успешного создания коллекции Posts пришло время разрешить общий доступ к коллекции, потому что доступ будет запрещен, если мы попытаемся получить к ней доступ с помощью нашего общедоступного HTTP-клиента.
- Нажмите Настройки на боковой панели.
- В разделе ПЛАГИН ПОЛЬЗОВАТЕЛЕЙ И РАЗРЕШЕНИЙ нажмите Роли.
- На странице Роли нажмите Общедоступно.
- Прокрутите вниз до раздела Разрешения:
- Выберите Опубликовать и установите флажок Выбрать все. Это делает все конечные точки общедоступными по адресу localhost:1337/api/post.
- Нажмите ✓ Сохранить.
Шаг 4: Установите и включите плагин Transformer
Нам нужно будет преобразовать JSON из запроса API для работы с нашим интерфейсом Blazor. Для этого воспользуемся Трансформером от @ComfortablyCoding.
- Остановите сервер Strapi, нажав
Ctrl + C
на клавиатуре. - Установите Transformer в корневую папку вашего приложения Strapi.
/purplerhino/backend $ npm install strapi-plugin-transformer
- Создайте файл
plugins.js
в папкеconfig
для настройки вашего плагина.
/purplerhino/backend $ touch config/plugins.js
- Добавьте эту конфигурацию в
./config/plugins.js
.
module.exports = ({ env }) => ({
'transformer': {
enabled: true,
config: {
prefix: '/api/',
responseTransforms: {
removeAttributesKey: true,
removeDataKey: true,
}
}
},
});
Эта конфигурация предоставит ответ API, который будет работать с настройкой вашего внешнего приложения Blazor.
- Перестройте приложение Strapi и запустите сервер, чтобы изменения вступили в силу.
/purplerhino/backend $ yarn build
/purplerhino/backend $ yarn develop
Настройка внешнего интерфейса
Шаг 5: Настройка проекта Blazor
Давайте настроим наше внешнее приложение Blazor, используя интерфейс командной строки (CLI) .NET для выполнения команд.
Откройте терминал и выполните следующие команды:
/purplerhino $ dotnet new blazorwasm -o frontend
/purplerhino $ cd frontend
/purplerhino/frontend $ dotnet run
Откройте localhost: 5024 в браузере, чтобы увидеть приложение Blazor frontend
.
Шаг 6. Интегрируйте API Strapi с приложением Blazor
Теперь ваш проект Blazor установлен; Следующим шагом является создание внешнего интерфейса блога.
Чтобы получить доступ к сообщениям, вам нужно будет использовать URL-адрес API Strapi, который имеет вид localhost:1337/api.
В папке frontend/wwwroot
создайте файл с именем appsettings.json
для хранения URL-адреса API Strapi.
/purplerhino/frontend $ touch wwwroot/appsettings.json
Добавьте следующий код в appsettings.json
:
{
"AppSettings": {
"STRAPI_API_URL": "https://localhost:1337"
}
}
Создайте папку с именем Models
и создайте в ней файл с именем AppSettings.cs
.
/purplerhino/frontend $ mkdir Models
/purplerhino/frontend $ touch Models/AppSettings.cs
Добавьте следующий код в Models/AppSettings.cs
:
// ./Models/AppSettings.cs
namespace frontend.Models
{
public class AppSettings
{
public string STRAPI_API_URL { get; set; }
}
}
Теперь откройте файл Program.cs
и приведенный ниже код. Это необходимо для чтения данных из файла appsettings.json
из любой точки приложения.
// ./Program.cs
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using frontend.Models;
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace frontend
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
}
public static void ConfigureServices(IServiceCollection services)
{
// Example of loading a configuration as configuration isn't available yet at this stage.
services.AddSingleton(provider =>
{
var config = provider.GetService<IConfiguration>();
return config.GetSection("App").Get<AppSettings>();
});
}
}
}
Вы только что настроили интеграцию API Strapi с приложением Blazor. Следующим шагом будет создание компонента для вашего блог-приложения.
Шаг 7. Отобразите все записи блога на главной странице.
Мы используем Tailwind CSS для оформления нашего замечательного блога. Итак, откройте файл index.html
в папке wwwroot
и добавьте этот фрагмент HTML в раздел <head></head>
.
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
Теперь откройте файл Pages/Index.razor
и замените существующий код кодом ниже, чтобы отобразить все сообщения, полученные из Strapi, в ваше клиентское приложение:
@* ./Pages/Index.razor *@
@page "/"
@inject HttpClient Http
@using Microsoft.Extensions.Configuration;
@using Models
@inject IConfiguration Configuration
@if (allPosts == null)
{
<p><em>Loading...</em></p>
}
else
{
<section class="text-gray-600 body-font">
<div class="container px-5 py-4 mx-auto">
<div class="text-center mb-20">
<h1 class="sm:text-3xl text-2xl font-medium title-font text-gray-900 mb-4">Strapi Blazor Blog App</h1>
<p class="text-base leading-relaxed xl:w-2/4 lg:w-3/4 mx-auto text-gray-500s">British History - From the Anglo-Saxon era to present day Britain.</p>
<div class="flex mt-6 justify-center">
<div class="w-16 h-1 rounded-full bg-indigo-500 inline-flex"></div>
</div>
</div>
<div class="flex flex-wrap -m-3">
@foreach (var post in allPosts.data)
{
<div class="xl:w-1/4 md:w-1/2 p-4">
<div class="bg-gray-100 p-6 rounded-lg">
<img class="h-40 rounded w-full object-cover object-center mb-6" src="@post.Image.Url"
alt="content">
<h2 class="text-lg text-gray-900 font-medium title-font mb-4">@post.Title</h2>
<NavLink href="@($"post/{post.Id.ToString()}")">
<a class="text-indigo-500 inline-flex items-center">
Read More
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2" class="w-4 h-4 ml-2" viewBox="0 0 24 24">
<path d="M5 12h14M12 5l7 7-7 7"></path>
</svg>
</a>
</NavLink>
</div>
</div>
}
</div>
</div>
</section>
}
@code {
private PostList allPosts = null;
public string strapi_api_url;
protected override async Task OnInitializedAsync()
{
strapi_api_url = Configuration["AppSettings:STRAPI_API_URL"];
var url = "{STRAPI_API_URL}/api/posts?populate=*";
allPosts = await Http.GetFromJsonAsync<PostList>(url.Replace("{STRAPI_API_URL}", strapi_api_url));
if (allPosts.data != null)
{
foreach (var post in allPosts.data)
{
post.Image.Url = strapi_api_url + post.Image.Url;
}
}
}
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public string Author { get; set; }
public Image Image { get; set; }
}
public class Image
{
public string Url { get; set; }
}
public class PostList
{
public List<Post> data { get; set; }
}
}
Вот краткое объяснение того, что делает код:
- Верхний раздел от
@page
до@inject
представляет собой список всех библиотек, которыеIndex.razor
необходимо использовать для получения данных из API Strapi. - Следующий раздел с
@if (allPosts == null)
по</section>}
— это HTML-код, необходимый для отображения сообщений из API Strapi.@foreach
будет перебирать все сообщения, извлекатьimage
,title
иid
каждого сообщения и отображать каждое сообщение на своей карточке. - Раздел
@code
представляет собой код C#.Post
,Image
иPostList
— это классы, которые мы будем использовать для сопоставления данных JSON из ответа API.allPosts
является экземпляромPostList
. Данные JSON изurl
будут преобразованы вallPosts
с помощью функцииHttp.GetFromJsonAsync()
. Цикл@foreach
будет получать URL-адреса изображений каждого сообщения.
Обновите файл Shared/NavMenu.razor
, чтобы удалить дополнительное меню с боковой панели. Замените существующий код следующим кодом:
@* ./Shared/NavMenu.razor *@
<header class="text-gray-600 body-font">
<div class="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center">
<a class="flex order-first lg:order-none lg:w-1/5 title-font font-medium items-center text-gray-900 lg:items-center lg:justify-center mb-4 md:mb-0">
<img src="/blazor_strapi_logo.png" alt="logo" style="height:60px" />
<span class="ml-3 text-3xl">StrapiBlazorBlog</span>
</a>
</div>
</header>
Обновите файл Shared/MainLayout.razor
, как показано ниже:
@* ./Shared/MainLayout.razor *@
@inherits LayoutComponentBase
<div>
<NavMenu />
<div>
@Body
</div>
</div>
Теперь запустите приложение и перейдите к localhost: 5024 в вашем браузере.
Вау 👌 Мы успешно отобразили все наши посты на главной странице.
Шаг 8. Отобразите один пост в блоге.
Нам удалось отобразить все сообщения на одной странице, но у каждого сообщения нет своей страницы, и кнопка Подробнее на главной странице тоже не работает. Давайте исправим это.
Создайте файл с именем PostDetails.razor
в папке Pages
.
/purplerhino/frontend $ touch Pages/PostDetails.razor
Добавьте следующий код в PostDetails.razor
:
@* ./Pages/PostDetails.razor *@
@page "/post/{Id}"
@inject HttpClient Http
@inject NavigationManager NavigationManager
@using System.Text.Json.Serialization
@using Microsoft.Extensions.Configuration;
@using Models
@inject IConfiguration Configuration
@if (postDetails == null)
{
<p><em>Loading...</em></p>
}
else
{
<section class="text-gray-700 body-font">
<div class="container mx-auto flex px-5 pb-24 items-center justify-center flex-col">
<h1 class="title-font sm:text-4xl text-3xl mb-4 font-medium text-gray-900">@postDetails.Data.Title</h1>
<img class=" mb-10 object-cover object-center rounded" alt="hero" src="@postDetails.Data.Image.Url" style="height:400px;width:900px">
<div class=" w-full">
<div class="mb-8 leading-relaxed">@((MarkupString)postDetails.Data.Content)</div>
</div>
<div class="p-2 w-full">
<button class="flex mx-auto text-white bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg" @onclick="NavigateToIndexComponent">Back</button>
</div>
</div>
</section>
}
@code {
[Parameter] public string Id { get; set; }
private PostSingle postDetails = null;
public string strapi_api_url;
protected override async Task OnInitializedAsync()
{
strapi_api_url = Configuration["AppSettings:STRAPI_API_URL"];
var url = "{STRAPI_API_URL}/api/posts/{Id}?populate=*";
url = url.Replace("{STRAPI_API_URL}", strapi_api_url);
url = url.Replace("{Id}", Id);
postDetails = await Http.GetFromJsonAsync<PostSingle>(url);
if (postDetails.Data != null)
{
postDetails.Data.Image.Url = strapi_api_url + postDetails.Data.Image.Url;
}
}
private void NavigateToIndexComponent()
{
NavigationManager.NavigateTo("");
}
public class PostSingle
{
public Data Data { get; set; }
}
public class Data
{
public int Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public string Author { get; set; }
public Image Image { get; set; }
}
public class Image
{
public string Url { get; set; }
}
}
Вот краткое объяснение того, что делает код.
@page "/post/{Id}"
относится к URL-адресу страницы, которая будет отображаться на основе идентификатора сообщения.- От
@if (postDetaills == null)
до</section>
— это разметка для отображения страницы, в которой используютсяtitle
,image
иcontent
сообщения, полученные из API Strapi. - Раздел
@code
содержит классы для заполнения данными из API Strapi, как и вIndex.razor
, за исключением того, что запрос API относится к одному посту, а не ко всем.
Теперь перезапустите приложение и нажмите кнопку Read More
для любого сообщения. Вы увидите полную запись в блоге на отдельной странице.
Вот короткая демонстрация того, как будет выглядеть блог:
Шаг 9. Разверните приложение блога
Серверный API Strapi и наше внешнее приложение Blazor работают, и следующим шагом будет развертывание вашего приложения. Среди доступных вариантов вы можете развернуть Strapi API на Heroku. Чтобы развернуть приложение Blazor WebAssembly на Netlify, ознакомьтесь с разделом Как развернуть приложение Blazor на Netlify.
Заключение
В этой статье показано, как создать простое приложение для блога, используя Blazor в качестве интерфейса и Strapi в качестве сервера. Strapi имеет множество интеграций с другими фреймворками. Посетите Блог Strapi, чтобы узнать больше интересных руководств, демонстрирующих возможности Strapi.
Вы можете скачать исходный код реализации с Github. Дайте мне знать, если у вас есть какие-либо комментарии, вопросы или предложения. Команда Strapi всегда готова помочь вам.