When developing custom extensions using plugins, it is often beneficial to install UI components as part of the installation of the extension making use of the IInstallallablePlugin interface and the UI automation API.
[toc]
What is the UI Automation API
The UI automation API is set of APIs made available to plugins via the in-process API to enable the automated adjustment of UI components. Specifically, it includes the following services:
ContentFragments | Enable/disable widgets, identify widgets to other UI automation APIs, translate widgets, and automate widget upgrading (see Managing Widget Source and Distribution). |
FactoryDefaultScriptedContentFragmentProviderFiles | Add/update, delete, and detect factory default widget provider source files and attachments to install files associated to a factory default widget provider (IScriptedContentFragmentFactoryDefaultProvider plugin). For the recommended approach to deploy factory default widgets, see Managing Widget Source and Distribution. |
ThemeFiles | Add/update and detect embedded theme files. |
ThemeFooterContentFragments | List, insert, replace, and delete widgets within theme footers. |
ThemeFooters | Add, edit, delete, and detect theme footers. |
ThemeHeaderContentFragments | List, insert, replace, and delete widgets within theme headers. |
ThemeHeaders | Add, edit, delete, and detect theme headers. |
ThemePageContentFragments | List, insert, replace, and delete widgets within theme pages. |
ThemePages | Add, edit, delete, and detect theme pages. |
Themes | List themes for a specific theme type. |
And the following sets of constants for use with the services:
ContentFragmentWrappingFormats | Constants for platform-defined widget wrapping formats for use with content-fragment-related services. |
LayoutRegions | Constants for platform-defined layout regions for use with widget placement in content-fragment-related services. |
ThemeableApplicationIds | Constant for identifying the site application identifier. |
ThemeProperties | Constants for theme properties used to interact with the ThemeFiles service. |
ThemeTypes | Constants for the platform-defined theme types to be used with other UI automation APIs. |
Using the UI Automation API
There are a few common situations where you'd use the UI automation API:
- A custom application or custom functionality defines new pages (see Page Definition and URL Routing) and wants to include theme-specific variants of the new pages to simplify installation. For this, use the ThemePages API.
- A set of custom functionality implemented as a set of custom widgets (via an IScriptedContentFragmentFactoryDefaultProvider) needs to install the source widget files as part of the plugin representing the custom functionality. For this, see Managing Widget Source and Distribution.
- A custom application with custom widgets needs to install one or more custom widgets on existing pages. For this, use the ThemeHeaders, ThemePages, and ThemeFooters APIs.
- A CSS file should be programmatically installed in the theme, either for general customization (perhaps as part of an automated deployment process) or as part of a custom application. For this, see the Installing a CSS File example below.
Example: Installing a CSS File
In this example, a hard-coded CSS file will be installed in the site theme. This is a common scenario when deploying widgets through an IScriptedContentFragmentFactoryDefaultProvider (see Managing Widget Source and Distribution) when the widgets share a common CSS or LESS file.
To integrate with the platform via code and access the In-Process API, the example will implement the IPlugin interface in a public class named InstallCssFile. To ensure that the CSS file is only installed when it needs to be (when the plugin is first enabled or when a new version is installed), the InstallCssFile
class also implements the IInstallablePlugin interface. To implement the class, the project will need to reference the Telligent.Evolution.Api and Telligent.Evolution.Components DLLs.
The full source is at the bottom of this page, but the key usage of the UI Automation API occurs in the Install()
and Uninstall()
methods:
public void Install(Version lastInstalledVersion) { foreach (var theme in Themes.List(ThemeTypes.Site)) { ThemeFiles.AddUpdateFactoryDefault( theme, ThemeProperties.StyleSheetFiles, _fileName, _fileStream, (int)_fileStream.Length, new CssThemeFileOptions { ApplyToModals = true, ApplyToNonModals = true }); ThemeFiles.AddUpdate( theme, ThemeableApplicationIds.Site, ThemeProperties.StyleSheetFiles, _fileName, _fileStream, (int)_fileStream.Length, new CssThemeFileOptions { ApplyToModals = true, ApplyToNonModals = true } ); } }
In Install()
, the plugin loops on each available site theme (using the ThemeTypes and Themes APIs). For each theme, it installs a factory default version of the CSS file and the same file into the current contextual version of the site theme (using the ThemeFiles, ThemeProperties, and ThemeableApplicationIds APIs). When installing CSS files into the ThemeProperties.StyleSheetFiles
theme property, CSS options can be defined using CssThemeFileOptions. In this example, the plugin identifies that the file should be rendered on modal and non-modal pages of the theme.
public void Uninstall() { foreach (var theme in Themes.List(ThemeTypes.Site)) { ThemeFiles.RemoveFactoryDefault(theme, ThemeProperties.StyleSheetFiles, _fileName); ThemeFiles.Remove(theme, ThemeableApplicationIds.Site, ThemeProperties.StyleSheetFiles, _fileName); } }
When uninstalling, the Uninstall()
method is called and the plugin again loops on the available themes and removes the installed CSS file from the factory default and contextual implementation of each theme.
The full source of this sample is below:
using System; using System.Text; using Telligent.Evolution.Extensibility.Version1; using Telligent.Evolution.Extensibility.UI.Version1; namespace Samples { public class InstallCssFile : IPlugin, IInstallablePlugin { private readonly string _fileName = "sample.css"; private readonly System.IO.Stream _fileStream = new System.IO.MemoryStream(Encoding.UTF8.GetBytes(@".content-fragment-page { background-color: #f00; }")); #region IPlugin Implementation public string Name { get { return "Install a CSS File Sample"; } } public string Description { get { return "Installs a CSS File in the Site theme."; } } public void Initialize() { } #endregion #region IInstallablePlugin Implementation public Version Version { get { return new Version(1, 0); } } public void Install(Version lastInstalledVersion) { foreach (var theme in Themes.List(ThemeTypes.Site)) { ThemeFiles.AddUpdateFactoryDefault( theme, ThemeProperties.StyleSheetFiles, _fileName, _fileStream, (int)_fileStream.Length, new CssThemeFileOptions { ApplyToModals = true, ApplyToNonModals = true }); ThemeFiles.AddUpdate( theme, ThemeableApplicationIds.Site, ThemeProperties.StyleSheetFiles, _fileName, _fileStream, (int)_fileStream.Length, new CssThemeFileOptions { ApplyToModals = true, ApplyToNonModals = true } ); } } public void Uninstall() { foreach (var theme in Themes.List(ThemeTypes.Site)) { ThemeFiles.RemoveFactoryDefault(theme, ThemeProperties.StyleSheetFiles, _fileName); ThemeFiles.Remove(theme, ThemeableApplicationIds.Site, ThemeProperties.StyleSheetFiles, _fileName); } } #endregion } }