在Boot中, SiteMap 中定义 Menu ,将 template中的lift:signup关联到
Menu(Loc("sign_up", List("signup"), S.?("base_menu_signup"), Snippet("signup", User.signupForm _), Unless(User.loggedIn_? _, S.?("base_menu_sign_up_error"))))
User中signupForm的定义如下:
def signupForm(xhtml: NodeSeq): NodeSeq = { /* * S.referer Returns the 'Referer' HTTP header attribute */ val from = S.referer openOr "/" val user = User.create val auth = UserAuth.defaultAuthModule.createHolder() /* * S.invokedAs * Returns the 'type' S attribute. This corresponds to the current Snippet's name. For example, the snippet: * <lift:Hello.world /> * Will return "Hello.world". */ val snippetName = S.invokedAs def genForm(xhtml: NodeSeq): NodeSeq = { /* *bind (namespace: String, xml: NodeSeq, params: BindParam*): NodeSeq *Bind a set of values to parameters and attributes in a block of XML. */ bind("signup", xhtml, /* * new SuperArrowAssoc (name: String) * def -%> (in: (NodeSeq) ⇒ NodeSeq): FuncBindParam */ "nickname" -%> user.nickname.toForm, //def toForm : Box[Elem] Create an input field for the item "firstname" -%> user.firstName.toForm, "lastname" -%> user.lastName.toForm, "image_url" -%> user.imageUrl.toForm, "timezone" -%> user.timezone.toForm, "locale" -%> user.locale.toForm, "credentials" -> auth.toForm, /* * The SHtml object defines a suite of XHTML element generator methods * to simplify the creation of markup, particularly with forms and AJAX * * def submit (value: String, func: () ⇒ Any, attrs: ElemAttr*): Elem * Generates a form submission button. */ "submit" -%> SHtml.submit(S.?("base_user_ui_signup"), doSubmit _) ) ++ SHtml.hidden(() => { doSubmit}) } def processEntryAdd() { logger.debug("processEntryAdd: " + firstName + ", " + lastName) } def doSubmit() { /* * S.mapSnippet * Associates a name with a snippet function 'func'. This can be used to * change a snippet mapping on a per-request basis. */ S.mapSnippet(snippetName, genForm) //why? user.validate ::: auth.validate match { case Nil => user.save auth.save(user) User.logUserIn(user) S.notice(S.?("base_user_msg_welcome", user.niceName)) S.redirectTo(from) case fe => S.error(fe) } } genForm(xhtml) }
doSubmit是个有副作用的函数,把user 和 auth保存起来,让user登录进来
注册页面 signup.html:
<lift:signup form="post" id = "validateForm"> <div id="form-signup"> <signup:credentials/> <div class="post-form-row"> <label class="main"><lift:loc>ui_sign_up_nickname</lift:loc></label> <signup:nickname class="inputBox2"/> </div> <div class="post-form-row"> <label class="main"><lift:loc>ui_sign_up_firstname</lift:loc></label> <signup:firstname class="inputBox2"/> </div> <div class="post-form-row"> <label class="main"> <lift:loc>ui_sign_up_lastname</lift:loc></label> <signup:lastname class="inputBox2"/> </div> <div class="post-form-row"> <label class="main"> <lift:loc>ui_sign_up_image_url</lift:loc></label> <signup:image_url class="inputBox2"/> </div> <div class="post-form-row"> <label class="main"> <lift:loc>ui_sign_up_timezone</lift:loc></label> <signup:timezone class="inputBox2"/> </div> <div class="post-form-row"> <label class="main"><lift:loc>ui_sign_up_locale</lift:loc></label> <signup:locale class="inputBox2"/> </div> <div class="post-form-row"> <div class="submit-btn"> <signup:submit type="image" src="images/btn-signup-big.gif" /> </div> </div> </div><!--form-signup--> </lift:signup>
注意:
<signup:credentials/>
对应 :
"credentials" -> auth.toForm
auth的toForm定义如下:
def toForm: NodeSeq = TemplateFinder.findAnyTemplate("templates-hidden" :: "upw_signup_form" :: Nil).map( xhtml => bind("signup", xhtml, "email" -%> SHtml.text(email, s => email = s.trim.toLowerCase), "pwd1" -%> SHtml.password(pwd1, s => pwd1 = s.trim), "pwd2" -%> SHtml.password(pwd2, s => pwd2 = s.trim)) ) openOr NodeSeq.Empty