From the time we started building Dropsource, we set our sights on opening up our platform to make it possible for our community to contribute to it. As a result, we made the conscious decision early on to make the entire platform plugin based, allowing for high degrees of extensibility. When I say “plugin based,” I mean all of the app functionality users see in the editor is defined and the source code is generated by plugins.
A plugin based architecture has provided many benefits. Namely, it allowed our team to add the core functionalities we expose to the entire community, and also allowed us to add custom functionality for users with more nuanced requirements for their app. It has also let us focus our development of the Dropsource editor to be an interface that defines the concepts that plugins can utilize and then to ultimately present and allows users to work with our plugins.
This design decision has allowed us to rapidly add functionality to the editor and quickly respond to user needs. Through this blog series, I will open up more about what plugins are, how they are built in Dropsource, and our long-term vision for building a plugin system our members could contribute to.
What is a Plugin?
At its core, a plugin represents a discrete app functionality. A plugin can take many forms, but currently they are limited to pages, page components (navigation / app bars and tab bars), elements, actions, events, and settings. Behind the scenes, plugins are made up of definition files and template files. These files work together to make plugins work from from end-to-end within the platform, all the way from the editor to the generated truly native source code.
The main responsibility of a definition file is to tell the editor what options to present to the user. Whether the plugin is an element, action, or a setting, the definition file defines the information required by the plugin to generate the native source code. When a user fills out all of the details in the editor, that data gets saved to the user’s project. When the user tests their app, that data gets passed to the plugin template to generate the source code.
Definition files are declared in a JSON format and define the values users see on the editor. So, for element plugins, definition files define the properties, events, canvas rules, default constraint values, as well as any documentation required for the element. Below is an example of an element definition file:
For action plugins, the definition files define the parameters, events, and action data used by the editor. Below is an example of an action definition file:
This pattern of implementing a definition file with a corresponding template file is how all functionality in Dropsource is defined. Now that I’ve covered how definition files are used in the editor, I will discuss how templates utilize the data from the definition files to generate the source code for the app.
The main responsibility of template files is to generate source code according to how a user configures the plugin in the editor. Template files are written using a popular templating language called Freemarker. Template files take the data for each instance of a plugin in a user’s project, puts it into the context of where the plugin is being used within the app, and generates the source code to be used by the whole app. This is a simplified explanation of how template files work inside of Dropsource; generating truly native source code is a very complex task, but how that process works is something I’ll write about in a future post.
Aside from using the data given to the template by the editor, templates are responsible for figuring out the context in which it writes the code. By context I mean, where in the app the code is being written. Is it being written into a page, is it being written in to an app life cycle event, or is it being written into a callback method that is not in the same scope as the original action? These are all complex decisions that plugins have to work through every time they contribute code to the app. To make these decisions easier on our plugin developers, Dropsource has an internal plugin API that assists with letting plugins contribute code that works in all of these varying contexts. There is a lot of functionality baked into the plugin API, but most commonly, the API is used by the developers on our team to:
- Generate key paths (code needed to access specific references) to elements and other data within our system
- Uniquely name variables and classes within app
- Store and share data between different plugins
- Access any data or object from the users project
Below is an example of a template file that is used to generate the code for an element plugin:
In future posts I will discuss more details about how templates work with definition files to generate source code for apps.
What’s next for the Dropsource plugin System?
We have always had our sights set on opening the plugin system to our community, something we remain committed to. As we continue to develop plugins, mature the platform, and refine the API and documentation, we will do so in a manner that positions us to open it to our entire community. This will be a big step in the evolution of our offering and we are constantly evaluating how to best deliver this to our members. We’d like to know your take on advancing our plugin system; leave a comment below to help us evaluate interest and weigh in on the direction we should take. Stay tuned for future blog posts from me about the plugin system!