[PLUGIN] - Dynamic Content Editor (mail merge with tags!)

Hi all,

I’ve just released a plugin which is designed to generate dynamic content in a similar way to how mail merges work.

You can iterate through a list of things and use the data from the fields to insert into your content using tags as replacements. For example, if you had 200 users in your database and wanted to send them all the same message (or generate the body of an email) but change certain things like the name, email, phone number etc then you can do that by inserting tags within the initial content.

Each tag is read and replaced with each row of data until you end up with a generated list of 200 raw text messages all with individual content included.

If any of your fields contains another list of things, then you can specify a field for the secondary list and it will retrieve the data for each item there too. Works slightly differently depending on whether a list of standard Bubble fields are detected or whether it’s a custom user fields but the result is the same which is a comma separated string list of those field values for each data type in the list.

Dynamic content can be written in either plain text or HTML if you prefer. You can feed the content in from other sources and then let the plugin generate whatever you like from it.

It’s quite powerful really!

PLUGIN
Dynamic Content Generator Plugin | Bubble

DEMO*
https://paul-testing-4.bubbleapps.io/dynamic_content

The image below is just a representation of the data available in the User table where some of the fields are made editable. Each field has a tag assigned to it which you stipulate through the element field options. Feel free to add/edit the data on this demo page because if there’s a loads of records it’ll be a nice performance test.

The configuration for the element is like so, where up to a maximum of 15 fields can be configured. All documentation fields are populated describing how it works.

Below outlines a list of all events, actions and documentation.
You can view the editor here: Dynamic Content Editor | Bubble Editor



ELEMENTS

Dynamic Content
This visual element is required to be placed somewhere on your page.

  • Data type
    Select your data type so you can see a list of fields to choose from below.

  • List of records
    This should be a list of items for your selected data type. Content will be generated X amount of times, where is X is the count on this list.

  • Replace null values
    If a null value (or empty field) is found then you can replace it with some text of your choice here.

  • Dynamic content
    This is your content, it can be standard text or HTML. You can use this to write a document, an email, an invoice etc and insert tags which represent the fields configured below. These will be replaced with the corresponding field values in your list. The output will be a list of texts where each text will be ‘this content field’ with all the replacements made.

  • Custom content 1, 2, 3
    Use these fields to create your own custom list from data within your list of records. For example, this could be used to create a unique subject for emails, where you may want to specify the user’s name like “Welcome [{first_name}]” or “Invoice [{invoice_number}] details”. When using tags to represent any data, it must be configured in one of the fields below for this to work. Items numbers in this list will match up with the item numbers in the list of content. If no data is available then it will be replaced with the null value option above.

  • The 3 fields below (all for Field 1) are duplicated through the editor options so you have up to a maximum of 15 fields to configure. They'll be a set for Field 2, Field 3, Field 4 etc.

  • Field 1
    Select a field where data will come from.

  • Field 1 List value
    If Field 1 is of another list of data types, then enter the field name that contains the data you want to return. This will tell the plugin what field to pull the data from for each item in this secondary list. Please don’t point this to another list of things, it’s not coded to go another level deep with lists! Data is returned in a comma separated string. The field name is case sensitive.

  • Field 1 Tag
    This is the replacement tag that will be looked for in the content and replaced by the value coming from Field 1, keep this to something unique. The tag is case sensitive!


EVENTS

  • A Dynamic Content - has finished generating
    Triggered when the content has been generated.

ACTIONS

  • Generate content
    This action will generate the content. There is no configuration for this.

EXPOSED STATES

  • Content
    This is a list of texts, where each item will contain the generated dynamic content.

  • Custom content 1
    This is a list of texts, where each item will contain the generated custom content 1 value.

  • Custom content 2
    This is a list of texts, where each item will contain the generated custom content 2 value.

  • Custom content 3
    This is a list of texts, where each item will contain the generated custom content 3 value.

As far as events, actions and states go I’ve kept this relatively simple, but if anyone wants additional functionality added then let us know!

Regards,
Paul!

12 Likes

Awesome! Nice work, @pork1977gm

