<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://www.yqz.dk/blog/rss/xslt"?>
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>Sitecore things</title>
    <link>https://www.yqz.dk/blog/</link>
    <description>Sitecore best practices, architectures, EXM, SPEAK...</description>
    <generator>Articulate, blogging built on Umbraco</generator>
    <item>
      <guid isPermaLink="false">1239</guid>
      <link>https://www.yqz.dk/archive/upgrading-to-sitecore-identity-server-8/</link>
      <title>Upgrading to Sitecore Identity Server 8</title>
      <description>&lt;p&gt;This guide describes how to upgrade Sitecore Identity Server from version 7 to version 8.&lt;br /&gt;In our setup, the Identity Server is hosted on Azure App Service, but the same steps also apply to on-premises hosting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Access to the Identity Server file system&lt;/li&gt;
&lt;li&gt;Access to the SQL Server hosting the security database (typically the Core database)&lt;/li&gt;
&lt;li&gt;Sitecore Identity Server 8 installation packages:
&lt;ul&gt;
&lt;li&gt;Sitecore.IdentityServer.8.x.x.scwdp.zip&lt;/li&gt;
&lt;li&gt;Sitecore.IdentityServer.UpgradeScripts.8.0.zip&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Upgrade Steps&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Back up the Sitecore security database (usually the Core database).&lt;/li&gt;
&lt;li&gt;Back up the following:
&lt;ul&gt;
&lt;li&gt;Config\production\Sitecore.IdentityServer.Host.xml&lt;/li&gt;
&lt;li&gt;The entire \sitecore folder&lt;/li&gt;
&lt;li&gt;Back up the license file: \sitecoreruntime\license.xml&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Clean the Identity Server root folder. Delete all folders and files in the root directory of the Identity Server.&lt;/li&gt;
&lt;li&gt;From Sitecore.IdentityServer.8.x.x.scwdp.zip, copy all folders and files from: Content\Website into the Identity Server root folder.&lt;/li&gt;
&lt;li&gt;Copy the backed-up files back into the root folder, overwriting the existing files where necessary.&lt;/li&gt;
&lt;li&gt;Make sure the connection string has Encrypt=true;TrustServerCertificate=false; For local develop instance, we use Encrypt=false;&lt;/li&gt;
&lt;li&gt;In sitecorehost.xml, verify that: InstrumentationKey and ConnectionString are correctly configured for Application Insights. If Application Insights is not used, leave these values empty.&lt;/li&gt;
&lt;li&gt;Open SQL Server Management Studio and execute the upgrade script from: Sitecore.IdentityServer.UpgradeScripts.8.0.zip against the security database (usually the Core database).&lt;/li&gt;
&lt;li&gt;Restart the Identity Server site&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Sun, 01 Feb 2026 10:01:58 +0100</pubDate>
      <a10:updated>2026-02-01T10:01:58+01:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1238</guid>
      <link>https://www.yqz.dk/archive/renewing-a-certificate-in-azure-key-vault/</link>
      <category>Azure</category>
      <title>Renewing a Certificate in Azure Key Vault</title>
      <description>&lt;p&gt;I recently needed to renew a certificate stored in Azure Key Vault. Below are the steps I followed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a new certificate version in Azure Key Vault.&lt;/li&gt;
&lt;li&gt;Download the CSR (Certificate Signing Request) and send it to your Certificate Authority (CA).&lt;/li&gt;
&lt;li&gt;After receiving the bundle .pem file from the CA, open it in a text editor and remove everything between&lt;br /&gt;-----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----&lt;br /&gt;(Azure does not accept those additional certificate blocks).&lt;/li&gt;
&lt;li&gt;Merge the signed request in Azure Key Vault using the cleaned-up .pem file.&lt;/li&gt;
&lt;li&gt;Download the renewed PEM file from Key Vault and convert it to a .pfx using OpenSSL: openssl pkcs12 -export -out new.pfx -in new.pem -inkey new.pem&lt;/li&gt;
&lt;/ol&gt;</description>
      <pubDate>Mon, 03 Nov 2025 22:52:50 +0100</pubDate>
      <a10:updated>2025-11-03T22:52:50+01:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1237</guid>
      <link>https://www.yqz.dk/archive/adding-certificate-to-azure-application-gateway-from-key-vault/</link>
      <title>Adding certificate to Azure Application Gateway from Key Vault</title>
      <description>&lt;p&gt;I am trying to create a listener which uses "HTTPS" protocol. Since I have already saved my certificates in a Key Vault, I choose a certificate from Key Vault option. However, I always got the following error when I saved the listener.&lt;/p&gt;
