Another handy thing. You can export an empty group with a script as a template. Create a new group from the template, and you don’t have to mess with hunting down the script.
And, in the prescient and immortal words of Monty Python, there was much rejoicing.
This script can be used to attach a triggered script to exsting groups
-- Attach triggered script to selected records
property theTriggeredScript_Path : "/Users/User/Desktop/Triggered Script - A.scpt" -- Set your path here
tell application id "DNtp"
try
set theRecords to selected records
if theRecords = {} then error "Please select some records"
repeat with thisRecord in theRecords
set attached script of thisRecord to theTriggeredScript_Path
end repeat
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
return
end try
end tell
This is really great, with the potential to save huge amounts of time otherwise spent manually selecting and adding transclusion links!
@pete31: Is there a way to include the transcluded items’ names as well through the script, in addition to the contents? For my use case, this would be essential.
This is by no means as sophisticated as anything that @pete31 produces but a simple change or two to my transclusion script may give what you need:
(* This script creates a new markdown record in the chosen database
and group and then adds to that record transclusion item links for plain text,
markdown or HTML records you have selected in the database with a line drawn
between each item. It will prompt you for the name of the new record or
you can choose to use the default name. *)
-- the database to open
property pDatabase : "/Users/stapp/Documents/DevonThink/Diaries.dtBase2"
-- the group to use for tbe markdown file of transclusions
property pGroup : "F3E59383-23EF-4CAB-9912-369CF9CF45CC"
-- the valid types of record for transclusion
property validTypes : {"markdown", "txt", "html"}
tell application id "DNtp"
try
activate
-- open the database
set theDatabase to open database pDatabase
set myGroup to get record with uuid pGroup
--check that we have some records selected for transclusion
set theSelection to the selection
if (count of theSelection) is 0 then
error "Please select some markdown records for transclusion"
end if
--set up the new record for the transclusions
set dAnswer to "New document"
set userEntry to display dialog ¬
"Enter the name of the new document (without the extension) or accept the default: " default answer dAnswer with title "New document for the transclusions"
set dAnswer to text returned of userEntry
set theNewRecord to create record with {name:dAnswer, type:markdown} in myGroup
-- Set up an empty list to populate with new strings, etc.
set textUpdates to {}
repeat with theRecord in (selection as list)
-- Check the document type
if (type of theRecord as string) is in validTypes then
--Get the reference URLs of the selected records
set recURL to reference URL of theRecord
set recordName to the name of theRecord
-- Format the transclusions
set transcludedItem to my createTransclusion(recURL)
-- Copy the string to the list, noting a linefeed is added after each line
copy (recordName & linefeed & transcludedItem & linefeed) to end of textUpdates
else
error "Check selected records: only markdown, plain text and HTML records are suitable for transclusion"
end if
-- Keep adding to the list until the loop expires
end repeat
-- Update the text of the file in one move
set plain text of theNewRecord to (textUpdates as string)
set root of viewer window 1 to myGroup
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
return
end try
end tell
--The handler to format the transclusion links is separate simply to make it easy
--to change the formatting between items if you wish.
on createTransclusion(theURL)
set theLink to "{{" & theURL & "}}" & linefeed & linefeed & "---" & linefeed
return theLink
end createTransclusion
…and for formatting along the lines you mentioned substitute the following where appropriate in the original script:
set recordName to the name of theRecord
set formattedName to "# This is a transclusion of " & recordName
-- Format the transclusions
set transcludedItem to my createTransclusion(recURL)
-- Copy the string to the list, noting a linefeed is added after each line
copy (formattedName & linefeed & transcludedItem & linefeed) to end of textUpdates
Sorry for the scrappy replies: in the middle of preparing lunch!
…accompanied by a rather nice bottle of Californian pinot noir, so shall resist tinkering with scripts this afternoon for fear they may be even more amateurish than usual.
Thank you very much @stephen_c for taking the time to respond. After some highly amateurish tinkering on my side trying to figure out where that code snippet belongs, your script now does what I was looking for
In a bid to automate this further, the ultimate transclusion script from my perspective would work via a smart rule to periodically create/update transclusions for all groups/tags that have a certain user-defined attribute.
I’m a little too befuddled to tackle that sort of thing—which I think is above my pay grade—but here is one final tweak. If you substitute set recordName to the name without extension of theRecord for set recordName to the name of theRecord the record name above the transclusion will display without the extension. (I wasn’t clear whether you wanted the extension or not.)
Again, this script is a big step forwards for me, as I previously had to add the titles (and the transclusion links themselves) manually. Thank you.
Still, I’m looking for ways to reduce the maintenance aspect of keeping transclusions up-to-date even further: I have a significant number of “atomic notes” for around 50 topic areas. I would like to use transclusions per topic area to review these insights regularly (including on the go) using text-to-speech.
However, re-creating this number of transclusions regularly would still require significant effort even with the help of @Stephen_C’s script, and could be impractical in the busyness of daily life.
I recognize my request for a smart rule - based script is a tall ask based on a single use case (mine).
So the next step forwards would be Pete’s script with some slight modifications. I’ve already figured out how to modify the script such that the transclusion record is neither selected nor opened in a new window, as this simplifies batch processing. My workflow would be to simply select all groups (topics) I have transclusions for once maybe on a weekly basis, which should not take more than a minute or so.
@pete31 I’m now primarily looking for a way to also include the item names of transcluded items in the transclusion. I’d hugely appreciate it, if you can find the time to make this modification. Feel free to send me your paypal, as I recognize there’s “no free lunch” and you’re surely busy as well
I managed to come up with a pretty good workaround:
Modified Steven’s script to no longer ask for the name of newly created transclusions, and instead to give them the name of the containing group…
Created KB Maestro macro, which (with a group selected), opens that group and searches it for Markdown items, then selects and transcludes all found Markdown items using the script.
So now my workflow is essentially to select a group and activate the macro with a hotkey to transclude all contained items. A smart rule adds dates to the new transclusion notes and deletes those, which are older than a week. Obviously, generating the transclusions still needs to be done one by one periodically but it’s a good start.
I tried but didn’t manage to modify your script, such that it also adds the item names next to contents.
Well, when transcluding items I think it’s quite reasonable to want to include the heading. Otherwise there’s no context for the contents. But to each his own and, as mentioned, I’m satisfied with my workaround now.
I appreciate your sentiment that this is a place where people share as part of the „community spirit”. But I also think there’s nothing wrong in offering to buy you a beer as a small thank you for your efforts
You can’t do that via a Smart Rule because in a Smart Rule script the current record (i.e. the one that’s currently processed) doesn’t know the Smart Group’s scope. It would be possible to use the record’s location, however this may not work reliable in case of replicated records.
But it’s possible via a triggered script. Let me know if you want that.
Really appreciate your offer to take another look at this. Even though a smart rule would be the ultimate solution for minimizing maintenance, a triggered script would certainly help a lot to further streamline things compared to my current workaround.
Quick clarification regarding the previous request to “include the heading” to ensure that if we’re ruling out a smart rule script, we’re doing so based on the same understanding of the objective:
What I meant to write here is actually that I want to include the title of the record as a formatted heading (##) in front of the record’s content in the transclusion document. So the end result would ideally be:
(##) Record A title (linebreak) Record A content
(two line breaks)
(##) Record B title (linebreak) Record B content
etc
It would be surprising to me if a smart rule could access a record’s contents but not its title. However, there may just be things about the mechanics of scripting in DT that I don’t yet understand. And again, a triggered script would be great as well otherwise!
One thing that would be important is that the script either needs to respect the visible order of items, or it needs to be possible to specify the field, by which records should be ordered in the transclusion. For my use case, I would want them to be ordered by a custom field that I created to group related items.
As a bonus, nice-to-have addition, another thought:
I noticed that the current version of the triggered script only creates a new transclusion, if none has already been created in the respective group. From my perspective, if it is feasible, an automatic replacement of the transclusion would be ideal. This way, the group would always contain the most up-to-date version including new Markdown items that were added into the group. Currently, one would need to check for each group whether it already contains a transclusion and delete it, before triggering the script. With this change, this additional step would no longer be needed.
It’s of course possible to get every property of a record via a Smart Group script. But a record can have multiple parents and it’s not possible to reliably get the right parent (i.e. the group that you’ve set as the Smart Group’s scope).
As there’s no way to get the group (that you’ve set as a Smart Group’s scope) via AppleScript the only (reliable) way would be to set the group’s reference URL in a script property.
That’s only possible if you sort by unsorted.
What type is your Custom Meta Data?
The triggered script already updates the Transclusion record’s contents. You need to deselect and select the group to trigger a triggered script.