PageRenderTime 31ms CodeModel.GetById 18ms app.highlight 9ms RepoModel.GetById 2ms app.codeStats 0ms

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