PageRenderTime 33ms CodeModel.GetById 8ms app.highlight 18ms RepoModel.GetById 2ms app.codeStats 0ms

/scalate-core/src/main/scala/org/fusesource/scalate/support/TemplateFinder.scala

http://github.com/scalate/scalate
Scala | 121 lines | 80 code | 11 blank | 30 comment | 18 complexity | 02e0290da9de877e9d5f57037e8bbf42 MD5 | raw file
  1/**
  2 * Copyright (C) 2009-2011 the original author or authors.
  3 * See the notice.md file distributed with this work for additional
  4 * information regarding copyright ownership.
  5 *
  6 * Licensed under the Apache License, Version 2.0 (the "License");
  7 * you may not use this file except in compliance with the License.
  8 * You may obtain a copy of the License at
  9 *
 10 *     http://www.apache.org/licenses/LICENSE-2.0
 11 *
 12 * Unless required by applicable law or agreed to in writing, software
 13 * distributed under the License is distributed on an "AS IS" BASIS,
 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18package org.fusesource.scalate.support
 19
 20import org.fusesource.scalate.TemplateEngine
 21import org.fusesource.scalate.util.Files
 22
 23/**
 24 * A helper object to find a template from a URI using a number of possible extensions and directories
 25 */
 26class TemplateFinder(engine: TemplateEngine) {
 27
 28  var hiddenPatterns = List("""^_|/_""".r, """^\.|/\.""".r)
 29  var replacedExtensions = List(".html", ".htm")
 30  lazy val extensions = engine.extensions
 31
 32  def findTemplate(path: String): Option[String] = {
 33    var rc = Option(engine.finderCache.get(path))
 34    if (rc.isEmpty) {
 35      rc = search(path)
 36      if (rc.isDefined && !engine.isDevelopmentMode) {
 37        engine.finderCache.put(path, rc.get)
 38      }
 39    }
 40    rc
 41  }
 42
 43  def search(rootOrPath: String): Option[String] = {
 44    val path = if (rootOrPath == "/") "/index" else rootOrPath
 45
 46    if (hiddenPatterns.exists(_.findFirstIn(path).isDefined)) {
 47      return None
 48    }
 49
 50    // Is the uri a direct path to a template??
 51    // i.e: /path/page.jade -> /path/page.jade
 52    def findDirect(uri: String): Option[String] = {
 53      engine.templateDirectories.flatMap { base =>
 54        extensions.flatMap { ext =>
 55          val path = base + uri
 56          if (path.endsWith(ext) && engine.resourceLoader.exists(path)) {
 57            Some(path)
 58          } else {
 59            None
 60          }
 61        }
 62      }.headOption
 63    }
 64
 65    // Lets try to find the template by appending a template extension to the path
 66    // i.e: /path/page.html -> /path/page.html.jade
 67    def findAppended(uri: String): Option[String] = {
 68      engine.templateDirectories.flatMap { base =>
 69        extensions.flatMap { ext =>
 70          val path = base + uri + "." + ext
 71          if (engine.resourceLoader.exists(path)) {
 72            Some(path)
 73          } else {
 74            None
 75          }
 76        }
 77      }.headOption
 78    }
 79
 80    // Lets try to find the template by replacing the extension
 81    // i.e: /path/page.html -> /path/page.jade
 82    def findReplaced(): Option[String] = {
 83      replacedExtensions.flatMap {
 84        ext =>
 85          if (path.endsWith(ext)) {
 86            findAppended(path.stripSuffix(ext))
 87          } else {
 88            None
 89          }
 90      }.headOption
 91    }
 92
 93    // Lets try to find the template for well known template extensions
 94    // i.e:
 95    // /path/page.css -> List(/path/page.sass, /path/page.scss)
 96    // /path/page.js -> List(/path/page.coffee)
 97    def findTemplateAlias(uri: String): Option[String] = {
 98      val ext = Files.extension(uri)
 99      lazy val remaining = path.stripSuffix(ext)
100      if (ext.size > 0) {
101        engine.extensionToTemplateExtension.get(ext).flatMap {
102          set =>
103            engine.templateDirectories.flatMap { base =>
104              set.flatMap { ext =>
105                val path = base + remaining + ext
106                if (engine.resourceLoader.exists(path)) {
107                  Some(path)
108                } else {
109                  None
110                }
111              }
112            }.headOption
113        }
114      } else {
115        None
116      }
117    }
118
119    findDirect(path).orElse(findAppended(path).orElse(findTemplateAlias(path).orElse(findReplaced())))
120  }
121}