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

net.liftweb.builtin.snippet.Embed.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2007-2011 WorldWide Conferencing, LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.liftweb
package builtin
package snippet

import scala.xml._
import net.liftweb.http._
import net.liftweb.util._
  import Helpers._
import net.liftweb.common._

import Box._

/**
 * This object implements the logic for the <lift:embed> tag. It
 * supports retrieving a template based on the "what" attribute, and
 * any <lift:bind-at> tags contained in the embed tag will be used
 * to replace <lift:bind> tags within the embedded template.
 */
object Embed extends DispatchSnippet {
  // Extract a lift:bind-at Elem with a name attribute, yielding the
  // Elem and the value of the name attribute.
  private object BindAtWithName {
    def unapply(in: Elem): Option[(Elem, String)] = {
      if (in.prefix == "lift" && in.label == "bind-at") {
        in.attribute("name").map { nameNode =>
          (in, nameNode.text)
        }
      } else {
        None
      }
    }
  }

  private lazy val logger = Logger(this.getClass)

  def dispatch : DispatchIt = {
    case _ => render _
  }

  def render(kids: NodeSeq) : NodeSeq =
  {
    for {
      ctx <- S.session ?~ ("FIX"+"ME: session is invalid")
      what <- S.attr ~ ("what") ?~ ("FIX" + "ME The 'what' attribute not defined. In order to embed a template, the 'what' attribute must be specified")
      templateOpt <- ctx.findTemplate(what.text) ?~ ("FIX"+"ME trying to embed a template named '"+what+"', but the template was not found. ")
    } yield {
      (what, Templates.checkForContentId(templateOpt))
    }
  } match {
    case Full((templateName,template)) => {
      val bindings: Seq[CssSel] = kids.collect {
        case BindAtWithName(element, name) =>
          s"#$name" #> element.child
      }

      val bindFn =
        if (bindings.length > 1)
          bindings.reduceLeft(_ & _)
        else if (bindings.length == 1)
          bindings(0)
        else
          PassThru

      bindFn(template)
    }
    case Failure(msg, Full(ex), _) =>
      logger.error("'embed' snippet failed with message: "+msg, ex)
      throw new SnippetExecutionException("Embed Snippet failed: "+msg)

    case Failure(msg, _, _) =>
      logger.error("'embed' snippet failed with message: "+msg)
      throw new SnippetExecutionException("Embed Snippet failed: "+msg)

    case _ =>
      logger.error("'embed' snippet failed because it was invoked outside session context")
      throw new SnippetExecutionException("session is invalid")
  }

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy