Tumgik
vu3lo · 6 years
Text
Episerver Asset Panel Search with Find Custom Fields
Had been struggling to figure out how to include our custom field extension methods on our product content types in the asset panel (right hand panel) search for editors.
We just had a simple extension method on the product content type that we used a custom CatalogContentClientConventions to include it in the Find index. 
But to ensure these fields are used in the Asset Panel for editors searching, the solution is to extend the EnterpriseCatalogSearchProvider class. The outcome looks something like this:
[SearchProvider] public class CustomEnterpriseCatalogSearchProvider : EnterpriseCatalogSearchProvider, ISortable {    public CustomEnterpriseCatalogSearchProvider(LocalizationService localizationService, IEnterpriseSettings enterpriseSettings, IContentTypeRepository<ContentType> contentTypeRepository)        : base(localizationService, enterpriseSettings, contentTypeRepository)    {    }    public CustomEnterpriseCatalogSearchProvider(LocalizationService localizationService, IEnterpriseSettings enterpriseSettings, IContentTypeRepository<ContentType> contentTypeRepository, UIDescriptorRegistry uiDescriptorRegistry)        : base(localizationService, enterpriseSettings, contentTypeRepository, uiDescriptorRegistry)    {    }    public CustomEnterpriseCatalogSearchProvider(LocalizationService localizationService, ISiteDefinitionResolver siteDefinitionResolver, IContentTypeRepository contentTypeRepository, UIDescriptorRegistry uiDescriptorRegistry)        : base(localizationService, siteDefinitionResolver, contentTypeRepository, uiDescriptorRegistry)    {    }    protected override IQueriedSearch<IContentData, QueryStringQuery> AddContentSpecificFields(IQueriedSearch<IContentData, QueryStringQuery> query)    {        return base.AddContentSpecificFields(query)            .InField(x => ((CustomProduct)x).GetSpecialValue());    }    /// <summary>    /// Change to be first search provider (otherwise other instances might be selected first)    /// </summary>    public new int SortOrder => 1; }
In the above example the overridden AddContentSpecificFields method will add the “GetSpecialValue()” to the asset panel catalog search query.
This should also work for CMS content search too. But instead you would extend EnterprisePageSearchProvider for pages, EnterpriseBlockSearchProvider for blocks, or EnterpriseMediaSearchProvider for media.
0 notes
vu3lo · 6 years
Text
Disable Episerver Commerce Find indexing on price or inventory updates
Episerver Commerce with Find integration will, by default, reindex content when a price or inventory update occurs.
This is coordinated by the CatalogContentEventListener class. Inside this class implementation there is are methods “IsReindexingContentOnPriceUpdates” and “IsReindexingContentOnInventoryUpdates” which return their respective boolean as to whether it should reindex.
The problem I had was to figure out how to change these settings. Because I am yet to find a simple appSetting or other property to set, here is how I have overridden their settings:
[ServiceConfiguration(ServiceType = typeof(CatalogContentEventListener))] public class CustomCatalogContentEventListener : CatalogContentEventListener {    public CustomCatalogContentEventListener(ReferenceConverter referenceConverter, IContentRepository contentRepository, IClient client, CatalogEventIndexer indexer, CatalogContentClientConventions catalogContentClientConventions)        : base(referenceConverter, contentRepository, client, indexer, catalogContentClientConventions)    { }    public CustomCatalogContentEventListener(ReferenceConverter referenceConverter, IContentRepository contentRepository, IClient client, CatalogEventIndexer indexer, CatalogContentClientConventions catalogContentClientConventions, PriceIndexing priceIndexing)        : base(referenceConverter, contentRepository, client, indexer, catalogContentClientConventions, priceIndexing)    { }    public override bool IsReindexingContentOnPriceUpdates()    {        return false;    }    public override bool IsReindexingContentOnInventoryUpdates()    {        return false;    } }
Hope this helps someone (or myself when I re google this in the future).
0 notes
vu3lo · 9 years
Text
EPiServer Commerce CartCheckout workflow with IsIgnoreProcessPayment parameter
EPiServer Commerce has substantial processes which rely on workflows. In many scenarios, like on a simple consumer website, you may get away without modifying or configuring these workflows beyond their defaults.
But on my current project I needed to simply disable payment processing in the CartCheckout workflow. And there is an API method in Mediachase.Commerce.Orders.OrderGroup that facilitates this:
// Summary: //     Runs the specified workflow. // // Parameters: //   name: //     The name. // //   throwException: //     if set to true the exception will be thrown and should be handled by the //     caller. // //   param: //     The additional input parameters. public virtual WorkflowResults RunWorkflow(string name, bool throwException, Dictionary<string, object> param);
For my situation setting IsIgnoreProcessPayment to true when running the CartCheckout workflow, this is my simplified code that was required:
var workflowParams = new Dictionary<string, object> { { "IsIgnoreProcessPayment", true } } var results = cartHelper.Cart.RunWorkflow(OrderGroupWorkflowManager.CartCheckOutWorkflowName, true, workflowParams);
I hunted for examples of how to set IsIgnoreProcessPayment so thought it deserved a blog post.
0 notes
vu3lo · 9 years
Text
Implementing IPriceService with default IPriceService as its dependency
In EPiServer Commerce prices are loaded via the IPriceService and IPriceDetailService. I needed to customise the IPriceService logic but just to tweak the price filtering and still intend to call the default IPriceService internally to reuse the base functionality.
This is where confusion ensues, how does one configure the dependency resolver (StructureMap) to return my custom price service implementation which itself has a dependency on the same IPriceService interface? Turns out StructureMap has a method called EnrichWith to achieve this.
So I have my implementation called “CustomPriceService” and the default EPiServer implmentation is “PriceServiceDatabase“. My CustomPriceService constructor looks like this:
public CustomPriceService(IPriceService defaultPriceService) { this._defaultPriceService = defaultPriceService; }
Now I have the local field _defaultPriceService that I can call for default functionality throughout my custom implementation and it still retains the injected abstraction for unit testing purposes.
To configure StructureMap all that is needed is:
container.For<IPriceService>().Use<PriceServiceDatabase>().EnrichWith((context, systemPriceService) => new CustomPriceService(systemPriceService));
When an IPriceService dependency is resolved StructureMap will get the default EPiServer Commerce “PriceServiceDatabase” and then create my “CustomPriceService” passing the PriceServiceDatabase into the constructor.
If your constructor needs other dependencies you can use the “IContext” that EnrichWith provides, for example:
container.For<IPriceService>().Use<PriceServiceDatabase>().EnrichWith((context, systemPriceService) => new CustomPriceService(systemPriceService, context.GetInstance<ICurrentMarket>()));
Hopefully this will help anyone trying to figure out how to get StructureMap to configure a dependency for a given type to itself have a dependency on the same type.
0 notes
vu3lo · 9 years
Text
EPiServer 7 & 8 overriding editor UI language values
Update (28 Dec 2015): I have since noticed that this information now seems to be officially documented at http://world.episerver.com/documentation/Items/Developers-Guide/Episerver-CMS/9/Globalization/localizing-the-user-interface/
It could be something I simply missed, but I spent a fair amount of time searching the web for how to override the text an EPiServer editor sees for content types and properties. Perhaps this is so obvious that no one else needed documentation or examples on the web to figure it out? Ultimately though, I found the answer in the Alloy sample website code.
I’m currently using EPiServer 8 (8.2 to be precise) and found placing the following in a lang xml file will override a custom content type and properties:
<contenttypes> <HomePage> <name>Hemsida</name> <description>Startsidan för webbplatsen</description> <properties> <MainContentArea> <help>Huvudinnehållsområdet till att omfatta hemsidan widgets</help> </MainContentArea> </properties> </HomePage> <ContentMetadataBlock> <name>Innehåll Metadata Block</name> <properties> <Description> <caption>Beskrivning</caption> <help>Meta beskrivning taggar arbetar med titeln att locka besökare till dina sidor. Standard SEO regeln är att hålla dina metabeskrivningar till 150 tecken eller mindre.</help> </Description> </properties> </ContentMetadataBlock> </contenttypes>
In this case I’m overriding the HomePage’s “name”, “description” and its “MainContentArea” properties “help” text with the Swedish language version. And below this I demonstrate a block having similar text overridden.
Now an editor with the UI set to Swedish will find property names and descriptions have been customised for them.
From what I see in the Alloy site, you can also do generic overrides for common properties throughout your codebase by using a base type or even an interface, such as IContentData:
<contenttypes> <icontentdata> <properties> <!-- SitePageData --> <disableindexing> <caption>Disable indexing</caption> <help>Prevents the page from being indexed by search engines</help> </disableindexing> <!-- Common properties--> <mainbody> <caption>Main body</caption> <help>Main editorial content of the page</help> </mainbody> </properties> </icontentdata> </contenttypes>
Hopefully this helps someone else to more easily discover this.
0 notes
vu3lo · 10 years
Text
EPiServer log4net stopped working
An EPiServer website I worked on had logging working well until it [seemingly] randomly stopped working. I reviewed changes in our configurations and could not trace a cause for the sudden failure.
I proceeded to enable log4net's own logging which is done by adding this to your web.config:
<appSettings> <add key="log4net.Internal.Debug" value="true"/> </appSettings> <system.diagnostics> <trace autoflush="true"> <listeners> <add name="textWriterTraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\log4net.txt" /> </listeners> </trace> </system.diagnostics>
This log revealed the following:
log4net: XmlConfigurator: configuring repository [log4net-default-repository] using file [C:\Dev\Project1\Trunk\Src\Web\web.config] log4net: XmlConfigurator: configuring repository [log4net-default-repository] using stream log4net: XmlConfigurator: loading XML configuration log4net: XmlConfigurator: XML configuration does not contain a <log4net> element. Configuration Aborted.
With EPiServer, this should be using it's default EPiServerLog.config rather than log4net's default web.config location - hence why it's not finding the <log4net> element.
It took me a little experimentation and searching before I realised the problem was caused because I referenced log4net in our Global.asax.cs. This causes it to setup log4net prior to EPiServer determining the EPiServerLog.config file. Once I removed that, it all worked again!
0 notes
vu3lo · 11 years
Text
Web deploy ignoring config transforms
If you have an annoying issue where your CI (TeamCity) web deployments were not transforming some configs, you’re not alone. And I might have found a reason why:
Mine in particular was transforming a few configs (web.config, episerverlog.config etc) whilst not transforming some (connectionstrings.config, episerverframework.config and episerver.config).
It turns out that the Web.csproj file had them specified differently. The ones that were working looked like this:
<Content Include="EPiServerLog.config"> <SubType>Designer</SubType> <TransformOnBuild>true</TransformOnBuild> </Content>
While the configs that did not work had only:
<Content Include="EPiServerFramework.config" />
So I’ve added in the <TransformOnBuild>true</TransformOnBuild> and they now work :)
1 note · View note