tag:blogger.com,1999:blog-82314532776179741032024-03-16T00:01:51.798-05:00Inside The BoxBe different. Be creative. Think inside the box.Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.comBlogger44125tag:blogger.com,1999:blog-8231453277617974103.post-2900636359336830012022-12-28T08:00:00.004-06:002022-12-28T08:00:00.239-06:00Updating Project Versions in Azure DevOps<p>We have a couple projects in DevOps that specify an incrementing
build version as part of the release pipeline. The approach we have is
working well and is deploying our projects with the proper version to
our hosted environments. This approach, however, was causing some issues
for local development and we needed a way to keep our local versions in
sync with the releases. After looking into the behaviour I discovered
we weren't the only ones. A quick search revealed many discussions
trying to deal with this situation, and after some trial and error I was
able to come up with a solution.<span></span></p><a href="https://beendaved.blogspot.com/2022/12/updating-project-versions-in-azure_01169308755.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-35243973937054455402022-05-13T06:00:00.033-05:002022-05-13T06:00:00.182-05:00Optimizely CMS 12 Installation Breaking Changes for Visual Studio 2019<p>Last October I wrote an article to act as an addendum to the Optimizely Documentation for starting a new CMS site using CMS 12 and .NET 5. Since then there have been some updates to the documentation and the packages involved. Today I got bit by one of them because I am using Visual Studio 2019, and if you are too this might save you some trouble.</p><a href="https://beendaved.blogspot.com/2022/05/optimizely-cms-12-installation-breaking.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-90293330470225156202022-05-13T00:29:00.000-05:002022-05-13T00:29:34.028-05:00Starting a New Project with Optimizely CMS 12 and .NET Core - updated!<p>Optimizely recently released CMS 12 based on ASP.NET Core (now .NET 5). With it comes a slew of new changes, including how to set up a new project. To help developers get started with Optimizely CMS on the new framework, Optimizely released a guide to creating a starter project. After working through it myself and talking with a few developers I decided to write a more detailed guide with a few additional notes to better help you get going. I updated this in May 2022 with some changes based on the updated Optimizely documentation (yay!). <br></p><a href="https://beendaved.blogspot.com/2021/10/starting-new-project-with-optimizely.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com1tag:blogger.com,1999:blog-8231453277617974103.post-46497610003962865152021-11-22T08:00:00.002-06:002022-03-02T17:15:15.119-06:00Validation Summary for Optimizely Forms in Non JS Mode<p>I recently wrote an article on how to <a href="https://beendaved.blogspot.com/2021/11/validation-summary-for-optimizely-forms.html">create a Validation Summary for Optimizely Forms</a>. The approach described in that article uses Form Client Events and Javascript to add a validation summary to the top of the form. That method is dependent on Javascript, and Forms must operate in JS mode for it to work. This article provides a different solution for use with Optimizely Forms with <b>workInJonJSMode</b> enabled.<span></span></p><a href="https://beendaved.blogspot.com/2021/11/validation-summary-for-optimizely-forms_01757455308.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-35185290739554320642021-11-16T08:00:00.024-06:002021-11-23T14:19:55.520-06:00Optimizely Form Container Block with Razor View<p>With CMS 11, Optimizely Forms display using a traditional Webform User Control (ASCX) out of the box. With all the work I have been doing with forms lately I wanted to change this behaviour to use a Razor View instead. Now that I have it working, I wanted to share it. </p><p>Take note: as mentioned this only applies to CMS 11. With the release of CMS 12, Optimizely has rewritten Forms views to now utilize Razor, and all this work is not necessary.<br></p><a href="https://beendaved.blogspot.com/2021/11/optimizely-form-container-block-with.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com2tag:blogger.com,1999:blog-8231453277617974103.post-5075530423317135512021-11-09T08:00:00.008-06:002021-11-11T21:55:14.716-06:00Custom Optimizely Form Containers - Put the View Where You Want<p>Most instructions for creating a custom form block in Optimizely follow <a href="https://world.optimizely.com/documentation/developer-guides/forms/creating-a-custom-form-block/" target="_blank">the same approach</a>. My problem with the typical approach is that it requires a folder structure that doesn't match my solution. I use a slightly different method to allow me to move my Form Container Block rendering to my choice of folders.</p><a href="https://beendaved.blogspot.com/2021/11/custom-optimizely-form-containers.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-29424487857616422312021-11-04T08:00:00.027-05:002021-11-04T10:20:23.730-05:00Validation Summary for Optimizely Forms<p>I have seen requests for a method to implement a Validation Summary for Optimizely Forms, and I dealt with one myself. If you're not familiar with the idea, a Validation Summary includes all the validation messages for form fields in a summary section for easy review. This is typically found at the top of the form after you try to submit. There is no option for this functionality out of the box with Optimizely so I put it together.<br></p><span></span><a href="https://beendaved.blogspot.com/2021/11/validation-summary-for-optimizely-forms.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-5114120377341872852021-10-25T08:00:00.019-05:002021-10-25T08:00:00.205-05:00The Problem with Nested Blocks and AdditionalViewData<p>It's not uncommon to nest blocks in Optimizely to create more controlled and complex layouts on pages. It's also sometimes necessary to provide additional data to the blocks you render. When using the PropertyFor helper this is done by specifying an additionalViewData object. However ViewData persists to nested views and this can mess up your layout. This is how to identify when this happens, and how to work around it.<span></span></p><a href="https://beendaved.blogspot.com/2021/10/the-problem-with-nested-blocks-and.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-59820546050068996702021-10-21T08:00:00.008-05:002021-10-21T08:00:00.424-05:00Moving the DisplayTemplates Folder<p>Optimizely uses DisplayTemplates to provide a way to render different partials for data types. DisplayTemplates are native to ASP.Net MVC, though, and Optimizely builds upon them, for instance, by specifying a Tag. An example of this is the rendering of ContentReference properties in my articles <a href="https://beendaved.blogspot.com/2021/09/rendering-contentreference-properties.html" target="_blank">here</a> and <a href="https://beendaved.blogspot.com/2021/09/rendering-contentreference-with-shared.html" target="_blank">here</a>. The MVC engine defaults the location for them to "Views/Shared/DisplayTemplates". Sometimes, though, it's convenient to reference different locations, and this is how you can do that. <span></span></p><a href="https://beendaved.blogspot.com/2021/10/moving-displaytemplates-folder.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-58006150688505631852021-10-18T08:00:00.008-05:002021-10-18T08:00:00.188-05:00Rendering ContentReference With Shared Views Using a TemplateTag<p>ContentReference properties provide a way to select a single item in Optimizely CMS when you don't need the featureset a ContentArea provides. However, rendering an item with a ContentReference is a bit different. I explored this a bit in my article <a href="Rendering ContentReference Properties">Rendering ContentReference Properties</a>. This post expands on this with a single DisplayTemplate that works for most content types. It builds on a similar technique using a ContentReferencePartial, and adds additional functionality using a TemplateTag. </p><a href="https://beendaved.blogspot.com/2021/10/rendering-contentreference-with-shared.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-20704634668727296672021-10-14T08:00:00.002-05:002021-10-14T08:00:00.224-05:00Rendering ContentReference Properties<p>A ContentReference property allows you to select a single ContentData object for reference. By default, when you render these property types with the PropertyFor helper, it renders as a link for a page, or displays the name of a block. This is because the value stored is a ContentReference object, not the ContentData of the item referenced. This is one approach to render that content with a partial view.<br><span></span></p><a href="https://beendaved.blogspot.com/2021/10/rendering-contentreference-properties.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-10710222085140424782021-10-11T08:00:00.004-05:002021-10-11T08:00:00.194-05:00How to Exclude or Modify Episerver Forms Samples Javascript and CSS<p>Optimizely Forms contains jQuery and CSS packages that are included for the Form rendering out-of-box. This isn't always desired because it can affect page performance, other styling, or it could have other side effects depending on your setup. Optimizely provides for the disabling of these files through the Forms.config file in the Forms module folder, which allows you to independently control the insertion of jQuery and CSS. However, this method is easy to break with an update. It also isn't very flexible since it's an all-or-nothing approach. <br><br><span></span></p><a href="https://beendaved.blogspot.com/2021/10/how-to-exclude-or-modify-episerver.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com1tag:blogger.com,1999:blog-8231453277617974103.post-59588426014620855202021-10-07T08:00:00.006-05:002021-10-13T11:59:08.418-05:00Creating Gated Content with Optimizely Forms<p>I recently worked on an Optimizely project where the customer wanted to serve gated content to visitors. If you're not familiar with gated content, it's where content is only available to a user that fills out a form - the form being the "gate". Gated content can be a powerful marketing tool to help capture valuable information for lead generation, or for tracking visitor statistics. </p><p>In our case, the customer wanted to provide whitepaper downloads to visitors that provided a defined set of information. Our goal was to create this interaction using Optimizely Forms.<br><span></span></p><a href="https://beendaved.blogspot.com/2021/10/creating-gated-content-with-optimizely.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com1tag:blogger.com,1999:blog-8231453277617974103.post-77976057417660183522021-10-04T08:00:00.000-05:002021-10-04T08:00:00.230-05:00Hide Optimizely Form Info when Redirecting<p>With Optimizely Forms you have the option to redirect to a page after a complete submission. By default, Optimizely appends some form information to the URL it redirects to. This allows you to process the form submission data in any way you need to on the page it directs to, or perform an action based on what form was submitted. However, if you don't want that information in the URL you can change the behaviour.<span></span></p><a href="https://beendaved.blogspot.com/2021/10/hide-optimizely-form-info-when.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-72193841779590090102021-10-01T17:29:00.014-05:002021-10-05T11:57:46.445-05:00Popup TextArea Property Editor <p>Inline editing in Optimizely delivers a great editor experience due to the WYSIWYG approach for content authors. Sometimes, though, the inline editing can get cumbersome. When making a bunch of edits, or editing a complex component, it can be easier to edit out of line. When working with string properties in these scenarios, I like to use a popup editing box, and this is how I do it.<span></span></p><a href="https://beendaved.blogspot.com/2021/04/previewable-textarea-properties.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-73732662186834354042021-09-30T08:00:00.001-05:002021-09-30T08:00:00.275-05:00Hide FormContainerBlock in Optimizely<p>It's easy to customize a FormContainerBlock by creating a new one inheriting from the out-of-box FormContainerBlock model. When doing this you gain the option of using the OOB container, or your new custom one. However, I have encountered numerous times when the OOB form container was no longer necessary for the project. Furthermore, attempting to use the OOB FormContainerBlock in certain areas created issues I had to account for. In several instances for me, the easiest approach was to hide the Optimizely FormContainerBlock from editors, and this is how I did it. </p><a href="https://beendaved.blogspot.com/2021/09/hide-formcontainerblock-in-optimizely.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-12828966466946885602021-09-23T08:00:00.004-05:002021-10-04T12:27:51.298-05:00Optimizely Form Events using an Interface Pattern<p>Much like standard content items in Optimizely CMS, Forms trigger events that can be subscribed to for further customization. You typically subscribe to these events by employing an Initialization Module and attaching an event handler to process the logic you need for each event. This works well for the out-of-the-box Forms, but I have done enough customization of forms that I started employing an Interface pattern to clean it up. I use this same pattern for content events, so I thought I would share my forms approach. <span></span></p><a href="https://beendaved.blogspot.com/2021/09/form-events-interface-pattern.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-26067405689600935222021-09-22T10:01:00.016-05:002021-10-01T08:53:48.743-05:00Working with SyntaxHighlighter in Blogger Simplified - UpdatedI’ve been attempting to clean up my blog and make it a little more user friendly for myself and visitors, and given that it’s a blog by a developer there is bound to be a code sample or two posted on it. When I see a code sample on a site I like to be able to scroll the code block to see the full thing, or highlight sections to copy if I like. Needless to say, it’s important to display code samples properly on a blog for coding.<br>
<br>
When I was first throwing this blog together I searched for the best approach to displaying code samples. Some people were using SyntaxHighlighter with some tweaks and troubles here and there; others said the simplest approach was to just create a GitHub Gist and copy the Gist embed URL into your post. The Gist approach seemed the simplest so I decided to go with that to start. Well, now that I tackled that with all the effort it took (none, seriously) I decided to try my hand at SyntaxHighlighter.<br>
<br>
<a href="https://beendaved.blogspot.com/2015/03/working-with-syntax-highlighter-in.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com23tag:blogger.com,1999:blog-8231453277617974103.post-52263178551511854782021-09-20T16:00:00.011-05:002021-10-04T12:23:23.037-05:00Stop Creating New Windows & Tabs When Debugging<p>By default, Visual Studio launches web applications in a new browser window when debugging. It also closes your browser window when you stop. While I prefer publishing my web applications locally, Optimizely runs well from Visual Studio, and it's easier to debug initialization modules and other items this way. However, when you want to leave the page or content open, this behaviour can get in the way. This is how you change that.<br></p><a href="https://beendaved.blogspot.com/2021/09/stop-creating-new-windows-tabs-when.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-8355053412279697962021-03-29T16:08:00.009-05:002021-09-23T09:20:36.407-05:00ContentArea with Groups of Personalized Content<div><p>
Personalization is a powerful component in Episerver that can provide a cool, fresh, and
tailored experience for users that visit your site. Leveraging different criteria and
conditions in Epi, Visitor Groups provide a grouping mechanism for users to be served
different content based on pages they've viewed, forms they've submitted, or campaigns
they have arrived from, among various other criteria. It's a pretty nice piece of
functionality that, if you haven't learned about yet, you should check out more about,
<a href="http://webhelp.episerver.com/latest/en/personalization/personalization.htm">here</a>.
</p>
<p> That said, Personalized Groups in Episerver serve content on a prioritized, top-down,
first-match basis. That means a visitor is served the first matching content item that is
tagged with a visitor group they're in. That also means you are limited to one piece of
changing content per Personalized Group for a user. But I needed more, and here are the solutions I explored.<br><br></p></div><a href="https://beendaved.blogspot.com/2021/03/contentarea-with-personalized-content.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-88620680643039647402019-11-12T09:17:00.000-06:002019-11-13T10:10:55.089-06:00Content and Growth are the Focus at Episerver Ascend 2019<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2zwf_P2WsF8DTcX43wsXt8p3nutg_uTgjwETcm9L3Nxvk43NiO6SbAoMCJ3x44rIW0ZlZ8wt8OYBdzFkYdtPSJo9SbsGPKs8-mFJ3Ay5WyD2o0l6DQ-1nSIVGBwMlpFX_aIa2ulnafhw/s1600/Ascend+2019+Banner.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="ascend header banner" border="0" data-original-height="600" data-original-width="1600" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2zwf_P2WsF8DTcX43wsXt8p3nutg_uTgjwETcm9L3Nxvk43NiO6SbAoMCJ3x44rIW0ZlZ8wt8OYBdzFkYdtPSJo9SbsGPKs8-mFJ3Ay5WyD2o0l6DQ-1nSIVGBwMlpFX_aIa2ulnafhw/s640/Ascend+2019+Banner.png" title="ascend header banner" width="640"></a></div>
Each year Episerver organizes the Ascend conference to showcase achievements and accomplishments for the product, the company, and the community. They also layout their roadmap for the future. Each day kicks off with a keynote that is usually intriguing, thought-provoking, or inspirational. A series of breakout sessions, developer labs, and networking opportunities follow. It's a great way for developers, partners, customers, and Epi employees to connect and learn from each other's experiences in the Episerver market.<br>
<br>
Now that Ascend 2019 is over, these are a few of my takeaways:<br>
<a href="https://beendaved.blogspot.com/2019/11/my-thoughts-on-episerver-ascend-2019.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com1tag:blogger.com,1999:blog-8231453277617974103.post-16644454842468124722019-06-21T09:58:00.001-05:002021-03-30T09:43:15.084-05:00Multiple Image Support in PropertyListWhile working on a past project with heavy use of IList<T> properties I ran into several usability situations. One of those situations involved read-only values that were being imported from an external system. They needed to appear in the <b>CollectionEditor</b>, but did not need to be editable (<a href="https://beendaved.blogspot.com/2018/10/defaultvalue-in-propertylist.html" target="_blank">read about that here</a>). Another scenario I encountered involved images in the <b>CollectionEditor</b>. It started off with a simple implementation of <a href="https://gregwiechec.com/2015/12/propertylist-with-images/" target="_blank">the solution provided by Grzegorz Wiecheć</a>, but evolved into something more.<br>
<br>
One of the challenges we faced was the customer's need for multiple images in the list, and those images not always sharing the same property name. As with the issue around default values, some of the data for this was being synchronized with an external system, so we needed to be flexible with the property names and the number of image properties that might be present in the list.<br>
<br>
<a href="https://beendaved.blogspot.com/2019/06/updated-image-support-in-propertylist.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com3tag:blogger.com,1999:blog-8231453277617974103.post-24823194074988516432018-11-06T16:05:00.001-06:002018-11-06T16:11:15.104-06:00Episerver Widgets Resources for Text, Labels, and StylesI have been doing more component and widget building in Episerver lately, and I have been digging around trying to find references to labels and text being used in widgets or referenced in other areas. I had to dig around to find some things, and instead of continually digging next time I need them, I decided to add them here. I also came across the Episerver style guide in my search for information, so I added that here as well. If I come across other references I need to use in the future, I'll update this with them also.<br>
<br>
So, to clarify, this is really here to make it easier for me to find things I need in the future, but if you need this information and find it helpful, it's here for you too.<br>
<a href="https://beendaved.blogspot.com/2018/11/episerver-resources-for-text-and-labels.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com0tag:blogger.com,1999:blog-8231453277617974103.post-87889067070064019752018-10-11T07:00:00.001-05:002021-09-30T22:51:16.382-05:00Replacing HTML strings with Dojo TemplatedMixinI've been playing around with Dojo a bit recently, modifying some Episerver widgets, and extending functionality, and I ran into a scenario I wasn't really satisfied with. In one situation I encountered, I needed to supply an HTML string for a widget to utilize when rendering data for an object, but the HTML markup had some conditions to it based on the object I was on at the time. Another situation involved looping through items and adding them to a list for display in a widget, again needing to include data from the object in the markup.<br>
<br>
I searched online for how to parse HTML strings to include object data or conditions in it, but I didn't find the kind of answer I wanted. Many of the examples online show HTML strings in the Dojo script using concatenation for adding the variables, and others involved multiple lines of node creation and dom manipulation using "<b>dojo.place</b>" and "<b>domConstruct</b>". If you want easily adjustable markup using a template approach, avoiding modifying your dojo JS, these techniques are not the most user friendly. However, I did discover a solution.<br>
<a href="https://beendaved.blogspot.com/2018/10/replacing-html-strings-with-dojo.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com1tag:blogger.com,1999:blog-8231453277617974103.post-77021870359890256262018-10-02T09:03:00.000-05:002018-10-02T10:52:42.422-05:00DefaultValue in PropertyListWhen Episerver brought out <b>PropertyList </b>support in 9.0 and showed the world how to utilize it (<a href="https://world.episerver.com/blogs/Per-Magne-Skuseth/Dates/2015/11/trying-out-propertylistt/">read the article here</a>) it rocked the Episerver developer community and changed the way we utilize the CMS to this day! Okay, that's obviously an exaggeration, but it did introduce a different property type to the community, and brought about a different way of supporting lists or collections of data, that didn't require a bunch of blocks added to a ContentArea.<br>
<br>
As interesting as it is, however, there are some shortcomings to this functionality. After all, it's mentioned in the linked article that it is a "pre-release API that is UNSTABLE." It's expected to have some quirks and shortcomings. Thankfully, as has already been demonstrated by Grzegorz, in his <a href="https://gregwiechec.com/2015/12/propertylist-with-images/">PropertyList with Images article</a>, the PropertyList, or more importantly the <b>CollectionEditor</b>, can be extended to modify the functionality to fit different needs.<br>
<br>
In this article I am taking a similar approach to Grzegorz to extend the functionality, but instead of supporting images in the list, I needed to support a default value specified through code.<br>
<a href="https://beendaved.blogspot.com/2018/10/defaultvalue-in-propertylist.html#more"></a>Daved Artemikhttp://www.blogger.com/profile/13005308699063382442noreply@blogger.com1