Est-ce que cette façon correcte de gérer RESTful comme URL dans le cadre de levage?

StackOverflow https://stackoverflow.com/questions/2036037

  •  19-09-2019
  •  | 
  •  

Question

Si j'ai une URL comme http: // localhost / test / edit /{id} et je voudrais que la transformée {id} en un paramètre au lieu de la partie du chemin d'URL.

Est-ce le meilleur moyen de le faire en créant un menu avec RewriteRequest? Parce que je l'ai trouvé un peu de passe-partout si j'ai un modèle d'URL beaucoup comme celui-ci.

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")) -> ()

    })
})
Était-ce utile?

La solution

Dans votre boot.scala, vous avez besoin de ce qui suit (à partir du code de travail réel!) Notez que chaque chemin de réécriture doit être dans votre plan du site.

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))
}

Autres conseils

Merci pour toutes vos réponses.

Ce que je veux le plus, c'est que ces choses réécrivent étroitement avec le menu, afin que je puisse les configurer juste dans ma classe de modèle, comme Crudify Trait.

En fin de compte, j'ai créé moi-même une sous-classe de LOC pour gérer ces règles de réécriture, et j'ai trouvé que cela fonctionne assez bien et rend les choses beaucoup plus simples (du moins pour moi), donc je publie le code ici.

N'hésitez pas à le copier si quelqu'un en a besoin

/**
 *  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) -> ()
        }
    })
}

Je suis tombé sur ce post parce que j'avais la même question. La réponse de Jim Barrows est correcte (et la plus facile), mais sans aucune explication, il m'a été difficile de faire de ce que ce code fait. Une explication détaillée des raisons pour lesquelles les travaux de la solution de Jim peuvent être trouvés dans le Lift Book en ligne (http://groups.google.com/group/the-lift-book). Consultez la section 3.12, intitulée "Réécriture d'URL" qui vous guide pas à pas sur la façon de construire une URL reposante.

En tout cas, il ne devrait pas être nécessaire d'écrire un LOC personnalisé pour atteindre l'effet souhaité.

Bonne chance!

Désolé, le commentaire ci-dessus est un liitle désordonné.

Le problème est que si j'ai un modèle nommé edit.html sous webapp / test, qui est le modèle que j'utilise pour modifier un élément.

Et j'ai une instance de menu comme ce qui suit:

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

Il ne correspondait qu'à l'URL comme http: // localhost / test / modifier, pas rien comme http: // localhost / test / edit / 1

Pourquoi voulez-vous le changer en param de requête? Est-ce pour des raisons techniques ou de cadre?

Le {id} appartient à mon point de vue au chemin URI, il identifie une ressource unique et j'aime garder ces informations à l'intérieur du chemin. L'URIS peut être n'importe quel type de chaîne de caractères (donc le paramètre de requête fonctionnerait également), mais je modéliserais l'uris aussi proche que possible des ressources.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top