&lt;p&gt;ApplicationGatewaySslCertificateInvalidData: Data or Password for certificateis invalid.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;It turns out that PEM certificate is not supported by Azure Application Gateway, I need to convert it to PFX certificate.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;I downloaded PEM certificate. My PEM certificate contains all the information, so I ran the following command:&lt;/p&gt;
&lt;p&gt;.\openssl pkcs12 -inkey my.pem -in my.pem -export -out my.pfx&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The command line will prompt to enter passwords for the pfx file.&lt;/p&gt;
&lt;p&gt;The listener was saved successfully after I uploaded the PFX certificate to it.&lt;/p&gt;</description>
      <pubDate>Thu, 12 Dec 2024 13:51:21 +0100</pubDate>
      <a10:updated>2024-12-12T13:51:21+01:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1233</guid>
      <link>https://www.yqz.dk/archive/tds-unable-to-sync-with-sitecore/</link>
      <title>TDS unable to sync with Sitecore</title>
      <description>&lt;p&gt;The other day, I suddenly ran into an issue that my Sitecore site could not synchronize with my development environment.  TDS kept popping up the error dialog saying that TDS’s web service was interrupted.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1084/tds_error.jpg" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;Then I found out that during synchronization, the context site was one of my sub-sites instead of the default site. And since I made a custom processor in the httpReqestBegin pipeline that redirected the sub-sites’ requests to another URL, TDS’s web services must be confused.&lt;/p&gt;
&lt;p&gt;I contacted Hedgehog support team, and they were very helpful. I was told that TDS connects to Sitecore instance in any single site instance, so it is no guarantee that it uses the default site.&lt;/p&gt;
&lt;p&gt;The solution is in my custom pipeline processor, I added one more check that if the request comes from /_Dev folder, the request will be ignored.&lt;/p&gt;
&lt;p&gt;So if you are using TDS and having custom processors in the httpReqestBegin pipeline, besides checking the context item, item template, context database, etc, you might also need to add a check for TDS.&lt;/p&gt;
</description>
      <pubDate>Fri, 30 Jun 2017 17:10:57 +0200</pubDate>
      <a10:updated>2017-06-30T17:10:57+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1232</guid>
      <link>https://www.yqz.dk/archive/case-insensitive-sorting-by-using-solr-in-sitecore/</link>
      <title>Case insensitive sorting by using Solr in Sitecore</title>
      <description>&lt;p&gt;In my latest project, I faced an issue that the sorting on a page stopped working properly after the solution switched the search engine from Lucene to Solr.&lt;/p&gt;
&lt;p&gt;The page sorted the items by the items’ names. After checking the indexed value, I found out that the item’s name field is sorted as text&lt;em&gt;general field type. In Solr, the text&lt;/em&gt;general field type performs tokenization of the field value and this was the caused that the sorting didn’t work.&lt;/p&gt;
&lt;p&gt;I also saw that Sitecore imported the string field type from Solr. The string type stores the word or sentence as an exact string, without performing tokenization, which seemed exactly what I needed here. So I explicitly set the name field to a string type. However, this didn’t solve issue, because the string field type is case sensitive. &lt;/p&gt;
&lt;p&gt;My first thought was that I could create another computed field for the name filed that would convert the value to lowercase. But this wouldn’t be nice because if the page needs to sort by another field, I will have to create such field again…
I opened the schema.xml file on the Solr server and checked all the field types defined in the file. It does have a lower case field type, but the problem is that Sitecore doesn’t support this field type out of the box. What I need to do is to add a new typematch field in my patch config file for the Solr configurations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;typeMatch typeName=&amp;quot;lowercase&amp;quot; type=&amp;quot;System.String&amp;quot; fieldNameFormat=&amp;quot;{0}_lc&amp;quot; settingType=&amp;quot;Sitecore.ContentSearch.SolrProvider.SolrSearchFieldConfiguration, Sitecore.ContentSearch.SolrProvider&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This means if a field is claimed as lowercase type in Sitecore’s Solr configuration, its indexing field name will append “_lc”. &lt;/p&gt;
&lt;p&gt;In the Solr’s schema.xml file, I added a new dynamic field that tells Solr all the fields end with _lc will be indexed using lowercase field type. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;dynamicField name=&amp;quot;*_lc&amp;quot;  type=&amp;quot;lowercase&amp;quot;  indexed=&amp;quot;true&amp;quot;  stored=&amp;quot;true&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After these changes, I set the name field to the new lowercase type in the configuration field. The sorting worked charming again.&lt;/p&gt;
</description>
      <pubDate>Sun, 21 Aug 2016 22:56:18 +0200</pubDate>
      <a10:updated>2016-08-21T22:56:18+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1231</guid>
      <link>https://www.yqz.dk/archive/consider-segmented-list-for-sitecore-exm/</link>
      <title>Consider Segmented List for Sitecore EXM</title>
      <description>&lt;p&gt;Since Sitecore 8, EXM uses List Manager to manage the recipient lists. The List Manager provides two kinds of lists, i.e. contact list and segmented List. A contact list contains a static numbers of contacts. A segmented list is a dynamic list, the number of the contacts changes due to the source of the contacts and the segment condition.&lt;/p&gt;
