IContentResolver

Users can paste content into the search-field which is at the top of the Add Content dialog when they are adding content to pages in Veva.

When users paste data into that field, Veva passes that data through all registered content resolvers to determine if the pasted content can be recognized as a certain type of content, and if so, which components should be suggested for the user.

For example, if you paste a generic URL into the field, Veva will recognize it's a URL and will suggest the Link component.  Furthermore, if the URL is a certain type of URL, such as a Youtube video URL, Veva will also recognize that and in addition to suggesting the Link component, the user will be given the option to insert the Youtube component and the video ID will be extracted from the URL and the component will be configured to show that video.

This functionality is implemented using content resolvers.  Each content resolver needs to be able to tell if it supports the pasted data, which is the CanResolve() method and if it returns true, the GetContentMeta() method will be called which returns a ContentResolverResult which tells Veva which component(s) to insert and with which property values, among other things.

If you have a specific scenario where if users paste a certain type of content into the search field and you want a specific component to be suggested, you can implement your own content resolver.

Interface declaration

public interface IContentResolver
{
	string Name { get; }

	int Priority { get; }

	bool CanResolve(string type, string data);

	public ContentResolverResult GetContentMeta(string type, string data);
}

Example

This example of a Content resolver implementation is the "Iframe content resolver" which recognizes when valid URLs are pasted into the search field and will present the "Embedded page" component as a suggestion.  If the user clicks that suggestion, the Embedded page component will be inserted into the page, and the "Url" property will be initialized to the pasted URL.

In many cases there will be multiple resolvers that claim they support content.  For example, if the user pastes a URL, the generic Link resolver will suggest the Link component, the Iframe content resolver will suggest the Embedded page component, and if the URL is a specific type of URL which other resolvers recognize, they will also show their suggestions and finally the paragraph and heading components will also be shown.  If you are implementing your own resolver to recognize a certain URL as an example, and you only want to show that suggestion to the user, then specify a high priority for your resolver (i.e. 10000) and in the ContentResolverResult, set the StopResolving property to true.  That will prevent processing of any other resolvers.

public class IframeContentResolver : IContentResolver
	{
		public string Name => "Iframe content resolver";

		public int Priority => 1100;

		public bool CanResolve(string type, string data)
		{
			data = data.Trim();

			return Uri.IsWellFormedUriString(data, UriKind.Absolute);
		}

		public ContentResolverResult GetContentMeta(string type, string data)
		{
			ContentResolverResult result = new ContentResolverResult();

			if (CanResolve(type, data))
			{
				return new ContentResolverResult()
				{
					Name = "Embedded page",
					Description = "Inserts the given URL as an embedded page component (iframe)",
					Content = {
						new ContentMeta()
						{
							ComponentId = Lisa.Modules.StandardViewComponents.Components.EmbeddedPage.Id,
							Properties = new Dictionary<string, object>() {
								{ "Url", data },
							},
							PreviewMarkup = string.Empty
						}
					}
				};
			}		
			return result;
		}
	}

Registration

This is how the implementation is registered into the DI container in Veva, this should be done in your module config file (The class which implements IModule).

public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
	services.AddScoped<IContentResolver, IframeContentResolver>();
}