Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Link Management Feature / Plugin #652

oleersoy opened this Issue · 21 comments

4 participants



First just wanted to say Thank You for making docpad. It's brilliant!

I'd like the ability to do something like this in my documents:


<p> Lookout @link(1)!</p>


<p> Lookout <a href="http:localhost/project1/out/index.html">Project Calamity</a</p>


<p> Lookout @link(1, "New Label")!</p>


<p>Lookout <a href="http:localhost/project1/out/index.html">New Label</a>!</p>

The general idea is that each time docpad generates files into out it also adds the file to a catalog (Located in the root of the content repository) like this (The label could come from meta data or docpad could ask):

location: project1/out/index.html
label: Project Calamity
location: project2/out/blog/blog1.html
label: Blog about Blah
location: project2/out/tutorials/tutorial1.html
label: How to write Tutorials

Docpad would use the above to resolve @link(Integer number, Integer elementID, String title) functions during document generation.

Id also like this to:

  • Verify links
  • Verify the existance of elementIDs when referenced
  • Provide an update mechanism
    • For example suppose tutorial1.html is renamed blog2.html and moved to the blog folder...
    • Suppose tutorial1.html is simply deleted, but links exist to it...
  • When docpad runs a site, it also checks the root of the content repository for linkmanager.json. If it exists, then docpad runs the other sites as well, so that links in resolve.

Do you know if anything like this exists? I'll work on this if not. Feedback and guidance is very much appreciated as I'm brand new to the Node world.



What's wrong with using relative URLs with Markdown?


That's interesting. Essentially referencing pages by id rather than realitive path allows you to eaisily move pages without worring about all the inbound links. I think this is what other cmses do. I like that it provides a way to test link on generate.

This could be added to docpad-plugin-geturl but where do the ids come from? Do they need to be added to every page.


Ah I see... That might be a good idea, but as @Hypercubed said, how do you assign the IDs?

If they're assigned automatically then there would need to be some kind of list somewhere to check what file each ID points to.


How do you update the list when the page moves? And I don't think an collection will keep it's order between generations. I think you'll have to create a metadata tag in each file with a unique id then search a collection of documents with this tag for the given id on each @link or @getUrl.


I was thinking that IDs would be assigned sequentially and not reused in the event that documents are deleted. Docpad would start a counter and just increment for each new document. The counter would be stored in repository.json.

Here's a conceptual overview of what I had in mind starting from scratch:

  • Step 0: cd ~
  • Step 1: Create repository root >> mkdir /home/ole/Documentation
    • Documentation is now the docpad repository root
  • Step 2: cd Documentation
  • Step 3: Create project1 >> docpad run >> Creates project1
  • Step 4: Create and generate it

    • Docpad generates the first entry into /home/ole/Documentation/repository.json
    • If the label was not provided, docpad asks for a label

    location: project1/out/index.html
    label: Project Calamity

  • Step5: Create project2 >> docpad run >> Creates project2

  • Step6: Create project2/src/documents/ and generate

    • During this step Ole looks at repository.json for the id of the index.html file in project1, because he wants place an @link(1) in the project2/src/documents/ document.
    • During generation docpad also adds the second entry to repository.json

    location: project2/out/index.html
    label: Meta Data Provided Label

    • If Ole done been messed up and added a wrong id (@link(12) ), docpad warns that the link proxy could not be resolved and does not generate the target.

Step 7: Ole refreshes the browser tab running project2...and tries out the link targeting project1/index.html
- It works because docpad is including the content from project1
Step 8: Ole attempts to delete project1/src/documents/ by running "docpad rm"
- Docpad warns that this will break links....
- Ole cancels since he does not want to break the links
Step 9: Ole attempts to move index.html like this:
- docpad mv project1/src/documents/ project1/src/documents/main/
- docpad performs the move and simultaneously updates as follows
location: project1/out/main/index.html
label: Project Calamity
- docpad also regenerates all the links referencing 1

And so on...


I think the complications of keeping a separate link dictionary is too much. Especially the docpad mv and docpad rm part. Already I need to do git mv and git rm. My vote would be for a metadata tag. Only issue I see is accidentally duplicated link ids. Just my opinion.


The simpler the better. Do you have any thoughts on how to prevent link breakages without docpad rm?


I guess it would generator a warning or error when an index is missing from the collection.


I guess it's possible to keep it really simple and point out that that users should do a commit / backup before doing a rm.

It would be nice though, especially with respect to a docpad gui, if there were an API that could be called to check whether a deletion causes link breakages.