&lt;p&gt;In EXM, we can choose either a contact list or a segmented list for the opt-in and opt-out recipient lists. Most clients choose the contact list since it looks straightforward. The normal workflow is that when a user signs up a newsletter, the contact representing the user will be added to a contact list. If you search for how to add a contact to a contact list, you will find several posts talking about it. Either you call some List manager APIs or you just add the contact list tag into the contact in MongoDB directly. However, my experience is that no matter which way you choose, you will end up list lock or inconsistent number of the contacts in the list. This is due to the lock mechanism in List manager. You don’t have the control and you shouldn’t try to customize it. Hopefully Sitecore will improve it in the future.&lt;/p&gt;
&lt;p&gt;So what about segmented list? In my most recent project, I suggested the client to use segmented list and I think it works really well. &lt;/p&gt;
&lt;p&gt;The segmented list uses segment condition to filter the contacts. It reads the contact information from analytics index and it doesn’t touch the MongoDB, which means you will not have the lock issue. &lt;/p&gt;
&lt;p&gt;The way to achieve it is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a facet that has a flag into the contact. The flag indicates if the contact subscribes newsletter or not.&lt;/li&gt;
&lt;li&gt;Create a new segment condition which can filter the contacts based on that flag. &lt;/li&gt;
&lt;li&gt;In the List manager, create a segmented list using that segment condition. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When a user signs up, create or find the contact for that user in the MongoDB, update the flag.  Once the contact is flushed into MongoDB, the analytics index will be updated, you will be able to see the contact in the segmented list.&lt;/p&gt;
&lt;p&gt;In the next post, I will demo this workflow.&lt;/p&gt;
</description>
      <pubDate>Wed, 11 May 2016 11:33:26 +0200</pubDate>
      <a10:updated>2016-05-11T11:33:26+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1230</guid>
      <link>https://www.yqz.dk/archive/exploit-sitecore-exm-subscription-message-type/</link>
      <title>Exploit Sitecore EXM Subscription Message Type</title>
      <description>&lt;p&gt;In Sitecore EXM, when you click the Create button in the navigation pane, you will see three message types (one-time message, subscription message and triggered message). &lt;/p&gt;
&lt;p&gt;In the one-time and triggered message, there are some pre-defined message templates, but you won’t find anything in the subscription message.&lt;/p&gt;
&lt;p&gt;A subscription message template is a template created from a message. For example, you create a new message based on one-time message template, and then you make some changes on the content. You want to reuse this updated message as a template next time. You can choose “Save as a Subscription message template” action. &lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1079/exploitsitecoreexmsubscriptionmessagetype-1.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;After doing this, the new message template will show up in the subscription message type.&lt;/p&gt;
&lt;p&gt;Think about the scenario that a client has several Sitecore sites. Each site has its own Email Campaign Root. The master email campaign editor updates the default newsletter message template and he wants the editors of the other sites use his changes. The subscription message template will really come in handy then. &lt;/p&gt;
&lt;p&gt;But there is another main issue needed to be solved. The new subscription messages will only be saved in its own Email Campaign Root. How could the other roots find it?&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1080/exploitsitecoreexmsubscriptionmessagetype-2.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;Fortunately, EXM uses a provider to retrieve the subscription message templates. The provider is defined in an item called Templates in the core database. The full path is /sitecore/client/Applications/ECM/Component/Create/Subscription/Templates.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1081/exploitsitecoreexmsubscriptionmessagetype-3.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1082/exploitsitecoreexmsubscriptionmessagetype-4.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;&lt;em&gt;DefaultCreateMessageInsertOptionsProvider&lt;/em&gt;&lt;/strong&gt; implements &lt;strong&gt;&lt;em&gt;ICreateMessageInsertOptionsProvider&lt;/em&gt;&lt;/strong&gt; interface. This interface has one member called &lt;strong&gt;&lt;em&gt;GetInsertOptions&lt;/em&gt;&lt;/strong&gt;. Its signature is &lt;strong&gt;&lt;em&gt;List&lt;CreateMessageOption&gt; GetInsertOptions(string managerRootId, string messageType, string database = null)&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;What we can do is to create a new provider also implements this interface. This provider will always load the subscription message templates from the master Email Campaign Root, no matter which current root is. So in our version of &lt;strong&gt;&lt;em&gt;GetInsertOptions&lt;/em&gt;&lt;/strong&gt;, the managerRootId will be the Id of the master Email Campaign Root, the messageType will be &lt;strong&gt;&lt;em&gt;Sitecore.EmailCampaign.Server.Helpers.Constants.Items.MessageTypes.Subscription&lt;/em&gt;&lt;/strong&gt; and the database will be the master database.&lt;/p&gt;
&lt;p&gt;A small issue of this solution is that you have to make sure  the /Email Campaign/Message Types/Subscription folder in each Email Campaign Root can’t be empty even it reads the subscription message templates from the master root. It seems that EXM will check this folder before it creates the message. A workaround is to create a new manager root branch template based on &lt;strong&gt;&lt;em&gt;/sitecore/templates/Branches/Email Campaign/Manager Root&lt;/em&gt;&lt;/strong&gt;, and add a dummy subscription message in the subscription folder.&lt;/p&gt;
</description>
      <pubDate>Fri, 29 Apr 2016 15:18:38 +0200</pubDate>
      <a10:updated>2016-04-29T15:18:38+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1221</guid>
      <link>https://www.yqz.dk/archive/keep-pascal-case-for-json-format-in-your-sitecore-solution/</link>
      <title>Keep Pascal Case for JSON Format in Your Sitecore Solution</title>
      <description>&lt;p&gt;More and more Sitecore solutions are adopting the architecture that exposes the content from back-end by using REST service. This can be achieved by using Sitecore.Services.Client or ASP.NET Web API to return JSON strings to the front-end. &lt;/p&gt;
