I want to tune my multilungual DocPad blog so that pages ended with *.ru.md go into /ru/ directory, and pages ended with *.en.md go into /en/ directory.
Let's say this is the initial structire
src/
pages/
page1.ru.md
page1.en.md
page2.ru.md
And this is what I want:
./
en/
page1.html
ru/
page1.html
page2.html
./
because I am going to host with gh-pages
.
And the same for posts. I would like to store them in
src/
posts/
post-about-docpad.ru.md
post-about-docpad.en.md
And get
./
en/
posts/
post-about-docpad.html
ru/
posts/
post-about-docpad.html
How should I config docpad?
The 1st step is renaming your documents to use a dash for the language like so: page1-en.html
, and page1-ru.html
, instead of page1.en.html
and page1.ru.tml
— as otherwise as @kizu correctly points out, it will cause problems as DocPad renders from extension to extension.
Once that is done, you can add the following to your docpad configuration file:
collections:
# Fetch documents in different languages
translate: (database) ->
languageRegex = /^(.+?)-(en|ru)$/
#docpadOutPath = @getConfig().outPath
@getCollection('documents').findAllLive({basename: languageRegex}).on 'add', (document) ->
# Prepare
a = document.attributes
parts = a.basename.match(languageRegex)
basename = parts[1]
language = parts[2]
relativeOutPath = "#{language}/#{a.relativeOutDirPath}/#{basename}.#{a.outExtension}"
#outPath = "#{docpadOutPath}/#{relativeOutPath}"
urls = ["/#{relativeOutPath}"]
# Apply
document
.setMetaDefaults({
#outPath
url: urls[0]
})
.addUrl(urls)
This will have URLs working in the way you want.
Then run DocPad in the static environment with the cleanurls plugin installed, to write the documents to the desired locations.
docpad install cleanurls
docpad generate --env static
This could be done, but with three changes in the file structure:
As dots in DocPad's path are there to delimit the different renderers and I'm not sure how to do what I'd propose inside a renderer, so it won't throw Rendering the extension … didn't do anything.
error, I propose to use the _en
/_ru
instead of .en
/.ru
, this way you could then do stuff based on filenames without any extra hassle.
It is better to use the Docpad's initial paths, i.e. put your pages
and blog
folders inside documents
folder.
There could be a way to use the files without the .html.md
part, but as it is a DocPad way, you should use it.
Maybe there are ways to do what you want this without those changes, but it would be less trivial :)
So, the code to place at docpadConfig
in docpad.coffee
(here is an example project at GitHub):
docpadConfig = {
collections:
# Declare `ru` and `en` collections
ruDocuments: ->
@getCollection("documents").findAllLive({
basename: /_ru$/
})
enDocuments: ->
@getCollection("documents").findAllLive({
basename: /_en$/
})
events:
renderBefore: () ->
# Rewrite `pages/` to the root and `posts/` to the `blog/`.
this.docpad.getCollection('documents').forEach (page) ->
newOutPath = page.get('outPath')
.replace('/out/pages/', '/out/')
.replace('/out/posts/', '/out/blog/')
newUrl = page.get('url')
.replace('pages/', '')
.replace('posts/', 'blog/')
page.set('outPath', newOutPath)
page.setUrl(newUrl)
# Rewrite `_ru` to the `/ru/`
this.docpad.getCollection('ruDocuments').forEach (page) ->
newOutPath = page.get('outPath')
.replace('/out/', '/out/ru/')
.replace('_ru.', '.')
newUrl = '/ru' + page.get('url')
page.set('outPath', newOutPath)
page.setUrl(newUrl)
# Rewrite `_en` to the `/en/`
this.docpad.getCollection('enDocuments').forEach (page) ->
newOutPath = page.get('outPath')
.replace('/out/', '/out/en/')
.replace('_en.', '.')
page.set('outPath', newOutPath)
newUrl = '/en' + page.get('url').replace('_en.', '.')
page.setUrl(newUrl)
}
module.exports = docpadConfig
At first we declare two collections: one for all ru documents and another for all en documents.
Then we at first rewrite the pages/
to the root, and then rewrite the _en
/_ru
files to /en/
and /ru/
.
Note that the changes are only how the source files are stored, the resulting output would be the same as you want in your question.
So, instead of
src/
pages/
page1.ru.md
page1.en.md
page2.ru.md
posts/
post-about-docpad.ru.md
post-about-docpad.en.md
You should write this way:
src/
documents/
pages/
page1_ru.html.md
page1_en.html.md
page2_ru.html.md
posts/
post-about-docpad_ru.html.md
post-about-docpad_en.html.md
But you would get you desired output just as you need. The only thing is that I didn't understand the part about the gh-pages
: are you going to store the result and the source in the same branch? I'd propose to use the master
for the source and the gh-pages
for the result.
But if you'd need to have only one branch, well, ok, you can easy rewrite all the things you'd like by replacing .replace('/out/', '/out/ru/')
with .replace('/out/', '/ru/')
etc. — this would put the rendered files up to one level above out
.