Pregunta

Si tengo una URL como http: // localhost/test/edit/{id} y me gustaría la transformación {id} en un parámetro en lugar de la parte de ruta de URL.

¿Es la mejor manera de hacerlo creando un menú con RewriteRequest? Porque me pareció un poco de caldera si tengo un patrón de URL como este.

val menu = Menu(new Loc[Unit] {

    override def name = "Test"
    override def text = "Test"
    override def link = (List ("Test"), true)
    override def params = Nil
    override def defaultValue = Full(())


    def isTarget (path: ParsePath) = path match {
        case ParsePath (List("Test", "edit", id), _, _, _) => true

        case _ => false
    }

    override def rewrite = Full ( NamedPF("Test") {
        case RewriteRequest (path, _, _) if isTarget(path) => 
             RewriteResponse(List("Test", "edit"),  
                             Map("id" -> "1024")) -> ()

    })
})
¿Fue útil?

Solución

En su boot.scala, necesita lo siguiente (¡del código de trabajo real!) Tenga en cuenta que cada ruta de respuesta de rewriter debe estar en su mapa del sitio.

LiftRules.rewrite.append {
  case RewriteRequest(ParsePath(List("shopInfo", "view", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "view" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "orders", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "orders" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "sync", id), _, _, _), _, _) => RewriteResponse("shopInfo" ::  "sync" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "delete", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "delete" :: Nil, Map("id" -> id))
  case RewriteRequest(ParsePath(List("shopInfo", "edit", id), _, _, _), _, _) => RewriteResponse("shopInfo" :: "edit" :: Nil, Map("id" -> id))
}

Otros consejos

Gracias por todas sus respuestas.

Lo que más quiero es que estas reescriben cosas combinadas con el menú, por lo que podría configurarlas solo en mi clase de modelo, como el rasgo de Crudify.

Al final, creé una subclase de Loc para manejar estas reglas de reescritura, y descubrí que funciona bastante bien y pongo las cosas mucho más simples (al menos para mí), así que publico el código aquí.

No dude en copiar esto si alguien lo necesita

/**
 *  A RESTful-like URL handling Loc
 *
 *  If you have the following templates:
 *
 *    * webapps/item/edit.html
 *    * webapps/item/view.html
 *  
 *  You want the following URL map to corresponding template with 
 *  last path component as a S parameter.
 *
 *    http://localhost/item/edit/1  to  http://localhost/item/edit
 *    http://localhost/item/view/1  to  http://localhost/item/view
 *
 *  You could create a Menu with this Loc class in your Model object.
 *
 *  <code>
 *  object Item extends Item with LongKeyedMetaMapper[Item] 
 *  {
 *      // Other methods here...
 *
 *      def menu () {  
 *
 *          // What methods do we have?
 *          val methods = List ("view", "edit")
 *
 *          val parameterName = "itemID"
 *          val itemLoc = new RESTfulLoc("Item", List("item"), "Item", 
 *                                       methods, parameterName)
 *
 *          Menu (itemLoc)
 *      }
 *  }
 *  </code>
 *
 *  Now add the menu to SiteMap in Boot.boot
 *
 *  <code>
 *  class Boot {
 *      def boot () {
 *          
 *          val entries = Item.menu ::  Nil
 *
 *          LiftRules.setSiteMap(SiteMap(entries:_*))
 *      }
 *  }
 *  </code>
 *
 *
 *  Finally, You could access the parameter in your snippet with 
 *  S.param("itemID")
 *
 */
class RESTfulLoc (val name: String, val path: List[String],
                  val text: LinkText[Unit], val methods: List[String],
                  val parameterName: String,
                  val locParams: LocParam[Unit]*) extends Loc[Unit] 
{
    override val defaultValue = Full(())
    override val params = locParams.toList
    override val link: Link[Unit] = (List(path.first), true)

    def this (name: String, path: List[String], text: LinkText[Unit], 
              methods: List[String], locParams: LocParam[Unit]*) = 
    {
        this (name, path, text, methods, "id", locParams:_*)
    }

    private def isTarget (path: ParsePath) = 
    {
        path.partPath -- this.path match {
            case List (action, id) => {
                (methods contains action) && id != "index"
            }
            case _ => false
        }
    }

    override def rewrite = Full (NamedPF("RESTfulLoc") 
    {
        case RewriteRequest (path, _, _) if isTarget(path) => {
             val parameter = path.partPath.last
             val action    = path.partPath.init
             val data      = Map (parameterName -> parameter)

             RewriteResponse(action, data) -> ()
        }
    })
}

Me topé con esta publicación porque tenía la misma pregunta. La respuesta de Jim Barrows es correcta (y la más fácil), pero sin ninguna explicación fue difícil para mí agrupar lo que ese código está haciendo. Una explicación detallada de por qué las obras de solución de Jim se pueden encontrar en el libro de elevación en línea (http://groups.google.com/group/the-lift-book). Echa un vistazo a la Sección 3.12, titulada "Reescritura de URL" que te guía a través del paso por cómo construir una URL RESTful.

En cualquier caso, no debería haber necesidad de escribir un LOC personalizado para lograr el efecto deseado.

¡La mejor de las suertes!

Lo siento, el comentario anterior es un liitle desordenado.

El problema es que si tengo una plantilla llamada Edit.html en WebApp/Test, que es la plantilla que uso para editar un elemento.

Y tengo una instancia de menú como la siguiente:

Menu (Loc("Test", List("Test") -> true, "Test"))

Solo coincidiría con URL como http: // localhost/test/editar, no nada como http: // localhost/test/edit/1

¿Por qué quieres cambiarlo a consultar Param? ¿Es por razones técnicas o marco?

El {id} pertenece a mi opinión a la ruta URI, identifica un recurso único y me gusta mantener esta información dentro de la ruta. El URI puede ser cualquier tipo de cadena de caracteres (por lo que el parámetro de consulta también funcionaría), pero modelaría los URI lo más cercano posible ID conforme.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top