&lt;p&gt;The default JSON format returned from Sitecore.Services.Client or ASP.NET Web API are using Pascal Case like {&amp;quot;Id&amp;quot;:1,&amp;quot;FirstName&amp;quot;:&amp;quot;Yuqing&amp;quot;}. However, most front-end developers are feeling awkward to work with JavaScript objects where the first letter of a property name is a capital letter. So I saw some projects change that to Camel Case.&lt;/p&gt;
&lt;p&gt;Unfortunately, this would introduce a serious problem in Sitecore after version 8. Sitecore 8 uses SPEAK as the front-end framework for most of its modules. And SPEAK consumes a lot of JSON strings returned from back-end.&lt;/p&gt;
&lt;p&gt;Let’s check in List Manager for example.&lt;/p&gt;
&lt;p&gt;The following is the default JSON string received in the front-end of List Manager. And it is using Pascal Case.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1077/keeppascalcaseforjsonformatinyoursitecoresolution-1.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;If your Sitecore solution introduces the Camel Case, then the JSON string would probably look like:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1078/keeppascalcaseforjsonformatinyoursitecoresolution-2.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;Since JavaScript is a case sensitive language, new camel case JSON string will cause a lot of SPEAK methods failed. &lt;/p&gt;
&lt;p&gt;In short, keep using Pascal Case for JSON format in your solution.&lt;/p&gt;
</description>
      <pubDate>Wed, 27 Apr 2016 16:40:01 +0200</pubDate>
      <a10:updated>2016-04-27T16:40:01+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1206</guid>
      <link>https://www.yqz.dk/archive/make-new-email-template-available-on-sitecore-exm-ui/</link>
      <title>Make new email template available on Sitecore EXM UI</title>
      <description>&lt;p&gt;Since Sitecore EXM 3.0 was released, we are able to show our own Sitecore EXM email template on the shining EXM UI. &lt;/p&gt;
&lt;p&gt;For example, I create a new one-time message template called New User and I want it to be displayed as below.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1072/make-new-email-template-available-in-sitecore-exm-ui-1.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;To achieve this, I need to switch to the core database and go to &lt;strong&gt;/sitecore/client/Applications/ECM/Component/Create/One Time/&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1075/make-new-email-template-available-in-sitecore-exm-ui-2.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;From there, I create a new item based on CreateMessageSection template. Later, I can save all my one-time message templates in this section.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1076/make-new-email-template-available-in-sitecore-exm-ui-3.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;I need to give a name to the new section and make it visible. The index field allows me to change the position of the section on the EXM UI.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1071/make-new-email-template-available-in-sitecore-exm-ui-4.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;To create my New User template thumbnail, I use the CreateMessageOption template.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1074/make-new-email-template-available-in-sitecore-exm-ui-5.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;I get more fields to fill out this time. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Name: The template name on the UI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IconUrl: The URL of the thumbnail to be displayed on the UI. The EXM's default
   thumbnails can be found at
   &lt;strong&gt;/sitecore/client/Applications/ECM/Assets/Thumbnails/&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Parameters: This field uses JSON syntax and needs to include the
   messageTemplateId and the messageTypeTemplateId. In this post, the
   messageTemplateId is the NewUser template Id, the
   messageTypeTemplateId is the One time message type template Id, which
   is located at &lt;strong&gt;/sitecore/templates/Email Campaign/Message
   Types/OneTime&lt;/strong&gt; in the master database.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Url: This field points to the page that EXM will redirect to when the
   thumbnail is clicked. This can be a customized page or the default
   EXM one time message page,
   &lt;strong&gt;/sitecore/client/Applications/ECM/Pages/Messages/OneTime&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Visible: Make the thumbnail to be displayed on the UI.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SectionIndex: The position of the thumbnail in the section.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1073/make-new-email-template-available-in-sitecore-exm-ui-6.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;That's it :-)&lt;/p&gt;
