All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalatex.site.Site.scala Maven / Gradle / Ivy

The newest version!
package scalatex.site

import java.io.FileOutputStream
import java.nio.CharBuffer
import java.nio.file.{Files, StandardCopyOption, StandardOpenOption}

import ammonite.ops.{Path, _}
import os.SubProcess.{InputStream, OutputStream}
import scalatags.Text.all._
import scalatags.Text.{attrs, tags2}

/**
 * A semi-abstract trait that encapsulates everything necessary to generate
 * a Scalatex site. Only `content` is left abstract (and needs to be filled
 * in) but the rest of the properties and definitions are all override-able
 * if you wish to customize things.
 */
trait Site{

  def webjars = resource/"META-INF"/'resources/'webjars

  def fontAwesome = webjars/"font-awesome"/"4.7.0"

  /**
   * Resources related to the pure-css library
   */
  def pureCss = Seq(
    webjars/'pure/"0.6.2"/"pure-min.css"
  )
  /**
   * Resources related to the font awesome library
   */
  def fontAwesomeResources = Seq(
    fontAwesome/'fonts/"FontAwesome.otf",
    fontAwesome/'fonts/"fontawesome-webfont.eot",
    fontAwesome/'fonts/"fontawesome-webfont.svg",
    fontAwesome/'fonts/"fontawesome-webfont.ttf",
    fontAwesome/'fonts/"fontawesome-webfont.woff",
    fontAwesome/'css/"font-awesome.min.css"
  )
  /**
   * Resources custom-provided for this particular site
   */
  def siteCss = Set(
    resource/'scalatex/'site/"styles.css"
  )

  /**
   * Resources that get automatically included in the bundled js or css file
   */
  def autoResources = pureCss ++ siteCss

  /**
   * Resources copied to the output folder but not included on the page by default
   */
  def manualResources = fontAwesomeResources
  /**
   * The name of the javascript file that all javascript resources get bundled into
   */
  def scriptName = "scripts.js"
  /**
   * The name of the css file that all css resources get bundled into
   */
  def stylesName = "styles.css"

  def pageTitle: Option[String] = None
  /**
   * The header of this site's HTML page
   */
  def defaultHeader: Seq[Frag] = Seq(
    link(href:="META-INF/resources/webjars/font-awesome/4.7.0/css/font-awesome.min.css", rel:="stylesheet"),
    link(href:=stylesName, rel:="stylesheet"),
    link(rel:="shortcut icon", `type`:="image/png", href:="favicon.png"),
    meta(httpEquiv:="Content-Type", attrs.content:="text/html; charset=UTF-8"),
    tags2.style(raw(Styles.styleSheetText)),
    pageTitle.map(tags2.title(_)),
    script(src:=scriptName)
  )

  /**
   * The body of this site's HTML page
   */
  def bodyFrag(frag: Frag): Frag = div(
    frag
  )


  type Body = Frag
  /** Enable pages to specify multiple header entries */
  type Header = Seq[Frag]
  type Page = (Header, Body)
  /**
   * The contents of the site.
   * Maps String paths to the pages, to their actual content.
   */
  def content: Map[String, Page]

  def bundleResources(outputRoot: Path) = {
    for {
      dest <- Seq(scriptName, stylesName)
      path = outputRoot / dest
    } new FileOutputStream(path.toIO, true).close()

    for {
      (ext, dest) <- Seq("js" -> scriptName, "css" -> stylesName)
      path = outputRoot / dest
      res <- autoResources |? (_.ext == ext)
    } {
      val content = read(res)

      path.toIO.getParentFile.mkdirs()
      Files.writeString(path.wrapped, content, StandardOpenOption.CREATE)
    }

    for {
      res <- manualResources
    } {
      val content = read(res)
      val path = outputRoot/(res relativeTo resource)
      path.toIO.getParentFile.mkdirs()
      Files.writeString(path.wrapped, content, StandardOpenOption.CREATE)
    }
  }

  def generateHtml(outputRoot: Path) = {
    for((path, (pageHeaders, pageBody)) <- content){
      val txt = html(
        head(pageHeaders),
        body(bodyFrag(pageBody))
      ).render
      val cb = CharBuffer.wrap("" + txt)
      val bytes = scala.io.Codec.UTF8.encoder.encode(cb)

      write.over(outputRoot/path, bytes.array(), createFolders = true)
    }
  }
  def renderTo(outputRoot: Path) = {
    generateHtml(outputRoot)
    bundleResources(outputRoot)
  }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy