/scalate-wikitext/src/main/scala/org/fusesource/scalate/wikitext/ChildrenTag.scala

http://github.com/scalate/scalate · Scala · 102 lines · 71 code · 8 blank · 23 comment · 16 complexity · c70f29995142d072e25edcda68f2bdc9 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
  19. package wikitext
  20. import StringConverter._
  21. import java.io.File
  22. import xml.NodeSeq
  23. import util.{ Log, Files }
  24. object ChildrenTag extends Log
  25. /**
  26. * Implements the **children** macro in confluence
  27. */
  28. class ChildrenTag extends AbstractConfluenceTagSupport("children") {
  29. import ChildrenTag._
  30. var page: Option[String] = None
  31. var depth = 1
  32. var all = false
  33. def setOption(key: String, value: String) = key match {
  34. case "all" => all = asBoolean(value)
  35. case "depth" => depth = asInt(value)
  36. case "page" => page = Some(value)
  37. case _ => Blocks.unknownAttribute(key, value)
  38. }
  39. def doTag() = {
  40. val context = RenderContext()
  41. def showChildren(rootDir: File, dir: File, level: Int): NodeSeq = {
  42. // TODO allow different sorting
  43. // lets make sure directories for "foo" appear after the "foo.conf" file so use "/" which is after "."
  44. lazy val files = dir.listFiles().sortBy(f => if (f.isDirectory) f.getName + "/" else f.getName)
  45. if (all || level <= depth && files.nonEmpty) {
  46. <ul>
  47. {
  48. files.map {
  49. f =>
  50. debug("{children} processing file '%s'", f)
  51. if (f.isFile) {
  52. val title = Pages.title(f)
  53. val link = Files.relativeUri(rootDir, new File(f.getParentFile, Files.dropExtension(f) + ".html"))
  54. val child = new File(f.getParentFile, Files.dropExtension(f))
  55. debug("{children} checking child '%s'", child)
  56. val dirXml = if (child.isDirectory) {
  57. showChildren(rootDir, child, level + 1)
  58. } else {
  59. Nil
  60. }
  61. <li>
  62. <a href={ link }>
  63. { title }
  64. </a>
  65. { dirXml }
  66. </li>
  67. }
  68. }
  69. }
  70. </ul>
  71. } else {
  72. Nil
  73. }
  74. }
  75. val requestUri = if (context.currentTemplate != null) context.currentTemplate else context.requestUri
  76. val idx = requestUri.lastIndexOf('/')
  77. val pageName = if (idx >= 0) requestUri.substring(idx + 1) else requestUri
  78. val pageUri = page.getOrElse(Files.dropExtension(pageName))
  79. SwizzleLinkFilter.findWikiFile(pageUri) match {
  80. case Some(file) =>
  81. info("{children} now going to iterate from file '%s'", file)
  82. val rootDir = file.getParentFile
  83. val dir = new File(rootDir, Files.dropExtension(file))
  84. if (!dir.exists) {
  85. warn("{children} cannot find directory: %s", dir)
  86. } else {
  87. //context << showChildren(rootDir, dir, 1)
  88. builder.charactersUnescaped(showChildren(rootDir, dir, 1).toString)
  89. }
  90. case _ =>
  91. warn("Could not find wiki file for page '%s'", pageUri)
  92. }
  93. }
  94. }