</description>
      <pubDate>Sat, 23 Jan 2016 22:44:09 +0100</pubDate>
      <a10:updated>2016-01-23T22:44:09+01:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1205</guid>
      <link>https://www.yqz.dk/archive/sitecore-nuget-package-generator/</link>
      <title>Sitecore Nuget Package Generator</title>
      <description>&lt;p&gt;I like using Nuget package to reference Sitecore DLLs in my solutions. There are nice posts discussing how to do it, for example &lt;a href="https://jermdavis.wordpress.com/2014/07/07/using-nuget-for-your-references-to-sitecore-dlls/"&gt;https://jermdavis.wordpress.com/2014/07/07/using-nuget-for-your-references-to-sitecore-dlls/&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;However, I am tired of remembering how to generate a Nuget package each time I need to upgrade my solution to the latest Sitecore version. So, I made a simply console application that can generate the package by accepting some augments.&lt;/p&gt;
&lt;p&gt;The application is available here: &lt;a href="https://github.com/zyq524/SitecoreNugetPackageGenerator"&gt;https://github.com/zyq524/SitecoreNugetPackageGenerator&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Wed, 06 Jan 2016 05:25:15 +0100</pubDate>
      <a10:updated>2016-01-06T05:25:15+01:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1201</guid>
      <link>https://www.yqz.dk/archive/forward-sitecore-logs-to-nlog/</link>
      <title>Forward Sitecore logs to NLog</title>
      <description>&lt;p&gt;In my current project, I need to use an in-house logging system that was built on NLog in the Sitecore project. &lt;/p&gt;
&lt;p&gt;Since Sitecore uses log4net for logging and we don’t want to replace all of it with another logging system, the easiest way would be to create a custom log4net appender that can forward the log messages to another logger.&lt;/p&gt;
&lt;p&gt;Firstly, let’s define the NLog loggers in NLog.config file.  In the following example, I defined 6 loggers that each of them maps to a log4net logger in Sitecore. I was using NLog 4.1, so I was able to use JSON as the log file format.&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/zyq524/ffd3bed9038447bba256.js"&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;Then I created an appender that inherited from &lt;strong&gt;&lt;em&gt;log4net.Appender.AppenderSkeleton&lt;/em&gt;&lt;/strong&gt;. It overrode the &lt;strong&gt;&lt;em&gt;Append&lt;/em&gt;&lt;/strong&gt; method. What it does is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Finding the correct NLog logger based on the log4ne logger name in the &lt;strong&gt;&lt;em&gt;log4net.spi.LogEventInfo&lt;/em&gt;&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;Converting the LogEventInfo from log4net to NLog  
&lt;/li&gt;
&lt;li&gt;Writing the converted LogEventInfo  by using the NLog logger.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/zyq524/c0cf515ea357e9269a71.js"&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;Last step was to define this appender in the &lt;strong&gt;&amp;lt; log4net&amp;gt;&lt;/strong&gt; section in the Web.config file.  
&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/zyq524/23be39280e718cdb3ed3.js"&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;Now we are able to append this NLogAppender to any &lt;strong&gt;&lt;logger&gt;&lt;/strong&gt; section that we want the log message be forwarded to Nlog. In this example, I put it to all the Sitecore loggers. By doing this, besides the default Sitecore log files, we also get the log files generated by NLog.&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/zyq524/41dbaf992fed10568ab2.js"&gt;&lt;/script&gt;&lt;/p&gt;
</description>
      <pubDate>Wed, 21 Oct 2015 15:04:40 +0200</pubDate>
      <a10:updated>2015-10-21T15:04:40+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1200</guid>
      <link>https://www.yqz.dk/archive/send-a-triggered-message-in-exm/</link>
      <title>Send a triggered message in EXM</title>
      <description>&lt;p&gt;The biggest change in Sitecore Email Experience Manager (EXM) module was that it introduced using the contact in xDB instead of the Sitecore User to represent the recipient. This gives a lot flexibility, but also means that we need to change our existing code.&lt;/p&gt;