The other potential, and also self inflicted, issue is document 1 being removed and document 2 being added, but it's given the index of document 1. Just something to guard against in a multi user environment.

Is docpad "Repository" aware? The other purpose of docpad reading repository.json would be to include all the other projects on startup, such that all links could be resolved.


Perhaps we could do something like this:
1) Implement @link...(Other names / suggestions?) using just meta data

linkID: "Memorable Link ID or just # causing massive confusion"
linkLabel: "Give us link refactoring or give us a Apple stock options"
isLinkManagementEnabled: "Oh Yeah!"

2) In ~/.docpad put the home of the repository

repositoryLocation: /home/ole/Documentation

3) Make all the documents in repositoryLocation available when docpadRuns (Could have a local configuration flag to toggle).



Just looked at the docpad-plugin-geturl now. This looks like a terrific place to start. Thanks again. Sorry I did not get to it sooner. Been so busy reading up on Docpad, CoffeeScript, Git, GFM, Markdown, etc. that I must have skipped a few cycles. Hope to have something worked out soon.


First just scratch all the stuff about repository awareness etc. These were targeted more at the thought of DocPad being something like the eclipse help system where you can drop in documentation plugins, and have them be integrated into the help system via extension points. Along the same lines I was thinking that people would have separate docpad documentation projects, that could later be assembled into a larger "Delivery Unit" by simply dropping them into the repository. I think this may be interesting down the line, but for starters just using a standard DocPad project as the "Repository" is simple and possibly the best solution.

Yes - correct I'd like to be able to change directory and file names and file location without causing URL breakages.

Off the top of my head @Link needs to:
Find all the documents that need to be generated
Check for URL "Collisions"
Check for Link ID "Collisions"
Create an in memory dictionary of the meta data provided link id to document url
Resolve all @link tags during document generation

If I understand right 593 needs to:
On each change to a file's URL

  • Save the new URL to a dictionary that also contains the old URL
  • Redirect the consumers of the old URL to the new URL

I think 593 would benefit from @Link or @getUrl type functionality. If I understand correct the "Slow moving article author" would:

  • Update the title >> Triggers update to URL. So if your original example goes from: [my referenced doc](/posts/post1) to @link(uniqueID) then [my referenced doc << Gets automatically updated along with the corresponding new URL on regeneration).

@oleersoy FYI, you're actually calling the users called 'link' and 'geturl'. lol


Hehe - Now you know why I need to read up on so much stuff :). Maybe I'll just change @link to @oleersoy to add some more confusion :). Now I get why whenever I type @ Benjamin Arthur Balupton pops up....


You can add ticks or whatever these are called and do:


And so it will ignore it. :)


@oleersoy Maybe you have something bigger in mind than I am not seeing yet. I don't see the need to create a dictionary of links. Just use the docpad query engine. I think it is something that docpad excels at.

My idea would be as follows:

  1. Add linkid: ## to the metadata for any page you want to reference by id.
  2. Create a collection in docpad config file (or in the plugin) that contains all the documents that have a linkid metadata tag. No need to create another dictionary.
  3. Modify (or fork) docpad-plugin-geturl to accept an id number in addition to what it already accepts (documents, strings, and arrays). When an integer is passed to docpad-plugin-geturl look for that id in the linkid collection, return the url.
  4. Do something to handle the cases when the document is not found or more than one document matches the id. Print a warning?
  5. (sort of optional) Add to docpad-plugin-geturl or create a new plugin that does almost the same thing as docpad-plugin-geturl except it creates a <a href- link.

After this a document can be referenced by id number @getUrl(1) that will persist even if the page moves.


Perfect! Thanks! That's precisely the type of guidance I was hoping for. That should square away the initial use case I had in mind.

It seems there are also plugins that can be configured to change the path based on, for example, dates. For instance blogs may be laid out as src/documents/blogs/, etc.. But the designer wants them displayed as: Do you know if these will be transparently handled by docpad as far as path lookup during url construction goes?

With respect to item 5, I'm thinking a tiny wrapper called docpad-plugin-link-resolver for creating anchors using @link(1) or @link(1, "A different label than the document title meta data"), so more along the lines of a plugin that almost does the same thing, as you were saying.

Thanks again,


OK - I think it's done (Famous last words).

Incidentally there's another plugin that validates links, per the original question asked in this thread.

@oleersoy oleersoy closed this

Just wanted to say thank you again for all the fantastic support!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.