The simply functional web framework for Scala Covers Lift 2.x Timothy Perrett MANNING www.it-ebooks.info Lift in Action www.it-ebooks.info www.it-ebooks.info Lift in Action THE SIMPLY FUNCTIONAL WEB FRAMEWORK FOR SCALA TIMOTHY PERRETT MANNING SHELTER ISLAND www.it-ebooks.info To my Dad for teaching me that hard work and dedication can triumph over any problem For online information and ordering of this and other Manning books, please visit www.manning.com The publisher offers discounts on this book when ordered in quantity For more information, please contact Special Sales Department Manning Publications Co 20 Baldwin Road PO Box 261 Shelter Island, NY 11964 Email: orders@manning.com ©2012 by Manning Publications Co All rights reserved No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, mechanical, photocopying, or otherwise, without prior written permission of the publisher Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks Where those designations appear in the book, and Manning Publications was aware of a trademark claim, the designations have been printed in initial caps or all caps Recognizing the importance of preserving what has been written, it is Manning’s policy to have the books we publish printed on acid-free paper, and we exert our best efforts to that end Recognizing also our responsibility to conserve the resources of our planet, Manning books are printed on paper that is at least 15 percent recycled and processed without the use of elemental chlorine Manning Publications Co 20 Baldwin Road PO Box 261 Shelter Island, NY 11964 Development editors: Copyeditor: Typesetter: Cover designer: Katharine Osborne Andy Carroll Dennis Dalinnik Marija Tudor ISBN: 9781935182801 Printed in the United States of America 10 – MAL – 17 16 15 14 13 12 11 www.it-ebooks.info brief contents PART GETTING STARTED 1 Introducing Lift PART ■ ■ Hello Lift 20 APPLICATION TUTORIAL 37 The auction application 39 ■ Customers, auctions, and bidding 60 PART ■ ■ Shopping basket and checkout 83 LIFT IN DETAIL 105 ■ Common tasks with Lift WebKit ■ SiteMap and access control 140 ■ HTTP in Lift 160 ■ AJAX, wiring, and Comet 187 10 ■ Persistence with Mapper 223 11 ■ Persistence with Record 259 v www.it-ebooks.info 107 vi BRIEF CONTENTS 12 ■ Localization 282 13 ■ Distributed messaging and Java enterprise integration 293 14 ■ Application testing 15 ■ Deployment and scaling 317 www.it-ebooks.info 347 contents preface xiii acknowledgments xv about this book xvii about the author xxi about the cover illustration xxii PART GETTING STARTED .1 Introducing Lift 1.1 What is Scala? 1.2 What is Lift? Lift design goals View-first design Community and team 10 ■ 1.3 Lift features 11 Lift Core and Lift Web Lift Modules 17 1.4 Summary 12 ■ 18 vii www.it-ebooks.info Lift Persistence 15 CONTENTS viii Hello Lift 20 2.1 Getting started with SBT 21 2.2 Your first Lift application 23 Creating the project 23 Inspecting the project Booting the application 29 ■ 2.3 Snippets and templating overview Snippets 2.4 31 Summary 31 35 ■ Templating overview 26 33 PART APPLICATION TUTORIAL 37 The auction application 3.1 Application requirements Frontend 3.2 40 ■ 43 ■ Scaffolding 43 Validation Summary ■ Connecting to the database 49 50 50 CRUD generation 53 Displaying field errors 58 ■ 57 Definitions 58 3.6 Template setup Data models 46 Prototype traits 3.5 41 Template structure 43 Schema definition 46 3.4 40 Administration Design workflow 3.3 39 ■ 59 Customers, auctions, and bidding 60 4.1 Building an auction catalog Listing auctions 61 4.2 ■ Displaying auctions 61 Adding to SiteMap 65 66 Auction detail URLs 66 The AJAX bidding interface 68 Real-time bidding 74 ■ ■ 4.3 Summary 82 www.it-ebooks.info CONTENTS ix Shopping basket and checkout 83 5.1 Order creation 84 Order models 84 5.2 ■ Attributing auctions to customers 87 Implementing the basket and checkout process Implementing the basket 5.3 Summary 99 91 Implementing the checkout 93 Collecting payment with PayPal Environment setup 5.4 91 ■ 99 The Buy Now button 102 ■ 103 PART LIFT IN DETAIL 105 Common tasks with Lift WebKit 107 6.1 Templates, snippets, and views Templates 6.2 108 Managing state ■ Snippets 114 Widgets 132 ■ 128 Wizard ■ Cookies 130 Summary 131 135 137 AutoComplete widget 6.5 Views 125 Forms with LiftScreen and Wizard LiftScreen 6.4 ■ 128 Request and session state 6.3 108 137 Gravatar widget ■ 138 139 SiteMap and access control 140 7.1 Menus and locations 141 Understanding and implementing locations Rendering menus 143 7.2 Location parameters 143 146 Default location parameters 147 Authentication parameters 150 7.3 Customizing SiteMap Creating a custom Loc 7.4 Summary 153 153 ■ 159 www.it-ebooks.info When to customize SiteMap? 158 Options and boxes 389 function if the value exists, so let’s simulate this by explicitly passing null to the Option type’s apply method: scala> Option[String](null).map(_.toLowerCase) res2: Option[java.lang.String] = None Notice that the definition is exactly the same as before, but the value is explicitly null The function definition is the same, but it doesn’t explode with a NullPointerException because the function is never executed Option is clever enough to realize that the value is null, so it returns the strongly typed representation of a nonvalue: None These two examples are explicit, but trivial Consider something more likely to crop up within your application Perhaps you query the database for a value, but the value you’re looking for may not exist In that case, it would be a lot better to receive a properly represented result in the form of None than it would be to simply receive null Appendix A (section A.2) describes some of the actions typically associated with collections and data structures within Scala, covering the map and flatMap functions found in most Scala collections Option also sports these methods, and by virtue of map and flatMap it’s possible to use what is known as a for-comprehension as some nice syntactic sugar for interacting with collection types Because Option is also a collection type, using for-comprehensions allows you to chain options together, so that they only fall through to the next function if the value is something Consider the following: scala> for { a val two: Option[Int] = None two: Option[Int] = None scala> for { | a