Quantcast
Channel: Ryan Bailey Development
Viewing all 287 articles
Browse latest View live

Sitecore Lucene scheduling a search index to rebuild with IntervalAsynchronousStrategy

$
0
0
For larger Lucene search indexes in Sitecore (that can take some time to run) it is not the best idea to have these update after publishing - via the onPublishEndAsync or RebuildAfterFullPublish index strategy. In my case the index contained 20,000 items, with more than half being PDFs so it took close to an hour to process.

Luckily with Sitecore there is an index strategy which allows the index to rebuild automatically on a schedule. This is done via the IntervalAsynchronousStrategy index strategy and you are able to define the database and interval for when it should run.


Define the strategy

First the indexing strategy will need to be defined. This is done inside the Sitecore.ContentSearch.Lucene.DefaultIndexConfiguration.config file which is located in Website/App_Config/Include.

In the example above (configuration has been trimmed for clarity), an index strategy of type IntervalAsynchronousStrategy has been defined on the web database with an interval of 3 hours. The CheckForThreshold element (if true) will fully rebuild the index if more items than the FullRebuildItemCountThreshold setting are affected.

Assigning the strategy to an index

Now that the strategy is defined, it needs to be assigned to your custom search index. Take note that the name of the strategy defined above (intervalAsync3Hour) is used in the search index configuration below. 

Testing that the index is running

Now to ensure that the index is running on schedule, open up the latest Crawling.Log file (found in Data/Logs) and the following line should appear:
INFO  [Index=MySearchIndex] Initializing IntervalAsynchronousUpdateStrategy with interval '03:00:00'.

Now your custom search index will update on schedule! It's also worth noting that this index strategy should not be combined with SynchronousStrategy and OnPublishEndAsync.

Custom workflow actions in Sitecore

$
0
0
Simple workflows (content approval with rejection for example) in Sitecore can be achieved out of the box, and there are also modules such as Dynamic Workflow for more complex solutions. However there are cases where there is need to create a custom action (perhaps for a more advanced emailer with HTML templates and other advanced logic), this can be achieved with the following code:

Once deployed, you simply create an action (template: /sitecore/templates/System/Workflow/Action) inside a workflow and set the Type string field to the class (fully qualified) followed by a comma and the assembly name (much like you would with pipelines).