&lt;p&gt;One of the common tasks by using EXM is sending a triggered message that could be triggered by user filling out a form, etc. We can use the Sitecore API to send the message. In ECM, basically we passed the Sitecore User to the SendStandardMessage by querying the username. &lt;/p&gt;
&lt;p&gt;This is no long valid in EXM. In EXM, we need to create or query a contact from the xDB, and then pass the contact to the SendStandardMessage.&lt;/p&gt;
&lt;p&gt;For example, if a client fills out a form, which includes his first name, last name, email address. A triggered message (a welcome message, etc) should be sent to him.&lt;/p&gt;
&lt;p&gt;To achieve this, we create a contact if it doesn't exist and get its contact Id. Otherwise, we find the contact Id in xDB by using the identifier of the contact. In this case, let's assume that the identifier is the email address.&lt;/p&gt;
&lt;p&gt;Then we can use the following code to send the triggered message to that contact.&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/zyq524/83e3ca097f7e3478520f.js"&gt;&lt;/script&gt;&lt;/p&gt;
</description>
      <pubDate>Wed, 07 Oct 2015 23:39:27 +0200</pubDate>
      <a10:updated>2015-10-07T23:39:27+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1198</guid>
      <link>https://www.yqz.dk/archive/walkthrough-adding-a-custom-button-in-sitecore-rich-text-editor-in-sitecore-8/</link>
      <title>Walkthrough: Adding a custom button in Sitecore Rich Text Editor in Sitecore 8</title>
      <description>&lt;p&gt;I needed to add a custom button in Sitecore Rich Text Editor for a website that has many global variables used across many pages. All the variables are saved as dictionary items in Sitecore. The custom button would allow the editors to insert the key of a global variable as a token into the text. When pages having the tokens are rendered, the tokens will be replaced by the values of the dictionary items.&lt;/p&gt;
&lt;p&gt;My idea was to create a SPEAK dialog page that would display all the keys of the global variables. The dialog pops up when the custom button on the Rich Text Editor is clicked. &lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1064/walkthrough-adding-a-custom-button-in-sitecore-rich-text-editor-in-sitecore-8-2.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;Once a key is selected/clicked on the dialog, the dialog closes and the key is inserted into the text and highlighted as below.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1063/walkthrough-adding-a-custom-button-in-sitecore-rich-text-editor-in-sitecore-8-1.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;h3&gt;Step 1&lt;/h3&gt;
&lt;p&gt;In Sitecore Rocks, find your default Rich Text profile. I use Rich Text Default. So I add a new _HTML Editor Button under &lt;strong&gt;/sitecore/system/Settings/Html Editor Profiles/Rich Text Default/Toolbar 1&lt;/strong&gt; in the core database and call it Insert Global Variable. Set the Click value of the Insert Global Variable Tokens item to a JavaScript method called “ShowTokens” that will be created later. This method handles when the button is clicked.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1061/walkthrough-adding-a-custom-button-in-sitecore-rich-text-editor-in-sitecore-8-3.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1062/walkthrough-adding-a-custom-button-in-sitecore-rich-text-editor-in-sitecore-8-4.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;h3&gt;Step 2&lt;/h3&gt;
&lt;p&gt;All the click event handler of the Rich Text Editor’s buttons are defined in &lt;strong&gt;\Website\sitecore\shell\Controls\Rich Text Editor\RichText Commands.js&lt;/strong&gt;. Instead of adding the “ShowTokens” method directly into this file, I create another JavaScript file called &lt;strong&gt;InsertGlobalVariableToken.js&lt;/strong&gt; and place it in &lt;strong&gt;\Website\sitecore\shell\Controls\Rich Text Editor\InsertGlobalVariableToken&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/zyq524/a9a0f2488f58b6a26900.js"&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;The first function is used to load a CSS file that defines the button’s icon. The &lt;em&gt;callbackFunction&lt;/em&gt; is used to insert the returned value, which is the key of the global variable. The first parameter of showExternalDialog specifies the item path of Insert Global Variable token SPEAK dialog.&lt;/p&gt;
&lt;p&gt;We also need to insert a script node inside clientscripts/htmleditor in a patch config file.&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/zyq524/4f1cda466a4190bd6e81.js"&gt;&lt;/script&gt;&lt;/p&gt;
&lt;h3&gt;Step 3&lt;/h3&gt;
&lt;p&gt;Now I am going to create a SPEAK dialog. I don’t want to elaborate how to create a SPEAK dialog here. The only thing special is that I create a custom SPEAK component that can list all the items in the specified dictionary folder and user can click one of them. The difficult part is how to send the selected key on the SPEAK dialog to the Rich Text Editor. I use the following piece of code in  my custom SPEAK component’s page code. It can close the dialog and send the selected item’s text back to the Rich Text Editor.&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/zyq524/a46424d835d69f60f4cc.js"&gt;&lt;/script&gt;&lt;/p&gt;
&lt;h3&gt;Step 4&lt;/h3&gt;
&lt;p&gt;Last thing is to replace the token with the value of the dictionary when page is rendered. To achieve this, we create a new RenderField processor. This process will replace the highlighted token if the field is a rich text field and the page is not in page editor mode.&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/zyq524/165badb5decc8e5ef91e.js"&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;Add this process to a patch config file as well.&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/zyq524/e64038055ea9e9a9ec3a.js"&gt;&lt;/script&gt;&lt;/p&gt;
&lt;p&gt;Hope this could help anyone who needs to do a similar task.&lt;/p&gt;
</description>
      <pubDate>Sun, 27 Sep 2015 21:05:03 +0200</pubDate>
      <a10:updated>2015-09-27T21:05:03+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1192</guid>
      <link>https://www.yqz.dk/archive/sitecore-speak-could-not-select-row-in-listcontrol/</link>
      <title>Sitecore SPEAK - Could not select row in ListControl</title>
      <description>&lt;p&gt;I use ListControl from SPEAK a lot  and most of the time I use self-defined datasource components for ListControl's items. &lt;/p&gt;
