Alloy MVC with Optimizely Graph Client
Create a standard Alloy MVC sample site and use Optimizely Graph Service and Optimizely Graph Client (OG Client).
Use a few lines of C# code and a dedicated package to build GraphQL search queries for Optimizely Graph, similar to Search & Navigation.
This tutorial uses Visual Studio Code with extensions. You can use whatever IDE you prefer.
Add the Optimizely Graph Client tools
This tool allows you to generate schema's models after indexing your data.
Create a new folder called ContentGraph
:
mkdir ContentGraph
Go to the folder ContentGraph
:
cd ContentGraph
Create a manifest file by running the dotnet new
command:
dotnet new tool-manifest
Install Optimizely Graph Client tools locally:
dotnet tool install Optimizely.Graph.Client.Tools
Create Alloy MVC site
Create a new folder for the site called AlloyMvcGraphQL
:
mkdir AlloyMvcGraphQL
Go to the folder AlloyMvcGraphQL
:
cd AlloyMvcGraphQL
Create the Alloy MVC site:
dotnet new epi-alloy-mvc
Add the latest CMS package:
dotnet add package EPiServer.Cms
Start the site:
dotnet run
Open your browser, go to the site https://localhost:5000
, add the admin user, and make sure the site is working properly.
Install the required packages for Optimizely Graph and OG Client
Add the Optimizely Graph Client:
dotnet add package Optimizely.Graph.Client
(Optional) Generate the model classes that will be used:
dotnet ogschema appsettings.json
Add Optimizely.ContentGraph.Cms
:
dotnet add package Optimizely.ContentGraph.Cms
Update Startup.cs to use Optimizely Graph and OG Client
Add using
:
using EPiServer.DependencyInjection;
using EPiServer.ContentGraph.Extensions;
Update constructor to handle IConfiguration
:
private readonly IConfiguration _configuration;
public Startup(IWebHostEnvironment webHostingEnvironment, IConfiguration configuration)
{
_webHostingEnvironment = webHostingEnvironment;
_configuration = configuration;
}
In ConfigureServices
method add:
services.ConfigureContentApiOptions(o =>
{
o.IncludeInternalContentRoots = true;
o.IncludeSiteHosts = true;
o.EnablePreviewFeatures = true;
o.SetValidateTemplateForContentUrl(true);
});
services.AddContentDeliveryApi(); // required, for further configurations, please visit: https://docs.developers.optimizely.com/content-cloud/v1.5.0-content-delivery-api/docs/configuration
services.AddContentGraph();
services.AddContentGraphClient(); //use graph client
Update search functionality in Alloy
In Alloy, use Optimizely Graph in the search controller.
Update SearchPageController
in Controller
folder to use Optimizely query
SearchPageController
in Controller
folder to use Optimizely queryusing AlloyMvcGraphQL.Models.Pages;
using AlloyMvcGraphQL.Models.ViewModels;
using EPiServer.ContentGraph.Extensions;
using EPiServer.ContentGraph.Api;
using Microsoft.AspNetCore.Mvc;
using EPiServer.ContentGraph.Api.Querying;
using GraphModels = Optimizely.ContentGraph.DataModels;
namespace AlloyMvcGraphQL.Controllers;
public class SearchPageController : PageControllerBase<SearchPage>
{
private readonly GraphQueryBuilder _contentGraphClient;
private static Lazy<LocaleSerializer> _lazyLocaleSerializer = new Lazy<LocaleSerializer>(() => new LocaleSerializer());
public SearchPageController(GraphQueryBuilder contentGraphClient)
{
_contentGraphClient = contentGraphClient;
}
public ViewResult Index(SearchPage currentPage, string q)
{
var searchHits = new List<SearchContentModel.SearchHit>();
var total = 0;
var facets = new List<SearchContentModel.SearchFacet>();
if (q != null)
{
var locale = _lazyLocaleSerializer.Value.Parse(currentPage.Language.TwoLetterISOLanguageName.ToUpper());
var result = _contentGraphClient
.OperationName("Alloy_Sample_Query")
.ForType<ProxyModels.SitePageData>()
.Fields(_=>_.Name, _=>_.Url, _=> _.MetaDescription)
.Facet(_=>_.ContentType)
.Total()
.GetResultAsync<ProxyModels.SitePageData>().Result;
var searchWords = q.Split(" ");
foreach (var item in result.Content.Hits)
{
searchHits.Add(new SearchContentModel.SearchHit()
{
Title = item.Name,
Url = item.Url,
Excerpt = item.MetaDescription.Length <= 500 ? item.MetaDescription : item.MetaDescription.Substring(0,500);
});
}
facets = result.Content.Facets["ContentType"].Select(x=> new SearchContentModel.SearchFacet {
Name = x.Name,
Count = x.Count
});
total = result.Content.Total;
}
var model = new SearchContentModel(currentPage)
{
Hits = searchHits,
NumberOfHits = total,
Facets = facets,
SearchedQuery = q
};
return View(model);
}
Go to the search page and try it out
Start the site:
dotnet run
Open your browser, and go to https://localhost:5000/en/search
.
Updated 20 days ago