Hi everyone,
Tree Shade is a CEP extension for InDesign + Startup script for Bridge + Node.js local server. I have been developing over a decade and reached about 40000 lines of code. It’s totally free and open source.
I wanted to share a glimpse of the engineering concept behind Tree Shade, and open a discussion on this approach to handling complex data structures within Adobe Bridge without an external database.
We developed a file structure logic where data loads into an online form incrementally, depending on selected options. It connects files (acting as the Controller) with paired folders (acting as the Content) to create dynamic, self-assembling forms.
I’m interested to hear your thoughts on this architecture.
Tree Shade Engineering Concept
The Core Logic:
Tree Shade replaces the need for a heavy database engine by treating the file system as a relational map.
![]()
![]()
![]()
The Rules:
The “Original” Connection
There is a permanent connection between a file and its “Original file” in the copying sequence. In Adobe Bridge, when a user builds a template, they can fabricate this “Original” relation manually by selecting file(s) and choosing a command to designate a specific fabricated Original file.
Logical Pairing
If a folder residing beside a file shares the exact same pure name, they are paired together logically.
Dynamic Field Conversion
In the dynamic form, files are converted into fields. And if a file is marked as a Selector field (identified by ts_opt in the filename) then all files in the “Original file” folder are automatically loaded as options. The “Original” serves as the default current selection.
The Paired File
Despite if a file marked by “ts_opt” or not, if it’s paired to a folder then it considered a Selector field and itself is an option! So the paired folder automatically loaded as the current sub-content to be edited. Normally the paired file is a text file has dynamic Live Snippet syntax for rendering the content of the paired folder. And also can be included a TS tag to render the html for the hosting by the same local server.
Conditional Loading
If the user picks an option in the form, the system disable current select option and requests to load the paired folder of that option file as sub-content.
The Overwrite/Commit
Upon submission, the picked file overwrites the Selector file (and is marked as the new Original). Simultaneously, the edited content of the paired folder of the picked option replaces the paired folder of the Selector file.
The Dynamic List
If the files in a folder have an ID prefix “ID4Y87FG” where the value consists of capital letters or digits or mix of both. And may the “ID” followed by a dash. If the length is 5 or more a random generation will be done when the end-user duplicate a field. And if the length 4 or less then an increment. But if there is a dash then the end-user will be asked for it.
The Nesting Behaviour
If a Selector file includes an ID, the end-user can duplicate the item and modify its type.
The Recursive Logic: True recursion is achieved when a paired folder contains an internal Selector file (acting as a dynamic list) whose ‘Original’ file is one of the main options files. This reference triggers a recursive call, enabling the creation of deeply nested structures.
![]()
![]()
![]()
Example: The “Figure” Component
➔ Imagine a layout project with a component named Figure ts_opt.txt paired with a folder named Figure.
➔ In a source folder called “Figure Options” we have:
❶ Photo.txt paired with a Photo folder beside it (containing Photo File.jpg and Caption.txt).
❷ Table.txt paired with a Table folder (containing Sheet.csv).
![]()
![]()
![]()
The Workflow:
- When the server loads the
Figure ts_opt.txtfile, it detects thets_optflag. It inherently loads “Photo” and “Table” as available options. - When the user picks “Table,” the form dynamically requests the Table paired folder (the CSV uploader) as sub-content.
- When the form is submitted:
Table.txtoverwritesFigure ts_opt.txt.- Simultaneously, the Figure folder is wiped and replaced by the content of the Table folder (the uploaded new
Sheet.csv).
![]()
![]()
![]()
This architecture allows for managing complex, nested content efficiently using the file system itself as the state machine.
You can inspect the tool and logic here:
I look forward to any feedback on this approach to local data management!
Suggested Tags for the post:
CEP UXP Adobe Bridge Workflow Automation Architecture Open Source