&lt;p&gt;This week, I bind a ListControl to a new data source as usual. Just an example, the data source is a JSON object array. &lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1057/sitecore-speak-could-not-select-row-in-listcontrol-1.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;I bind a ListControl to this datasource.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1056/sitecore-speak-could-not-select-row-in-listcontrol-2.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;The control displays the items as expected, so far so good. &lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1058/sitecore-speak-could-not-select-row-in-listcontrol-3.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;However, I could not select any row in this list. &lt;/p&gt;
&lt;p&gt;The reason is that the &amp;quot;selectedItem&amp;quot; or &amp;quot;selectedItemId&amp;quot; attribute of a ListControl requires an default &amp;quot;itemId&amp;quot; property from the datasource and the items in my JSON object array do not have &amp;quot;itemId&amp;quot; field. When I add the &amp;quot;itemId&amp;quot; into each object in my JSON object array, I can select the row again.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1059/sitecore-speak-could-not-select-row-in-listcontrol-4.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;In sum, when we define a datasource component for ListControl, we need to make sure that we include the &amp;quot;itemId&amp;quot; for each item in the datasource.&lt;/p&gt;
</description>
      <pubDate>Sun, 20 Sep 2015 22:55:24 +0200</pubDate>
      <a10:updated>2015-09-20T22:55:24+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1183</guid>
      <link>https://www.yqz.dk/archive/sitecore-speak-multiselectlist/</link>
      <title>Sitecore SPEAK - MultiSelectList</title>
      <description>&lt;p&gt;In Sitecore SPEAK, I use ListControl to bind a data source and display items in that data source. The ListControl has selectedItem and selectedItemId attributes so that I can easily access the selected item/row in the list. &lt;/p&gt;
&lt;p&gt;In order to select multiple items in the ListControl, we need to use a control called MultiSelectList. A MultiSelectList is a Behavior control instead of a &amp;quot;real&amp;quot; list control. &lt;/p&gt;
&lt;p&gt;To add a MultiSelectList Behavior into a ListControl, I need to do the following steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a MultiSelectList rendering into the page. It is important that even if the ListControl is on a subpage, the
  MutlitSelectList should still be added on the main page.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1052/sitecore-speak-multiselectlist-1.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the ListControl, add MultiSelectList into the Behaviors property. No matter what the Id of the MultiSelectList is,
  it only needs to put the name of the control into the Behaviors property. Thus, only one MultiSelectList control is needed on a page and it can be reused by several ListControl controls on that page.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1049/sitecore-speak-multiselectlist-2.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;That’s it. When I open the page in my browser, I can see the check box in the first column of each row. &lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1055/sitecore-speak-multiselectlist-3.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;There are two more attributes i.e. checkedItems and checkedItemIds been added into the ListCotrol’s attributes.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1051/sitecore-speak-multiselectlist-4.png" alt="enter image description here" /&gt;&lt;/p&gt;
</description>
      <pubDate>Mon, 07 Sep 2015 23:33:50 +0200</pubDate>
      <a10:updated>2015-09-07T23:33:50+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1171</guid>
      <link>https://www.yqz.dk/archive/sitecore-speak-edit-layout-file/</link>
      <title>Sitecore SPEAK - Edit Layout File</title>
      <description>&lt;p&gt;When I edit a SPEAK page, I usually use the “Task-&amp;gt;Design Layout” command in Sitecore Rocks and add renderings from there. It is fine if the page doesn’t contain too many rendering components. &lt;/p&gt;
