PageRenderTime 39ms CodeModel.GetById 28ms RepoModel.GetById 1ms 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. */
  18. package org.fusesource.scalate.support
  19. import org.fusesource.scalate.TemplateEngine
  20. import org.fusesource.scalate.util.Files
  21. /**
  22. * A helper object to find a template from a URI using a number of possible extensions and directories
  23. */
  24. class TemplateFinder(engine: TemplateEngine) {
  25. var hiddenPatterns = List("""^_|/_""".r, """^\.|/\.""".r)
  26. var replacedExtensions = List(".html", ".htm")
  27. lazy val extensions = engine.extensions
  28. def findTemplate(path: String): Option[String] = {
  29. var rc = Option(engine.finderCache.get(path))
  30. if (rc.isEmpty) {
  31. rc = search(path)
  32. if (rc.isDefined && !engine.isDevelopmentMode) {
  33. engine.finderCache.put(path, rc.get)
  34. }
  35. }
  36. rc
  37. }
  38. def search(rootOrPath: String): Option[String] = {
  39. val path = if (rootOrPath == "/") "/index" else rootOrPath
  40. if (hiddenPatterns.exists(_.findFirstIn(path).isDefined)) {
  41. return None
  42. }
  43. // Is the uri a direct path to a template??
  44. // i.e: /path/page.jade -> /path/page.jade
  45. def findDirect(uri: String): Option[String] = {
  46. engine.templateDirectories.flatMap { base =>
  47. extensions.flatMap { ext =>
  48. val path = base + uri
  49. if (path.endsWith(ext) && engine.resourceLoader.exists(path)) {
  50. Some(path)
  51. } else {
  52. None
  53. }
  54. }
  55. }.headOption
  56. }
  57. // Lets try to find the template by appending a template extension to the path
  58. // i.e: /path/page.html -> /path/page.html.jade
  59. def findAppended(uri: String): Option[String] = {
  60. engine.templateDirectories.flatMap { base =>
  61. extensions.flatMap { ext =>
  62. val path = base + uri + "." + ext
  63. if (engine.resourceLoader.exists(path)) {
  64. Some(path)
  65. } else {
  66. None
  67. }
  68. }
  69. }.headOption
  70. }
  71. // Lets try to find the template by replacing the extension
  72. // i.e: /path/page.html -> /path/page.jade
  73. def findReplaced(): Option[String] = {
  74. replacedExtensions.flatMap {
  75. ext =>
  76. if (path.endsWith(ext)) {
  77. findAppended(path.stripSuffix(ext))
  78. } else {
  79. None
  80. }
  81. }.headOption
  82. }
  83. // Lets try to find the template for well known template extensions
  84. // i.e:
  85. // /path/page.css -> List(/path/page.sass, /path/page.scss)
  86. // /path/page.js -> List(/path/page.coffee)
  87. def findTemplateAlias(uri: String): Option[String] = {
  88. val ext = Files.extension(uri)
  89. lazy val remaining = path.stripSuffix(ext)
  90. if (ext.size > 0) {
  91. engine.extensionToTemplateExtension.get(ext).flatMap {
  92. set =>
  93. engine.templateDirectories.flatMap { base =>
  94. set.flatMap { ext =>
  95. val path = base + remaining + ext
  96. if (engine.resourceLoader.exists(path)) {
  97. Some(path)
  98. } else {
  99. None
  100. }
  101. }
  102. }.headOption
  103. }
  104. } else {
  105. None
  106. }
  107. }
  108. findDirect(path).orElse(findAppended(path).orElse(findTemplateAlias(path).orElse(findReplaced())))
  109. }
  110. }