This page will walk you trough a change log system for a multiple applications.
Welcome to our tutorial on building a robust logging system for your applications using rich text and templates! In the world of application development, logging plays a pivotal role in tracking changes, capturing important information, and maintaining a comprehensive record of activity.
Whether you're building a project management tool, a customer relationship management (CRM) system, or an inventory management solution, implementing an effective logging system is essential for ensuring accountability, transparency, and reliability. Access, audit, and change logs serve different purposes. Access logs document resource requests, audit logs monitor security events, while change logs record data modifications.
In this tutorial, we'll guide you through the step-by-step process of setting up a logging system using rich text and templates. You'll learn how to capture and store critical information, track changes over time, and present data in a clear and organized manner. By the end of this tutorial, you'll have a fully functional logging system tailored to your specific application needs.
The logging system operates by utilizing a transient single-select field that include all actions deemed loggable. When a loggable action is initiated, the system sets the transient field to reflect the action and enters the "Log Before Action" sub-flowchart. This sub-flowchart adds a new row to the log list, assigns field values and fills in the "Before" rich text field with the log fields template. Subsequently, the user progresses its database action.
Prior to finalizing the action, the system incorporates the "Log After Action" sub-flowchart. Within this sub-flowchart, it integrates the after-action template into the rich text field and ensures simultaneous saving of both the user's loggable action and associated log items. This synchronized approach guarantees preservation of logged data upon action commitment.
Log items should always be saved in UTC, you can display timestamps in local time for user convenience but it should be stored in UTC format. This practice ensures consistency and accuracy across different time zones
The first step is to make the Log data list, this will be the list used to record and save the changes made.
Change Log
Reference to changed item
Reference to signed in user
After Action Rich Text
Before Action Rich Text
Date and Time of change (UTC)
Log Action (Single-select)
Name of Changed Item
Name of User
Alternatively, the last two items can be derived using the references in the first two fields. Opting to save and utilize text-based name fields can enhance performance in the Log management screens and ensures the referenced person cannot change.
You will also need to make a concept in the concept tab of the resource pane, this concept describes logged actions. As an example this can be:
New Item
Edit of General information
Edit of Specific information
(soft) delete
Full delete
The flows handling the logging need a few transient fields to store some information used in the logging process.
Log Action (Single-select)
Reference to changing item
And a few transient field for searching the log list:
Name User (text)
Date Action (date time)
Log Action (multi-select)
To create the log template, first, add a reference component to the canvas. Within this reference component, incorporate a table with a column for the field names and a column for the corresponding values. If your application features multiple screens with varying editable fields, consider making templates for each screen, reflecting the specific fields available for modification. In this tutorial, we utilize one template for general information and another for all fields within the main data-list.
The properties of this table are default display mode, no column or row as header and no borders but this is up to the developer.
This solution is tested for 150+ fields and a repeater in one template without any issues.
This flow is very simple and will be the management screen of the logging system. The first step is resetting the Filters with a assignment node followed by the interaction node for the overview. Connected to the Log overview there is another interaction node for the log details page, here we show the log item details and see saved fields.
The details page shows some information about the log item with below it the rich text fields for the before and after situation. With these shown next to each other you can see changes immediately.
There are two flows that actually do the work, the before change log flow and the post change log flow. In the first flow a new row is created in the change log, the information fields are filled and the template is written to the before action rich text field.
In the second flow the details are checked, the time can be updated and the post change rich text field is filled with the template again but this time with the changed information. Optionally you can also end with a save node to commit the changes then and there and save the change log item at the same time, know that with the save node ALL changes are committed.
The Write template to rich text node has the above picture as template, these are templates for each possible action that can have different fields to be logged. In this example the top one is when somebody edits a screen with access to all fields in from the main list, with the second template only for when a user edits the general info page. The transient field Log Action made earlier is used to check the conditionals and which choose the right template for the right screen. The same templates are used for the before and after flow.
In this section, we'll explore the practical implementation of the log entry flows discussed earlier into the core functionalities of your application. Specifically, we'll focus on how these flows are integrated into the junctures where changes are made to items within the main list that need to be logged.
It is important for this part to know your application and analyze it if the application is less known. Go trough every flow where a user can:
Create an item
Change an item
(soft) Delete an item
This can also be checked using the find usages on the data list AND its fields or going to the preview of the application and use go to flow from the debug menu on every save or delete button. The change log depends on doing this part completely so this is an import step to do properly.
When a log trigger moment is found you add an assignment node to set the Log action transient field immediately after the start node. The value of this field will depend on the action in the main so it cannot be part of the sub-flow creating the log. After the assignment node you add the sub flow Log before action flow and connect the sub-flow back into the main flow functionality. Before any changes are saved but after the interaction node you add the post change flow, then connect this flow the the save or end node.
When all steps are finished the result can look like this:
Logging Multiple Lists: Expand the logging system to handle changes from multiple lists. Implement a mechanism to differentiate changes from different lists and ensure that the appropriate template is applied to the log entry's rich text field. Add a reference field to the log items for each list and keep track of which list you are changing before entering the make log flows.
Data Retention Policy: Consider establishing a data retention policy to manage the duration for which log items are retained. Develop a cleanup process that runs periodically, based on either a set number of years or a specified number of items, to prevent database overload and maintain storage efficiency.
File Management: Avoid storing files directly within log items to mitigate storage space usage and potential performance impacts. Implement a file management system that links files to log entries without duplicating them, thereby minimizing storage requirements and optimizing processing time.
Performance Optimization: Keep the log flows concise and efficient to avoid performance degradation. Be mindful of the complexity and extent of the log flows, ensuring they do not excessively impact system performance.
Learn to work with the WEM Platform.
You may need a WEM User Account to fully work with WEM Tutorials. If you don't have a WEM account yet, you can create your account in MyWEM.
Many of the tutorials require some level of familiarity with the WEM terminology and the use of basic functions. The CRM Application developed as part of the First Application tutorial guides you to build a basic CRM application (Customer Relation Management) from scratch in a few easy-to-follow steps, independently and at your own pace.
Discover how to create a placeholder system for dynamic text replacement in emails, notifications, and more.
In this guide, we'll explore how to create and implement a placeholder system that lets users define placeholders and seamlessly replace them with actual values. Whether you're managing email templates, internal notifications, generating dynamic text, or customizing user interactions, understanding and implementing placeholder systems can enhance efficiency and flexibility in your applications. Let's dive in and unlock the full potential of placeholders!
The placeholder system operates through a simple yet powerful mechanism. At the core of the placeholder system is the replace
function, which scans through text for predefined placeholder tags and substitutes them with corresponding values. These tags are sourced from a list of placeholder items stored in the database. Replacement values can be set in one of two ways: either by end users during runtime or by developers in the modeler using expressions.
Placeholder values can be defined in two ways:
User-Defined Values: End users can set placeholder values during runtime. This approach allows for dynamic and flexible content based on user input.
Calculated Values: Developers can define placeholders with values calculated using expressions. This optional extension enables placeholders to have dynamically generated values at the moment of replacement, providing a more automated and contextual update.
This list contains the placeholders and their corresponding replacement values.
PlaceholderLabel
ReplacementFunction (Calculated field) (optional)
ReplacementValue
In this example we also use a list of email templates:
Subject
Message
This list stores the generated emails after placeholders have been replaced with actual values:
Subject
Sender
Receiver
Message
When using the calculated ReplacementFunction
for dynamic values, you will also need to create a concept for each optional calculated value. In this example we will use the following:
Placeholders (concept set)
Date
Time
Full Date and Time
Current Projects Count
Also, add a concept property called TagLabel
to the placeholder concept set. This will enable you to set a TagLabel
for each concept. This allows the user to set the full PlaceholderLabel
without retyping it, reducing errors from incorrectly copying the PlaceholderLabel
property.
Do not use punctuation marks or non-text characters in {PlaceholderLabel}
names. These characters have corresponding rich text tags that can break the replace function, as the values will not match correctly. This problem occurs when using plain text values and rich text as the source text.
For example, Recipient's
in plain text appears as Recipient's
in rich text. This difference can be observed by enabling the source option in the rich text input field's toolbar.
How your screens will look and feel highly depends on the specific implementation. For this guide we will make some screens and flows to explain how it works but are not real world implementations.
This page will serve as the main dashboard where you'll see the available email templates, the emails with replaced values, and the optional placeholders. It will also have buttons for key actions like creating emails with replaced placeholders and accessing the template and placeholder management page.
This flow revolves around the Manage templates and placeholder interaction screen. Here, we create, edit, and delete the placeholders or email templates. In the top right, the New placeholder node can be found. Here, we set the PlaceholderLabel
and PlaceholderValue
with a simple form. At the bottom right, there is a sub-flowchart for setting default placeholders. You typically do this only the first time an application is run.
Again, on the left, we have the email templates with the subject and message as input fields and a button to add a new one at the top. On the right, we show a list of all placeholders and the options to reset to default or add a custom one. This gives users the ability to make/edit template texts and edit/add placeholders in the runtime letting users set it up.
PlaceholderLabel
In this flow, several key processes are nested: first, there's the email template loop. Within this loop, there's the placeholder loop, which iterates through each placeholder. A decision node within the placeholder loop determines if the conditions are met to continue through Yes or No. This inner process repeats until all placeholders are processed. Then, the flow moves to the next email template, repeating until all templates are complete. The email template loop starts with adding a new email row and setting the subject and message fields with the template. The flow then continues into the placeholder loop.
The following expression is part of the decision node in the placeholder loop:
When this statement is true, the PlaceholderLabel
is replaced with the ReplacementFunction.
when false, the ReplacementValue
is used. The assignments part of the placeholder loop is the core business part of this flowchart. Here, the email message is assigned with the replacement function or value, replacing the original text. This is done with the following expressions:
Core Concepts:
Placeholder System: Operates through a replace function that scans text for predefined placeholder tags and substitutes them with values from a database. Replacement values can be either user-defined during runtime or calculated by developers using expressions.
Determining Placeholder Values:
User-Defined Values: Set by end users at runtime for dynamic content.
Calculated Values: Defined by developers using expressions for automated and contextual updates.
Data Model Preparation:
Placeholder List: Contains placeholders and their corresponding replacement values.
Email Template List: Stores email templates with subject and message fields.
Created Emails List: Stores generated emails after placeholder replacement.
Flows and Screens:
Mail Home Page: Main dashboard showing email templates, mails with replaced values, and placeholders. Includes buttons for creating mails and managing templates and placeholders.
Manage Templates and Placeholders: Allows users to create, edit, and delete placeholders or templates, and set default placeholders for initial application setup.
Replacement Flow:
Email Template Loop: Iterates through email templates.
Placeholder Loop: Nested within the template loop, replaces placeholders based on a decision node that evaluates whether to use calculated or static values.
Reflecting on the placeholder system we've implemented, it offers a solution for inserting static or dynamically calculated results into user-defined texts. This system accommodates both fixed and computed placeholder values, making it adaptable for various applications. By going through text templates and replacing placeholder tags with the appropriate values, users can effortlessly generate contextually relevant content.
Notifications Internal notifications can be enhanced by using placeholders for descriptions or titles.
Email Applications that send standardized emails to lists of people.
Forms and Surveys Questionnaires that are more personal or include current time/date information
Documents Template documents can use placeholders for variable information.
PlaceholderLabels
The concepts made are already used to find the right ReplacementValue
for a function, but they can also help users with adding placeholders to texts.
On the user side of managing the template text, add buttons for each concept/placeholder option. This can be done with a list of 'default placeholders' representing the concepts in a repeater:
When a concept is selected, a flow runs that adds the concept:'TagLabel'
property to the template text.