&lt;p&gt;However, it could be a headache to maintain a page that has a lot renderings. For example, I have page like this.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1047/sitecore-speak-editlayoutfile-1.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;It could be painful to move the renderings around or insert a new rendering in the middle of the page. &lt;/p&gt;
&lt;p&gt;Another scenario could be that the page has a lot of renderings of some same components. It would be boring to add them without the ability to use copy function. &lt;/p&gt;
&lt;p&gt;Actually, each SPEAK page’s layout is a XML file. Moreover Sitecore Rocks does give us the ability to edit the XML file. &lt;/p&gt;
&lt;p&gt;The trick is to use the “Task -&amp;gt; Edit Layout File” command. To me, it is a more confidence and pleasant way to edit my long renderings list.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1046/sitecore-speak-editlayoutfile-2.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1048/sitecore-speak-editlayoutfile-3.png" alt="enter image description here" /&gt;&lt;/p&gt;
</description>
      <pubDate>Tue, 25 Aug 2015 15:32:37 +0200</pubDate>
      <a10:updated>2015-08-25T15:32:37+02:00</a10:updated>
    </item>
    <item>
      <guid isPermaLink="false">1131</guid>
      <link>https://www.yqz.dk/archive/sitecore-speak-repeater/</link>
      <title>Sitecore SPEAK - Repeater</title>
      <description>&lt;p&gt;I've used dozens of Sitecore SPEAK components since Sitecore 7.2, and I have to say the most confusing one for me is the Repeater component. &lt;/p&gt;
&lt;p&gt;After reading the documentation, I know that the Repeater component doesn't render items by itself, which means that renderings are not added to the Repeater component directly. &lt;/p&gt;
&lt;p&gt;Instead, I need to define a template for the items that I want to render and add all the renderings to that template’s standard values. Afterwards I create items from that template and the Repeater component only needs to bind to them.&lt;/p&gt;
&lt;p&gt;I am going to create a page that has a Repeater component on it. The Repeater component can display the football match results. Each match result is an item of the Repeater component.&lt;/p&gt;
&lt;p&gt;First things first, I create a MatchResult template in my Playground application’s template folder. The template has four fields. &lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1039/sitecore-speak-repeater-1.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;I also create the standard values for this template. Open the Design Layout of _Standard Values, I add the SPEAK components that are needed to render one match result. It is important not to forget to select a layout, I use Speak-EmptyLayout here. &lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1037/sitecore-speak-repeater-2.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;This is how I bind the field data to the Text component.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1035/sitecore-speak-repeater-3.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;Since I have a template, I can start to create the items. I created two items based on MatchResult template.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1033/sitecore-speak-repeater-4.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;Now I switch to my Playground page’s layout and add a Repeater component to it. In the Items property I need to assign that two match results items. In order to achieve this, I create a SearchDataSource that can find the two items and binding the DataSource.Items to the Items property of the Repeater component.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1034/sitecore-speak-repeater-5.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1040/sitecore-speak-repeater-6.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;I open my browser and go to my playground page, two match results have been rendered correctly.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://www.yqz.dk/blog/media/1044/sitecore-speak-repeater-7.png" alt="enter image description here" /&gt;&lt;/p&gt;
&lt;p&gt;So far so good. The issue caught me out is that I need to create item for each match result in the core database. This is a bit weird. Because what if the match results have already been saved in the master database? Why should I keep another copy in the core database? &lt;/p&gt;
&lt;p&gt;Maybe SPEAK’s idea is that the items in the master database are kind of models for the backend and those items in the core database are ViewModels in the frontend, but it is truly overloaded to keep all these items in the core database.&lt;/p&gt;
&lt;p&gt;The way I can figure out is to create these items as temporary items on the fly by using Sitecore Item Web API and delete them right after it has been rendered in the Repeater. &lt;/p&gt;
&lt;p&gt;All the rendered items of the Repeater can be accessed through MatchResultReapter.RenderedItems. When the “add” event of the RenderedItems is triggered, I can call item.toModel().destroy(); to delete the item just created.&lt;/p&gt;
&lt;p&gt;I know this is nasty. My wish is that in the future it would be possible to use JSON objects as data instead items in the core database. &lt;/p&gt;
&lt;p&gt;Last thing, to access the rendering components of each MatchResult item in the MatchResultRepeater, I use the “app” attribute. For example, to access the components of the first match result:
&lt;img src="https://www.yqz.dk/blog/media/1038/sitecore-speak-repeater-8.png" alt="enter image description here" /&gt;&lt;/p&gt;
</description>
      <pubDate>Thu, 20 Aug 2015 21:04:31 +0200</pubDate>
      <a10:updated>2015-08-20T21:04:31+02:00</a10:updated>
    </item>
  </channel>
</rss>