Добавка Шаблон Процесор

Въведение

Процесорите за шаблони се създават от класове, които наследяват интерфейса ITfTemplateProcessorAddon. Tefter.bg сканира за тези класове по време на стартиране и ги прави достъпни за потребителите. Процесорите за шаблони също изискват типизирани компоненти за техния жизнен цикъл.

Типичният процес за създаване и разпространение на процесор за шаблони за Tefter.bg включва разработване на Razor библиотечен проект и след това разпространение на резултата като NuGet пакет. За практически примери можете да прегледате проектите на съществуващи процесори, създадени от нас, като:

Text Content Processor GitHub
Text File Processor GitHub
Excel File Processor GitHub
Word File Processor GitHub
Email Processor GitHub

Проект на процесор за шаблони

Обичайната структура на проектите е следната:

Template processor project

Клас на процесор за шаблони

Това е обичайната структура на метод на процесор за шаблони и неговите свойства и методи за обратно извикване.

using System.Text;
namespace WebVella.Tefter.Seeds.SampleTemplateProcessor.Addons;
public class SampleTemplateProcessor : ITfTemplateProcessorAddon
{

	public const string ID = "9754c7dc-80da-4b65-bf10-eb441d370fe2";
	public const string NAME = "Sample content template";
	public const string DESCRIPTION = "scrambles text";
	public const string FLUENT_ICON_NAME = "ScanText";
	public const TfTemplateResultType RESULT_TYPE = TfTemplateResultType.Text;

	public Guid Id  { get; init; } = new Guid(ID);
	public string Name { get; init; } = NAME;
	public string Description { get; init; } = DESCRIPTION;
	public string FluentIconName { get; init; } = FLUENT_ICON_NAME;
	public TfTemplateResultType ResultType  { get; init; } = RESULT_TYPE;

	/// <summary>
	/// Called when template preview result is submitted for generation.
	/// Sometimes when the user selects template from this processor, 
	/// it needs to provide input needed by the processor to generate the final result.
	/// This method validates this input
	/// </summary>
	public void ValidatePreview(
		TfTemplate template,
		ITfTemplatePreviewResult preview,
		IServiceProvider serviceProvider)
	{
	}

	/// <summary>
	/// Presented to the user when it wants to use this processor with data.
	/// </summary>
	/// <returns></returns>
	public ITfTemplatePreviewResult GenerateTemplatePreviewResult(
		TfTemplate template,
		TfDataTable dataTable,
		IServiceProvider serviceProvider)
	{
		var result = (SampleTemplateResult)GenerateResultInternal(
			template, dataTable, serviceProvider);

		return new SampleTemplatePreviewResult
		{
			Errors = result.Errors,
			Items = result.Items
		};
	}

	/// <summary>
	/// Method generating the final result
	/// </summary>
	/// <returns></returns>
	public ITfTemplateResult ProcessTemplate(
		TfTemplate template,
		TfDataTable dataTable,
		ITfTemplatePreviewResult preview,
		IServiceProvider serviceProvider)
	{
		return GenerateResultInternal(template, dataTable, serviceProvider);
	}

	/// <summary>
	/// Called when user submits settings
	/// </summary>
	public List<ValidationError> ValidateSettings(
			string settingsJson,
			IServiceProvider serviceProvider)
	{
		return new List<ValidationError>();
	}

	/// <summary>
	/// Called in transaction with the creation method, but before it.
	/// </summary>
	public List<ValidationError> OnCreate(
		TfManageTemplateModel template,
		IServiceProvider serviceProvider)
	{
		return new List<ValidationError>();
	}

	/// <summary>
	/// called after the creation method outside its transaction
	/// </summary>
	public void OnCreated(
		TfTemplate template,
		IServiceProvider serviceProvider)
	{
	}

	/// <summary>
	/// Called in transaction with the update method, but before it.
	/// </summary>
	public List<ValidationError> OnUpdate(
		TfManageTemplateModel template,
		IServiceProvider serviceProvider)
	{
		return new List<ValidationError>();
	}

	/// <summary>
	/// called after the update method outside its transaction
	/// </summary>
	public void OnUpdated(
		TfTemplate template,
		IServiceProvider serviceProvider)
	{
	}
	/// <summary>
	/// Called in transaction with the update method, but before it.
	/// </summary>
	public List<ValidationError> OnDelete(
		TfTemplate template,
		IServiceProvider serviceProvider)
	{
		return new List<ValidationError>();
	}
	/// <summary>
	/// called after the delete method outside its transaction
	/// </summary>
	public void OnDeleted(
		TfTemplate template,
		IServiceProvider serviceProvider)
	{
	}

	private ITfTemplateResult GenerateResultInternal(
		TfTemplate template,
		TfDataTable dataTable,
		IServiceProvider serviceProvider)
	{
		var result = new SampleTemplateResult();


		var tfService = serviceProvider.GetService<ITfService>();

		if (string.IsNullOrWhiteSpace(template.SettingsJson))
		{
			result.Errors.Add(new ValidationError("", "Template settings are not set."));
			return result;
		}

		var settings = JsonSerializer.Deserialize<SampleTemplateSettings>(template.SettingsJson);
	
		try
		{

			foreach (TfDataRow row in dataTable.Rows)
			{
				var item = new SampleTemplateResultItem();
				item.NumberOfRows = 1;

				//foreach row scrables values of TEXT type and append them to string builder
				StringBuilder sb = new StringBuilder();
				foreach (var column in dataTable.Columns)
				{
					if (column.DbType == TfDatabaseColumnType.Text)
					{
						if (row[column.Name] == null)
							continue;

						var scrabledText = Scramble( row[column.Name].ToString());
						sb.Append(scrabledText);
					}
				}
				item.Content = sb.ToString();
				result.Items.Add(item);
			}
		}
		catch (Exception ex)
		{
			result.Errors.Add(new ValidationError("", $"Unexpected error occurred. {ex.Message} {ex.StackTrace}"));
		}

		return result;
	}

	private static Random rand = new Random();

	private string Scramble( String str)
	{
		var list = new SortedList<int, char>();
		foreach (var c in str)
			list.Add(rand.Next(), c);
		return new string(list.Values.ToArray());
	}
}


Компонент DisplaySettings

Това е компонент, който се използва за показване на персонализираните настройки на процесора за шаблони. Той трябва да наследи интерфейса ITfScreenRegionComponent<TfTemplateProcessorDisplaySettingsComponentContext>.

Компонент Help

Това е компонент, който се използва в модалния прозорец за помощ, за да насочи потребителя как правилно да конфигурира шаблона. Той трябва да наследи интерфейса ITfScreenRegionComponent<TfTemplateProcessorHelpComponentContext>.

Компонент ManageSettings

Това е компонент, който се използва в модалния прозорец за управление на настройки, за да позволи управление на персонализирани настройки на шаблона. Той трябва да наследи интерфейса ITfScreenRegionComponent<TfTemplateProcessorManageSettingsComponentContext>.

Компонент ResultPreview

Това е компонент, който се използва в модалния прозорец за преглед на резултатите, за да представи очаквания резултат на потребителя, както и да получи необходимата обратна връзка от него. Той трябва да наследи интерфейса ITfScreenRegionComponent<TfTemplateProcessorResultPreviewComponentContext>.

Компонент Result

Това е компонент, който се използва в модалния прозорец за резултати, за да представи информация за резултата от обработката на шаблона. Той трябва да наследи интерфейса ITfScreenRegionComponent<TfTemplateProcessorResultComponentContext>.