Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deploy a site that is not at the root of a server with DocPad?

Tags:

docpad

I'm using DocPad to make a demo site and i want to deploy it at for example: http://www.example.com/demo/ but when i use docpad generate --env static, links are relative to the root of the server not demo directory so links are broken. What can i do ? is there a metadata to declare somewhere ?

EDIT: In this case, I use the Twitter Bootsrap skeleton, so for example links in the main navigation in the default layout looks like:

<div class="nav-collapse collapse">
  <ul class="nav">
    <% for document in @getCollection('pages').toJSON(): %>
      <li class="<%= 'active'  if @document.url is document.url %>">
        <a href="<%= document.url %>"><%= document.title %></a>
      </li>
    <% end %>
  </ul>
</div>
like image 350
Dharma Avatar asked Dec 01 '25 00:12

Dharma


2 Answers

I've written a small plugin which does the job, there's probably a better solution but it works fine:

# Export Plugin
module.exports = (BasePlugin) ->
  # Define Plugin
  class absolutePathPlugin extends BasePlugin
    # Plugin Name
    name: 'absolutepath'
    config:
      url: "/"

    renderAfter: (opts,next) ->
      docpad = @docpad
      if 'static' in docpad.getEnvironments()
        docpad.log 'debug', 'Writing absolute urls'
        href = 'href="' + @config.url
        src = 'src="' + @config.url
        database = docpad.getCollection('html')
        database.forEach (document) ->
          content = document.get('contentRendered')
          if /href="\//.test(content)
            content = content.replace(/href="\//g, href)
          if /src="\//.test(content)
            content = content.replace(/src="\//g, src)
          document.set('contentRendered',content)
        next()?
      else
        next()?

      # Chain
      @

And in my docpad.coffee file, I just have to configure the url and if you use the cleanUrls plugin, you have to adapt the getRedirectTemplate function to take the absolute url into account:

plugins:
  absolutepath:
    url: "http://www.example.com/demo/"
  cleanurls:
    getRedirectTemplate: (document) ->
      absolutepath = docpadConfig.plugins.absolutepath.url.slice(0, - 1) 
      """
      <!DOCTYPE html>
      <html>
        <head>
          <meta charset="utf-8">
          <title>#{document.get('title') or 'Redirect'}</title>
          <meta http-equiv="REFRESH" content="0;url=#{absolutepath + document.get('url')}">
        </head>
        <body>
          This page has moved. You will be automatically redirected to its new location. If you aren't forwarded to the new page, <a href="#{absolutepath + document.get('url')}">click here</a>.
        </body>
      </html>
      """
like image 70
Dharma Avatar answered Dec 02 '25 15:12

Dharma


Another option is to transform all the absolute URLs to relative ones so the site works from any path prefix (/, /path/, or /some/other/path/) without rebuilding. Think gh-pages with a custom domain.

Here's a grunt task to do the transformation on HTML and CSS after a static docpad generation. It's currently built on regex replacement inspired by @Dharma's docpad plugin.

like image 44
hurrymaplelad Avatar answered Dec 02 '25 14:12

hurrymaplelad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!