Writing extensions

IContentTemplate

Namespace: Lisa.Themes.Demo.ContentTemplates

The IContentTemplate interface allows you to create a "content template", i.e a predefined component config in code, which will then be presented to the user on the "Saved templates" tab in the "Add Content" dialog.  A content template implementation has a name and a description, and a JsonData property which returns the component config as JSON.  The JSON is a essentially a ContentMeta class, just like the IContentResolver implementations use.

ICustomFormFieldValidator

Namespace: Lisa.Core.Domain.Interfaces

By implementing the ICustomFormFieldValidator, you can create your own validation rules for form fields.  This can be useful when the built-in field validators are not enough.  An example would be to create complex conditional validation rules like enforcing certain fields where other fields contain certain values.

The interface only has one method that needs to be implemented, the Validate() method.  The value of the field which the validator is assigned to is provided as an argument, and also the formValues collection which contains data from all other fields present in the form.

ICustomFormValidator

Namespace: Lisa.Core.Domain.Interfaces

The ICustomFormValidator interface allows you to write your own form validator, much like the ICustomFormFieldValidator, except it's not meant for single fields but the entire form.  ICustomFormValidators are applied to the form component under the Validation -> Custom Validators section.

You only need to implement the Validate() method which gets all the formValues as an argument.  If your validation succeeds, just return an empty string, otherwise return the validation/error message as a string.

IFieldType

Namespace: ****

IFormValueAggregator

Namespace: Lisa.Core.Domain.Interfaces

The SubForm component allows you to group multiple form components together and extract and aggregate values from those components and place them into a single field in the parent form, which could be another SubForm component, or any other form component such as the Document form or Generic form components.  How those values are aggregated into a single value is controlled by the selected IFormValueAggregator implementation.  Veva contains various implementations, such as the "Concatenate values" aggregator which simply concatenates values with the specified separator.

Instead of implementing the IFormValueAggregator directly, you can also inherit the BaseAggregator and override the GetValues() method.  The BaseAggregator gives you access to the ReadValue() method which makes it easy to read a certain value from the form context.

IPageRequestHook

Namespace: Lisa.Core.Domain.Interfaces

All registered IPageRequestHook implementations are executed each time a page is requested on the front end.  By implementing a Page request hook, you can access the current pageRequest object to do various things, such as add links to custom JS/CSS files, modify page properties for the request etc.  There is one method you need to implement, which is the OnRequestAsync() method.  You also need to define a OrderIndex which is a number.  This controls the order in which registered page request hooks are invoked.  The page request hook with the lowest number will be executed first.

IPropertyEditorResolver

Namespace: Lisa.Core.Domain.Interfaces

The IPropertyEditorResolver interface is used by Veva to determine which UI editor component is shown to the user for each type of property in the system.  This applies everywhere in the system where the user is managing settings for things, such as components, website settings, page settings and so forth.  Veva includes standard property editor resolvers which take care of all basic types such as strings, integers, booleans etc. and also some advanced types such as enums, and even various complex objects.

If you have a special use case, where you have a property which you'd like to create your own UI editor component for, you can implement your own IPropertyEditorResolver.

ISettings

Namespace: Lisa.Core.Domain.Interfaces

The ISettings interface is used to populate the settings UI in Veva, where users can configure various aspects of the system.  Any module which needs configuration from the user can provide it's own implementation of the ISettings interface and each implementation will render a new tab in the settings UI where the user can fill in information.  Each ISettings implementation has a scope, which can be "global", "website" or "user".  If the scope is "global", it will be shown in the global settings dialog in Veva.  If the scope is "website", it will be shown under the website settings in the website UI in Veva, where each website has it's own set of configuration values.  If the scope is "user", then it will be shown under the user profile UI in Veva, where each user has it's own set of configuration values.

Each implementation has to return a name, which is usually just the type name of the class.  The RequiresAppRecycle bool determines if the settings require the web application to be restarted after each change.  If this is true, Veva will show a notification to the user that changing the settings will not be reflected until after a restart of the web application.  Finally there's the scope as mentioned above.

Then you simply need to add public properties to the class, marked with the [EditorBrowsable] attribute.  Those properties will be reflected and shown to the user.

INavigationProvider

Namespace: Lisa.Core.Domain.Navigation

The INavigationProvider is used by the navigation component to display the site navigation, usually based on the pages which have been created on the website.  To display pages, the PageNavigatorProvider (which is an implementation of the INavigationProvider) is used.  If you would like to display custom data in the navigation component, you can implement your own INavigationProvider.