Action

add backlinks to selected linked drafts

Posted by FlohGro, Last update 9 days ago

UPDATES

9 days ago

added notification

created by @FlohGro / more on my Blog

add backlinks to selected linked drafts

finds [[wiki-style-links]] in the current Draft.
It presents a prompt where you can select the drafts where you want to insert a backlink to the current draft.
The action will check each selected draft and add a backlink to the current draft at the end if it is not yet existing


If you find this useful and want to support me you can donate or buy me a coffe

Buy Me A Coffee

Steps

  • script

    
    const backlinkSectionTitle = "backlinks"
    addBacklinksToSelectedForwardLinkedDraftsInGivenDraft(draft)
    
    /**
     * add backlinks to selected drafts linked as wiki-style-links in the given draft
     * @param {Draft} d the draft you want to search the outgoing links from
     */
    function addBacklinksToSelectedForwardLinkedDraftsInGivenDraft(d){
        const matches = getOutgoingLinksInDraft(d)
        let drafts = getDraftsFromTitles(matches)
        // create map for titles and drafts to be used in prompt
        const titleToDraftMap = new Map();
        drafts.forEach((curDraft) => {  
            titleToDraftMap.set(curDraft.displayTitle,curDraft)
        })
    
        // create prompt to let user decide which drafts should be linked
        let p = new Prompt()
        p.title = "select drafts"
        p.message = "select the drafts where backlinks should be added"
        p.addSelect("draftsToLink","",Array.from(titleToDraftMap.keys()),[],true);
        p.addButton("add links to drafts")
        if(p.show()){
            let selectedDrafts = p.fieldValues["draftsToLink"]
            selectedDrafts.forEach((dTitle) => {
                insertBacklinkToDestinationDraftFromSourceDraft(d,titleToDraftMap.get(dTitle))
            })
        }
    }
    
    /**
     * finds all wiki-style-links in the given draft and returns them
     * @param {Draft} d the Draft where you want to search the outgoing links in
     * @returns array of titles in outgoing links
     */
    function getOutgoingLinksInDraft(d){
        let content = d.content
        const regex = /\[\[([^\]]+)\]\]/g;
        const matches = [];
    
        let match;
        while ((match = regex.exec(content)) !== null) {
            const linkText = match[1];
            if(!matches.includes(linkText) && linkText != draft.displayTitle){
                matches.push(linkText);
            }
        }
        return matches
    }
    
    /**
     * finds drafts for each given title
     * @param {String[]} titles array of titles that you want to search drafts for
     * @returns array of Drafts[] (only unique titles are retuned)
     */
    function getDraftsFromTitles(titles){
        let drafts = []
        titles.forEach((title) => {
            let foundDrafts = Draft.queryByTitle(title)
            if(foundDrafts.length == 1){
                drafts.push(foundDrafts[0])    
            }
        })
        return drafts
    }
    
    /**
     * insert a backlink to the sourceDraft at the linkedDraftsSection in the destinationDraft
     * @param {Draft} sourceDraft the Draft you want to link from
     * @param {Draft} destinationDraft the Draft where you want to insert the link to the sourceDraft
     */
    function insertBacklinkToDestinationDraftFromSourceDraft(sourceDraft, destinationDraft) {
        // don't allow linking to the same draft
        if (sourceDraft == destinationDraft) {
            return 0
        }
        let updateNeeded = false
        let linkText = `[[${sourceDraft.displayTitle}]]`
        const backlinkSectionStartingText = `---\n\n## `+ backlinkSectionTitle + `\n\n`
        //check if text is already in given draft d
        if (destinationDraft.content.includes(backlinkSectionStartingText)) {
            // already present, only add link
            // check if link is already exisitng
            let backLinksSectionText = destinationDraft.content.split(backlinkSectionStartingText)[1]
            if (!backLinksSectionText.includes(linkText)) {
                destinationDraft.content = destinationDraft.content.trim() + "\n- " + linkText
                updateNeeded = true
            }
        } else {
            // its the first backlink - add section marker and link
            destinationDraft.content = destinationDraft.content.trim() + "\n\n" + backlinkSectionStartingText + "- " + linkText
            updateNeeded = true
        }
        if(updateNeeded){
        	destinationDraft.update()
        	app.displaySuccessMessage("link added")
        }
    }

Options

  • After Success Nothing
    Notification Error
    Log Level Info
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.