Generate different docpad collections for differen

2019-03-17 03:07发布

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?

标签: docpad
2条回答
我只想做你的唯一
2楼-- · 2019-03-17 03:54

This could be done, but with three changes in the file structure:

  1. 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.

  2. It is better to use the Docpad's initial paths, i.e. put your pages and blog folders inside documents folder.

  3. 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.

查看更多
Juvenile、少年°
3楼-- · 2019-03-17 04:01

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
查看更多
登录 后发表回答