1 Like

Wow, this is amazing! Great work @pork1977gm

I can’t wait to use this with my app!

Thank you both

To improve the usability of this with regards to actually sending an email and using the contents of each item processed, the following things have been added.

ELEMENT FIELD OPTION

  • Delay
    Use this to set a delay between loop cycles since this process can run faster that the time allowed to trigger the ‘has processed an item’ event. Defaults to 100ms.

  • Field Conditions (JavaScript)
    Use this field to write a conditional block of JavaScript which will be used to further manipulate the tag replacement. For example, whilst looping through the supplied list of records, if this field value were to contain the name “cat” and you wanted to replace it with “dog” then you could write this as:
    if ( [*tag1*] = "cat" ) { [*tag1*] = "dog" }.
    Another example might be that you want to change a name to read “Dear name,” and if no name is present then display “Hello,” instead. To do this, the condition would read:
    if ( [*tag1*] ) { [*tag1*] = "Dear " + [*tag1*] + "," } else { [*tag1*] = "Hello," }. The variable name is always the tag name which is also case sensitive.


EXPOSED STATES

  • Current content item
    Contains each item’s ‘Content’ value as the main list of records are processed.

  • Current custom content 1
    Contains each item’s ‘Custom content 1’ value as the main list of records are processed.

  • Current custom content 2
    Contains each item’s ‘Custom content 2’ value as the main list of records are processed.

  • Current custom content 3
    Contains each item’s ‘Custom content 3’ value as the main list of records are processed.

  • Current field 1
    Contains each item’s ‘Field 1’ value as the main list of records are processed. If this field contains another list of items then it will contain a comma separated list of values.

  • Current field 2
    Contains each item’s ‘Field 2’ value as the main list of records are processed. If this field contains another list of items then it will contain a comma separated list of values.
    .
    … Through to …

  • Current field 15
    Contains each item’s ‘Field 15’ value as the main list of records are processed. If this field contains another list of items then it will contain a comma separated list of values.

  • Current thing
    Contains each item’s “thing” as the main list of records are processed.


EVENTS

  • A Dynamic Content - has processed an item
    Triggered each time an item has been processed.

When the event is triggered, all of the above states will be populated with data coming from the current iteration of your main list of records you supplied. If for example, you wanted to send an email to each of your users, you could use Bubble’s Send email action within the event and utilise the states to get the data for each record. A list containing 15 items for example, would trigger the event 15 times and you could access the data for each particular item by using the states which get updated upon each cycle.

The field states hold the direct data from your database (as configured in the plugin element) whilst the content states are more dynamic which would ideally contain the Body of an email with any replacements made.

The concept of this plugin is to be able to loop through any list of things (client side) whilst having the ability to take any data from each loop cycle and inject it into the body of a larger piece of data.

Hoping some of that makes sense because it’s a little awkward to explain.

It becomes incredibly powerful when you have thousands of items in your initial list of records and you start manipulating the data.

Paul

1 Like

Hi, is this plugin like a native version of Mailchimp and Sendgrid?

I suppose yes, I never thought of it like that but you could use it with saved templates in your database and then use those templates to send emails with all the replacements made inside them.

I think I might amend the demo page with a bunch of pre-set templates so it’s easier to see what it does.

3 Likes

Impressive plugin!

Would it fit my use case?

  1. Admins create templates with fields from multiple datatypes.
  2. A User selects a template to use for a document which gets populated with data from the database. The document will not be linked to the template – merely a copy of the template. I do not need to get a list of docs, just one doc each time a template is used.
  3. Parts of the document (the copied template) content can be changed by the User, both template text blocks and data from the database. What is allowed to be changed is set by the Admin on the template level. Changing doc content can be inputing a text, date, number or selecting something from a lookup table (aka from the database).
  4. When the User is done editing the document it is saved to the database and a PDF is generated, an potentially sent to DocuSign.

Do you see your plugin fitting into this and being possible to build around to accommodate for my use case?

Cheers, Peter

Hi Peter,