The custom action should now run as expected, and you have access to the full item (including it's history - such as who approved the previous workflow step).

Woff2 font giving 404 error in console

$
0
0
If you are using a font face which has the extension of woff2, by default users may get a 404 error when attempting to access the resource. The MIME type for woff2 will need to be added to IIS for the website. This can be done as follows:
  1. Open up IIS manager
  2. Select the server name OR a given web site
  3. Click the MIME types button


  4. On the right hand actions pane, click Add
  5. Enter .woff2 as the extension and application/font-woff2 as the mime type


  6. The font should now load correctly

How to give Sitecore sublayouts and renderings custom thumbnails

$
0
0
Where possible, it's nice to configure Sitecore in a way that makes it easier for the content authors to use the system. One such way is to provide custom thumbnails for any sublayouts or renderings (instead of the standard blue rectangle). The main benefit here is that it helps content authors to distinguish between the many sublayouts or renderings available and also gives them a preview of what it looks like.An example of how it would look is shown below:





As you can see the PageBody rendering has a custom image, which illustrates what the page would look like. To set this up in Sitecore you need to:
  1. Create an image to use on a given sublayout/rendering and upload it to the media library
  2. Navigate to the sublayout/rendering item in the content tree
  3. Ensure Standard Fields are enabled (under View on the ribbon)
  4. Under the Appearance section of the sublayout/rendering properties you will see a field called Thumbnail, select the image uploaded at step 1
  5. That's it, the custom thumbnail is setup


Sitecore install errors

$
0
0
If you are running through the Sitecore installation wizard and at the instance name step get this error:
The name you entered is not unique
It is likely due to the fact that you have previously uninstalled a Sitecore instance with the same name. To fix this error (after first ensuring a Sitecore instance does not currently exist with the given name), you will need to:

  1. Open up the registry editor (regedit)
  2. Navigate to HKEY_LOCAL_MACHINE > SOFTWARE > Wow6432Node > Sitecore CMS
  3. Then select the child item (will have a GUID for a name) where the InstanceName value is equal to that which you are trying to install and right click delete
  4. Now restart the Sitecore installation wizard
If you then get to the IIS Web Site> Create a New Web Site step and get this error:
The site name must be unique.
 Then there may still be artifacts left over from the old Sitecore installation, ensure the following items have been removed/renamed:

  • IIS Application pool
  • IIS Web Site
  • Inetpub website root
  • SQL Server databases
Once these have all been removed you will need to restart the Sitecore installation wizard.

One final error which may occur is in relation the Sitecore installation wizard attaching the databases in SQL Server. If this error occurs, firstly ensure that the databases from the previous installations have been removed and then restart the server (the computer, not SQL Server instance).

Sitecore Could not find configuration node: databases/database Core

$
0
0
While playing around in a development environment I loaded up the Sitecore admin area only to  be greeted with the error:
Could not find configuration node: databases/database[@id='core']
 It was down to a simple mistake where a new Visual Studio solution had deployed the default web.config over the Sitecore one. The fix is to restore the web.config from a backup or to get a new one off of a clean Sitecore install.

Custom item resolver in Sitecore

$
0
0
I had a website migration to Sitecore with a large subset of URLs which could not be mapped using any of the available URL redirect modules (due to custom business logic). Therefore a custom item resolver had to be written.

This then gets referenced in the Web.config or Sitecore.config file after the default item resolver. That means that if Sitecore doesn't find the item it goes into this custom resolver. If the business logic doesn't find the correct item, it continues on through to a normal 404 error.

Using Sitecore search to resolve PDFs not found

$
0
0
When you link to a PDF or other media library item in Sitecore, and subsequently move that file, the link will remain intact. Likewise if you attempt to delete an item linked internally, a warning will present itself to the user. The problem I faced is PDF files which are linked externally (via email and third party websites for example), along with migration from another CMS to Sitecore with a large amount of PDFs.

The solution, was to index all PDFs in the media library (using a Lucene search index) by name. Then after the default Sitecore media handler, add a custom one for PDFs that searched that index for a file that macthes the requested document name. If a single match was found, that would then be served up. If not the request would ultimately 404.

Lucene Index
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <contentSearch>
      <configuration type="Sitecore.ContentSearch.ContentSearchConfiguration, Sitecore.ContentSearch">
        <indexes hint="list:AddIndex">
          <!-- Change this to Sitecore.ContentSearch.LuceneProvider.SwitchOnRebuildLuceneIndex, Sitecore.ContentSearch.LuceneProvider if you would like indexes to be
               built in a temporary directory i.e. while rebuilding is happening, your old indexes work like normal until the rebuild is finished. -->
          <index id="PdfIndex" type="Sitecore.ContentSearch.LuceneProvider.LuceneIndex, Sitecore.ContentSearch.LuceneProvider">
            <param desc="name">$(id)</param>
            <param desc="folder">$(id)</param>
            <!-- This initializes index property store. Id has to be set to the index id -->
            <param desc="propertyStore" ref="contentSearch/indexConfigurations/databasePropertyStore" param1="$(id)" />
            <configuration ref="contentSearch/indexConfigurations/defaultLuceneIndexConfiguration">
<include hint="list:IncludeTemplate">
<template>{0603F166-35B8-469F-8123-E8D87BEDC171}</template> <!-- Unversioned PDF -->
</include>
<IndexAllFields>true</IndexAllFields>
            <fields hint="raw:AddComputedIndexField">
            <field fieldName="pdfname" storageType="yes" indexType="untokenized"
                  patch:after="field[last()]">MyProject.ComputedSearchFields.PdfCleanName, Sitecore.Common.Website</field>
          </fields>
</configuration>
            <strategies hint="list:AddStrategy">
              <!-- NOTE: order of these is controls the execution order -->
              <strategy ref="contentSearch/indexConfigurations/indexUpdateStrategies/onPublishEndAsync" />
            </strategies>
            <locations hint="list:AddCrawler">
              <crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
                <Database>web</Database>
                <Root>/sitecore/media library</Root>
              </crawler>
            </locations>
          </index>
        </indexes>
      </configuration>
    </contentSearch>
  </sitecore>
</configuration>

Computed Search Field
namespace MyProject.ComputedSearchFields
{
    public class PdfCleanName : IComputedIndexField
    {
        /// <inheritdoc />
        public string FieldName { get; set; }
        /// <inheritdoc />
        public string ReturnType { get; set; }

        /// <inheritdoc />
        public object ComputeFieldValue(IIndexable indexable)
        {
            Item item = indexable as SitecoreIndexableItem;

            if (item != null)
            {
                MediaItem mediaItem = new MediaItem(item);
                if (mediaItem != null)
                {
                    return mediaItem.Name.Replace("-", " ").Replace("%20", " ").Replace("_", " ");
                }
            }
            return null;
        }
    }
}

The Handler
namespace MyProject.Handlers
{
    public class PdfRewriteHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get { return false; }
        }

        public void ProcessRequest(HttpContext context)
        {
            try
            {
                // If PDF request
                if (context.Request.RawUrl.ToLower().EndsWith(".pdf"))
                {
                    // Terrible code to get the pdf file request file name... I need to practice REGEX
var itemName = context.Request.RawUrl.Substring(context.Request.RawUrl.LastIndexOf("/")).Replace("/", "").Replace(".pdf", "").Replace("-", " ").Replace("%20", " ").Replace("_", " ");

                    var index = ContentSearchManager.GetIndex("PdfIndex");

                    using (var seaechContext = index.CreateSearchContext())
                    {
                        var results = seaechContext.GetQueryable<MyResultItem>().Where(resultItem => resultItem.Name == itemName).GetResults();

                        if (results.Hits.Count() == 1)
                        {
                            // one match found
                            MediaItem item = (MediaItem)Factory.GetDatabase("web").GetItem(results.Hits.FirstOrDefault().Document.ItemId);

                            if (item != null)
                            {
                                // Get name to be shown when image is saved
                                var fileName = string.Format("{0}.pdf", item.Name);

                                context.Response.Clear();
                                context.Response.ContentType = item.MimeType;
                                context.Response.AppendHeader("Content-Disposition", string.Format("inline;filename=\"{0}\"", fileName));
                                context.Response.StatusCode = (int)HttpStatusCode.OK;
                                context.Response.BufferOutput = true;
                                item.GetMediaStream().CopyTo(context.Response.OutputStream);
                                context.Response.Flush();
                                context.Response.End();
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e.ToString(), "");

                context.Response.StatusCode = 404;
                context.Response.End();
            }

            context.Response.StatusCode = 404;
            context.Response.End();
        }

        public class MyResultItem : SearchResultItem
        {
            [IndexField("pdfname")]
            public string Name { get; set; }
        }
    }
}

Web.config
<add verb="*" path="sitecore_media.ashx" type="Sitecore.Resources.Media.MediaRequestHandler, Sitecore.Kernel" name="Sitecore.MediaRequestHandler" />
<add name="PdfRewriteHandler" path="*.pdf" verb="*" type="MyProject.Handlers.PdfRewriteHandler" resourceType="Unspecified" preCondition="integratedMode" />

We place the custom handler after the Sitecore media handler, because if Sitecore doesn't find the file, it's a 404.

This concept could be extended using Lucene to find files that are not exact matches (like the file name or contains key words for example). In my case the requirement was an exact match, however if there were more than one they could be presented on a page where the user is able to select the relevant one.

Another option is to place all legacy PDF files in a single folder and set that as the crawler root in the Lucene search index configuration.

Sitecore using a custom template for PDF and other media items

$
0
0
In cases where you index PDF content in Sitecore, it's a good idea to set a flag on the template which allows the content authors to exclude the item from search results. Instead of editing the system templates (both unversioned and versioned), it's possible to use your own. Simply:
  1. Create a new template which inherits from the base Sitecore media template 
  2. Add the custom fields or reference another base template which relates to search
  3. Open up the web.config (or sitecore.config) file and look for the mediaLibrary mediaTypes node
  4. Find the mediaType node for the template you are replacing
  5. Update it to use your new template
<mediaType name="PDF file" extensions="pdf">
<mimeType>application/pdf</mimeType>
<forceDownload>true</forceDownload>
<sharedTemplate>Path/MyPDF</sharedTemplate>
<versionedTemplate>Path/MyPDF</versionedTemplate>
</mediaType>

Simple, now there is no need to hack any of the Sitecore system templates

Creating a custom filter for advanced system reporter in Sitecore

$
0
0
The advanced system reporter module for Sitecore is a great way to provide reporting, in a similar way to the out-of-box broken links report. After installation the module comes with a number of pre-defined reports, along with scanner and filter, but there can be a need to customize for specific reports the business needs.

In this case I have written a custom filter to filter by template name. The business need for this one would be to use an existing report, but filtered on a specific template (for example media releases).

namespace MyProject.Reports
{
    public class TemplateNameFilter : BaseFilter
    {
        public string TemplateName { get; set; }
        public override bool Filter(object element)
        {
            Item item = null;

            if (element is Item)
            {
                item = element as Item;
            }
            else if (element is ItemWorkflowEvent)
            {
                item = (element as ItemWorkflowEvent).Item;
            }

            if (item != null)
            {
                if (item.TemplateName == TemplateName)
                {
                    return true;
                }
            }

            return false;
        }
    }
}

Once deployed to Sitecore, the custom filter can be created:


A custom parameter also needs to be created:



Now the filter can be added to any advanced system report.

Installing MongoDB on a Windows machine as a service

$
0
0
The great experience analytics features (including the experience profile) in Sitecore 8 and beyond require the use of MongoDB. MongoDB is not like common database management servers (such as SQL Server or Oracle) whom use tables and rows, MongoDB instead stores data dynamically in the JSON format. The instructions to install MongoDB on your windows machine (as a service) are as follows.

  1. Download the latest version of MongoDB from the downloads page (3.2 at time of writing)
  2. Run the MSI installer package
    1. Accept the license agreement
    2. Select the complete installation (this will install MongoDb at C:\Program Files\MongoDB - custom will allow you to select a location)
    3. Click install
  3. Now to run MongoDB as a service, open the command prompt (in administrator mode)
    1. Run the command cd C:\Program Files\MongoDB\Server\3.2\bin to point the command prompt to the correct location
    2. Create the following directories:
      1. C:\Mongo\db
      2. C:\Mongo\logs
    3. Run the command mongod --dbpath="C:\Mongo\db" --logpath="C:\Mongo\logs\log.txt" --install to install the database
    4. Run the command net start MongoDB to start running MongoDB
MongoDB should now be running as a service.


Sitecore Lucene include and exclude template warning

$
0
0
With my Lucene indexes I tend to include the relevant templates which I want included in the index. This will often lead to the following warning:
You have specified both IncludeTemplates and ExcludeTemplates. This logic is not supported. Exclude templates will be ignored.
 Inside the default Lucene configuration file (/App_Config/Include/Sitecore.ContentSearch.Lucene.DefaultIndexConfiguration.config) there is a section with some templates excluded by default:

<exclude hint="list:AddExcludedTemplate">
<BucketFolderTemplateId>{ADB6CA4F-03EF-4F47-B9AC-9CE2BA53FF97}</BucketFolderTemplateId>
</exclude>

As the error suggests, with Lucene search in Sitecore you can't both include and exclude templates. Therefore as I choose to decide on what templates to include (opt-in rather than opt-out), this section can be commented out which fixes the warning throughout the logs.

Sitecore warning Could not compute value for ComputedIndexField

$
0
0
In one implementation where PDF content was being indexed in Sitecore (with Luncene), the content was not returning in the search results (no PDFs appearing). After looking in the crawling logs, the following warning was in there for each PDF document that was attempting to be indexed:
WARN  Could not compute value for ComputedIndexField: _content for indexable: sitecore://web/{10D8A7A1-880C-4143-923C-84D94BA56232}?lang=en&ver=1
Exception: System.Runtime.InteropServices.COMException
I am using PDFBox to index PDF content however there was an element left  in the default Lucene configuration file (/App_Config/Include/Sitecore.ContentSearch.Lucene.DefaultIndexConfiguration.config):
<field fieldName="_content" storageType="no" indexType="tokenized">Sitecore.ContentSearch.ComputedFields.MediaItemContentExtractor,Sitecore.ContentSearch</field>
Should be changed to the computed index field in your solution which does the PDF indexing.
<field fieldName="_content"                 type="MyProject.ComputedIndexField.IndexPdfContent,MyProject"></field>

    Sitecore publish to web failed - Web database full

    $
    0
    0
    While working on a Sitecore development environment which was using SQL Server Express, the following error came up when attempting a full publish to web:
    Job started: Publish to 'web'|#Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Could not allocate space for object 'dbo.EventQueue'.'IX_Stamp' in database 'Sitecore_Web' because the 'PRIMARY' filegroup is full. Create disk space by deleting unneeded files, dropping objects in the filegroup, adding additional files to the filegroup, or setting autogrowth on for existing files in the filegroup.

    This was because the web database had grown to 10gb, even though master was only 2gb:

     The Sitecore clean up databases wizard

    In the Sitecore control panel, under database there is a clean up databases wizard:



    This allows you to run a cleaner on selected databases (in this case web), which will perform some cleanups, including:
    • Deleting orphan content
    • Removing unused blogs
    • Clears all caches
    Once run, your database size should be much smaller. For those with extremely large databases (hundreds of gigabits), Craig Taylor has a post on what to do if the tool fails.

    Worst case for getting a SQL Server Express web database down to a manageable size (on non production environments) is to run a shrink on the database and then files in SQL Server Management Studio.

    Angular 2 errors when compiling with Gulp

    $
    0
    0
    When attempting to use a Gulp script to compile my Angular 2, I was getting a lot of various errors in the output window. These included:
    error TS2304: Cannot find name 'Promise'.
    error TS2304: Cannot find name 'Map'.
    error TS2304: Cannot find name 'Iterator'.
    Adding 'node_modules/angular2/typings/browser.d.ts' to the Gulp src appeared to fix the error and the code compiled correctly.

    return gulp
    .src(['node_modules/angular2/typings/browser.d.ts','src/app/**/*.ts'])
    .pipe(typescript(tscConfig.compilerOptions))
    .pipe(gulp.dest('dist/app'))

    This is a source map file required for the code to compile.

    Node.js npm integration with Visual Studio 2015

    $
    0
    0
    One of the greatest features of Node.js is the ability to install and manage packages using npm. As a CMS developer on the Microsoft stack, I am more accustomed to using Visual Studio for my development environment. Luckily for me there is an (open source) extension available for Visual Studio called Node.js Tools for Visual Studio. It's even released on the Microsoft Github account...
    I am using this on Visual Studio 2015 Community Edition (update 2) and it works a treat. A full list of features is available on the wiki, but where I get the most value is from:
    • TypeScript project support

    •  

    • npm integration via: command line, Node.js interactive window, npm install GUI, solution explorer and output windows




    • ES6 Intellisense (preview)
    • Debugging support
    • Testing support
    It's worth the install for the npm support alone!

    Sitecore web forms for marketers on a multi-instance environment

    $
    0
    0
    A typical multi-instance Sitecore environment will likely contain one content management (CM) server and two content delivery servers (CD). The master connection is removed from the CD servers as they should not be connecting to it, and this will affect web form for marketers (WFFM) because it has save actions such as creating Sitecore items and uploading files.

    Therefore for these actions to work as expected the CD servers will need to be able to access the CM server via a service (port 80). The following connection string needs to be added to connectionstrings.config:

    <add name="remoteWfmService" connectionString="url=http://[masterserver]/sitecore%20modules/shell/Web%20Forms%20for%20Marketers/Staging/WfmService.asmx;user=[domain\username];password=[password];timeout=60000" />

    Sitecore access to the viewstate folder denied

    $
    0
    0
    If you are unable to load the Sitecore desktop and get errors pertaining to access being denied on the Data\viewstate folder (and its many child folders), it's a permissions issue...

    To allow file uploading and modification of the site, grant the ASP.NET user Read/Write rights to the following folders:
    • /data
    • /upload
    • /temp (if this directory does not exists immediatly after installation, create it).
    • /sitecore/shell/Applications/debug (if this directory does not exist immediately after installation, create it).
    • /sitecore/shell/Controls/debug (if this directory does not exists immediately after installation, create it). 
    • /layouts (If Developer Center will be used to create and modify layouts and sublayouts).
    • /xsl (If Developer Center will be used to create and modify XSL renderings).
    • /App_Data/
    In order to maintain the search indexes ASP.NET and IUSR_* users also require the modify access rights to the following folder:
    • /indexes
    Both the ASP.NET and IUSR_* users require Read and Write access rights to the following folders:
    • /audit
    • /logs
    • /viewstate
    • /mediacache
    • /diagnostics
    Where IUSR_* refers to IUSR_MachineName.

    Sitecore Advanced Sitemap Module Updated

    $
    0
    0
    Mohammed Syam has developed a great module for Sitecore called Advanced Sitemap Module. I have used this on a number of implementations, and it works well. However with Sitecore 8.1 the following error might occur when installing the package:
    Empty strings are not allowed. Parameter name: itemName
    This appears to be due to a corrupt package (or one not supported by Sitecore 8.1 +). So I recreated the items to create a fresh package that will install on Sitecore 8.1.

    Code was updated from a fork of the original by Patrick Stysiak. Here are a couple of notes:

    1. Fixes have been made to work on Content Delivery servers (no master connection)
    2. Error with info logger in one case removed
    3. Icons may be different from the original
    4. GUIDs have changed from the original (in terms of template IDs and SiteMap configuration content item).
    5. Field changed from Show In SiteMap to Show In XML SiteMap
    6. Code will no longer error when root site item has descendants which don't include the sitemap base template. This was P => P.Fields["Show In XML SiteMap"].Value == "1" code. We now check for items which have the field and the field value is set to "1". P => P.Fields["Show In XML SiteMap"] != null && P.Fields["Show In XML SiteMap"].Value == "1"
    7. Fixed config bug where Sitemap would not generate unless MultilingualSiteMapXML was set to true 

    The Github source for the code is available at: Sitecore Advanced SiteMap module. - This is not required as the package has the DLL included.

    The updated package is available here.

    Notes

    • ERROR Advanced SiteMap config item was not found: This is because the SiteMap config item (ID {38ACC950-E87F-4A5C-9271-C55C4336AAAB}) could not be found in the web database
    • The Sitemap Site template has a field called Site Name, this should refer to a site defined in the sites node of Sitecore.config
    • This module uses the web database, so ensure a publish will be needed for changes to appear in the Sitemap

    Angular 2 and Sitecore Example

    $
    0
    0
    Having worked on a number of Sitecore projects which used version 1.x of AngularJS, and with Angular 2 now in beta, I decided to take a look and see how a migration path would be for existing Sitecore sites.

    Initial thoughts

    • I was able to get Node.JS (including npm) integration into Visual studio which provided Typescript project templates and had a gulp file compiling the Angular 2 Typescript to ES5 JavaScript.
    • There is a learning curve after using Angular 1.x and not having used Typescript before.
    • Angular 2 appears to have large amounts of JavaScript (file size once compiled and minified) which will affect page load times.
    • It has been built with single page apps in mind, which is how a lot of the demos are structured (using routing for example). 
    • It's still in it's early stages so tooling and error reporting still have some way to come. Features apparent in documentation and example blogs have since been removed.

    Setting up the environment

    There are a lot of detailed blog posts about doing this, however the quick list of pre-requisites is:
    • Install Visual Studio 2015 - Select Visual C++ features to support Node
    • Install Node 5.x
    • Register Node at the top of External Web Tools in Visual Studio


    • Install Python 2.7.x - this is needed for Node and the C++ compiler
      • Set Python in the windows path
      • Run the command: npm config set python python2.7
      • Run the command: npm config set msvs_version 2015 --global
    • Install this Visual Studio add-on to get npm script support in task runner explorer
    • Install Typescript for Visual Studio
    • Install Node.js tools for Visual Studio - see Node.js npm integration with Visual Studio 2015 for more information

    Setting up the solution

    I chose to split the Visual Studio solution into two main projects:
    1. Typescript project for the Angular 2 app - this used gulp to compile into JavaScript
    2. A standard web forms project which had user controls which referenced the compiled JavaScript (and standard Angular 2 requirements)
    I didn't want to get carried away with the tooling here, but the [future] idea was that the build of the Sitecore web forms project would compile the Angular 2 and clean/deploy it onto the target website, then deploy itself. It's manual deploy right now ;)

    The code is available at: Sitecore Angular 2 on Github.



    Angular (Ang) Project
    The structure is:
    • dist - compiled JavaScript I checked this in (not included in solution) for demo purposes
    • src/app - the TypeScript source
    • gulpfile.ts - can be run from Task Runner Explorer to compile the TypeScript into JavaScript (ES5)
    • package.json - used by Node to define the various npm packages used y the solution
    • tsconfig.json - configuration for the TypeScript and is used for compiliation
    To restore the npm packages, right click npm and select Update npm Packages - this will use package.json

    To compile the TypeScript, open up the Task Runner Explorer and run the build. This will output it to the dist directory. 



    Sitecore (Sc) Project
    This one is fairly self explanatory, it contains one layout and two sublayouts. The layout references all of the required JavaScript resources and instantiates the Angular 2 (the script below the body tag). The two sublayouts simply output their Angular 2 components.

    In Sitecore
    Now it's simply a matter of creating a layout, two sublayouts and then assigning them to a page:


    Then the two Angular 2 components as Sitecore sublayouts will appear on the page:


    Final thoughts

    This exercise was a proof of concept to get Angular 2 working in Sitecore. As Angular 2 is current under development/in beta it's not production ready, however it is a good idea to get a handle on the changes from Angular 1.x. I'll be working with some more advanced concepts in a future blog post.

    From what I have seen, the framework is ever improving, and breaking changes are made with each beta release. Many of the code samples online contain broken code, so I would recommend waiting for a more stable state before bringing larger solutions into the fold.

    I kept this post brief as to cover a few concepts, feel free to comment below if you have any issues getting setup. Or you have any more discussion points on Angular 2 with Sitecore 8.1.

    Viewing all 287 articles
    Browse latest View live