Yes, pretty sure all that is very possible, maybe without the use of this plugin in fact. Probably best to jump in and start designing it then if you run into any problems along with way (if using the plugin) just give us a shout and I’ll try and help out where I can. Try before buying outright though.

Paul

1 Like

Thanks for coming back on this.

My main thought is on how to get hold of the datatypes names and fields as you do and the get data from them.

I’ll get back to you on this Pete, I need to go check a few things in the editor, fix an issue in the demo page then remind myself what I did! I’ve not looked at the plugin for a bit so bare with me, I’ll answer your question soon.

1 Like

Hi @philledille,

Few things for you here.

The demo page had a couple of things not working with it, they’re now fixed. I hadn’t realised the tags dropdown was empty and the HTML content wasn’t showing correctly.

I’ve made a few adjustments which I hope will help.

For each of the 15 field selections in the element’s options, there’s now an associated data type and name state included. They look like this:

image

image

These states are populated as soon as the page loads (although they may take a second).

You should be able to reference these to get the actual field names and data types for whatever fields are selected through this section…

image

There are a couple of things to be aware of…

When bubble shows us the field names through the editor, these are simply “display names”.
As far as I can tell there is no way to get the actual display name through the plugin. Every table name and field name has an associated “internal name” (it’s a static name), so by that I mean if you were to create a field called “My Record Count” then the name of it reported will be “My_Record_Count” (spaces replaced with underscores).

If you were to later rename that field to “My Data Count” then the internal name stays the same, it never changes so it will always be returned as “My_Record_Count”. If you want the returned field names to always match what you see, then you need to create your tables with no spaces and never rename them. I don’t think there’s a way around this, hope that makes some sort of sense.

If anyone knows of a way to get the actual field display names then please let me know!

The data types I can handle accordingly, so they should always be reflected. A data type of text will return text, number return number and a list of something returns exactly that, so it looks like this.

You can see in my users table, the fields called “phone” and “list of texts” started off being called “phone1” and “cars_list” so those are the names returned.

I’ve pushed an update anyway so hopefully it will help if you need this. If you end up using these, let us know how you get on and if you get stuck then feel free to shout and I’ll do what I can to help out.

Paul

Thanks so much for creating this plugin, I’m building a whitelabbeled CRM for the recruitment space, we’re using postmark to send batch emails out to clients, any idea how I would set up this plugin to run in a backend workflow?

I’ve purchased it and have been playing around with it all day but haven’t got far.

Hi @john40

No probs at all, hope it’s useful for you.

So there’s no backend server side actions in this, it’s all run client side. But once the content has been generated and it’s sitting as a list of texts within the “Content” state, then you should just be able to trigger one of your backend workflows that should be setup with a parameter to accept a list of texts. So you send the data in the “Content” state to your backend workflow. Make sure you do that inside the “has finished generating” event.

From there, you should be able to process it further.

Is that what you wanted to know?
Paul

1 Like

Hey, I love the concept! And have got the plugin as it suits my use-case.
I’m building a referral management product and want to allow my users to dynamically address their clients.

However, I’m running into some trouble while implementing the plugin. I’m a little confused on how to actually implement it. Could you please help me with it?

Best Regards

Yep sure, PM me some screenshots showing how you have it setup and I’ll try and help you figure it out.

I’ve been looking for this feature for days.

Do you have something you can also use in word? (docx)

Hey @rcgrcontato8

Afraid I don’t, but if you can give us some more info as to what you mean here, I might be able to help.

Paul

Thanks for the feedback.
I’m creating a property leasing management platform for landlords and one of the modules is the automation of documents (contracts, notices, cancellations…).
I want to make it as dynamic as possible for my clients.

I have the documents in word and I want to fill in some information dynamically.

Ha, I’m Brazilian.

I see. I’m afraid it won’t do that. The structure which makes up a docx file is xml based and it’s a complex job to do what you need. If you have a docx file, just rename it to .zip and open it up. You’ll see it’s not just one file, there’s a few xml files which make up what you see when you open it inside the Word.

The plugin doesn’t have the code required to read or manipulate it.

2 Likes