The new percolator is to be loaded in the following ratio:

1/8 cup (metal scoop) per 2 cups water.

Review pending.

The MappedEmail class does not take kindly to blank submissions in it’s default form, however with a simple override you can retain all the goodness of the validations built into MappedEmail, while ignoring these requirements if there is no value submitted:

object emailAddress extends MappedEmail(this, 100) {
override def validate = if (this.is == "") Nil else super.validate
}

Open up your preferences, and go to your SBT settings. You want to add this to your VM Parameters: “-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005″

Now to debug, you need to create a new debugging profile of type “Remote”

And make sure that it is running with your sbt debug line ” -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005″, and verify that the settings are set to transport:socket, debugger mode: Attach, and host:localhost on port 5005.

Set breakpoints and enjoy.

Lift provides built in snippets to allow easy pagination of data. Here is a brief reference for the SortedMapperPaginatorSnippet (SMPS henceforth). As you can tell from the name, it specifically allows sorted pagination of mapper data.

The Lift documentation provides more general information on PaginatorSnippets here.

Let’s say you have a snippet called listProducts. You’d like listProducts to display a sorted pagination of all your products, which are stored in your database. Of course, you’ve already created Mapper classes to relate to the data. The very first thing to do is add a couple of imports to your snippet:

import net.liftweb.mapper.{By, OrderBy, MaxRows, Like,Cmp,NotNullRef,NullRef, QueryParam, StartAt, Ascending, Descending}
import net.liftweb.mapper.view.{MapperPaginatorSnippet, SortedMapperPaginatorSnippet}

Now let’s create the paginator.

val paginator = new SortedMapperPaginatorSnippet(Product, Product.createdAt, “createdAt” -> Product.createdAt, “price” -> Product.price) {

}

The first argument sets the mapper class we are querying. The next one specifies the column we want to sort by initially. Finally we have the two columns we will allow the user to sort by. These are actually both part of the third argument, but thanks to scala’s repeated parameters, we can have as many choices as we’d like. The third argument(s) should be pair(s) of column labels [String] and MappedFields.

Now let’s say we want to add some custom query criteria. For example, let’s only return products who have their inStock field set to true. To do this, we must set the constantParams var that is built into SMPS. This variable takes the format of a Seq[QueryParam]. So inside our paginator, add the following code:

var params: List[net.liftweb.mapper.QueryParam[Product]] = Nil
params = By(Product.inStock, true) :: Nil
constantParams = params

The first line sets up the Seq[QueryParam] format of the variable. Then, we set the list to have 2 elements: first is a By QueryParam and second is a Nil. If we had set the variable to just the QueryParam, then Scala would have changed the variable type to QueryParam. By prepending a Nil to the end, it maintains its status as a sequence of elements. The By param takes two arguments. First is the Mapper field to check and second is the value it must be. So in this case, we are checking the inStock is true. Finally set constantParams equal to params. This adds our custom query to the SMPS’s logic.

This is all you need to do to set up an SMPS in a snippet. To add it to a template, you need to bind each page to something in the xhtml. An example of how to do this would be to add this code to the snippet (outside of the paginator!):

def all(xhtml: NodeSeq) : NodeSeq = paginator.page.flatMap(a => bind(“p”,xhtml,”createdAt” -> a.createdAt, “price” -> a.price, “inStock” -> a.inStock))

Paginator creates a “page” that is essentially a list of Products that is sorted and offset based on which page the user has selected. The code above simply binds each product in the paginator.page to some xhtml code. We could use this on a Lift template like this:

<lift:listProducts.paginator.paginate>
<tr><th><sort:createdAt /></th><th><sort:price /></th></tr>
</lift:listProducts.paginator.paginate>

<lift:listProducts.all>
<tr><td><p:createdAt /></td><td><p:price /></td><td><p:inStock /></td></tr>
</lift:listProducts.all>
<lift:listProducts.paginator.paginate>            <nav:first/>            |            <nav:prev/>            |           <nav:allpages/>          |            <nav:next/>            |            <nav:last/>            |            <nav:records/>
</lift:listProducts.paginator.paginate>

Note that all of the tags inside both the <lift:listProducts.paginator.paginate> areas are built into SMPS, which the code inside <lift:listProducts.all> is populated by the custom all function we defined above. Also note that all this can (and should) be customized for your own needs.

A final point about SMPS is that the current sort field, offset, and sort order can all be set by url query strings:

paginatorpage?sort=0 would cause our SMPS above to sort by the createdAt field. sort=1 would cause it to sort by price.

paginatorpage?offset=100 would cause our SMPS’s current page to start at record 100.

paginatorpage?asc=false would cause our SMPS to sort in descending order.

Of course these can be combined such as: paginatorpage?sort=1&asc=true

 

 

 

Before you start this tutorial, make sure you have the following handy:

  • An email address hosted by Morroni Technologies
    (For this tutorial, we will use info@morroni.com as an example)
  • A username
    (For this tutorial, we will use mor0127 as an example)
  • A password

Once you are ready, go to your iPhone home screen and tap the Settings icon.

In settings, scroll to and tap Mail, Contacts, Calendars

Tap Add Account

Tap Other

Tap Add Mail Account

At this next screen, you will need to enter the name you want associated with your email account. The sample image below uses “Morroni Technologies” but you can enter anything you want.

For the Address and Password please enter the email address and password you were provided with.

Tap Next when finished.

The next step is to set up the Incoming/Outgoing mail servers. First, set up the Incoming Mail Server (IMAP).

  • Host Name: mailserver.morroni.com
  • User Name: Enter the User Name (not the email address!) you were sent by Morroni Technologies. In the sample image below, mor0127 is the user name.
  • Password: Enter the password you were sent.

Now, scroll down to set up the Outgoing Mail Server (SMTP).

  • Host Name: smtpserver.morroni.com
  • User Name: Enter the User Name (not the email address!) you were sent by Morroni Technologies. In the sample image below, mor0127 is the user name.
  • Password: Enter the password you were sent.

Tap Next when finished.
Note: If you get a message saying Cannot Verify Server Identity tap Continue as shown below.

When the Verifying… is finished, you will be greeted with the following screen. Tap Save.
At this point, your iPhone can send and receive messages using your Morroni account.
However, we need to instruct it to use your Morroni Trash, Drafts, and Sent folders instead of sharing with your other email accounts. To do so, first return to your home screen and open the Mail app.

Scroll down to Accounts (not inboxes!).

Note: On the New Account screen from before, there was a Description field. If you made any changes to that field, the description you entered will be the name of the account you want to tap. Otherwise, tap the account that is labelled with your new email address. For the tutorial images, we did not make a change to the Description field, so the Account to select is simply the info@morroni.com email address.
Select your newly created account.
Ensure that under Inbox is a list of email folders as is show below. If the only item listed is Inbox, you may need to tap the refresh icon in the lower left corner of the screen.

 

 

 

 

 

Scroll down and tap Mail, Contacts, Calendars. Tap your newly created account in the list as shown below. Again, it will be labelled with either your email address or, your description if you entered one.


You will arrive at the account settings screen pictured below. Tap the account under IMAP.

Scroll to the bottom of this screen and tap Advanced.

Tap Drafts Mailbox

Scroll to the On The Server list and select Drafts.

Tap the Advanced button in the upper left corner of the screen.
Tap
Sent Mailbox.

Scroll to the On The Server list and select Sent.

Tap the Advanced button in the upper left corner of the screen.
Tap
Deleted Mailbox.

Scroll to the On The Server list and select Trash.


At this point, you are ready to use the iPhone Mail app with your Morroni Email account. Simply press the home button and tap the Mail app to begin!

I’ve been searching for the ideal startup process when building a lift project and I might have just found it!

I am using simple-build-tool(sbt) and two sbt processors.  The processors are:

lifty:  http://lifty.github.com/Lifty/
sbt-idea:  https://github.com/mpeltonen/sbt-idea

Here are the steps:

amore:wheels lmorroni$ sbt
Project does not exist, create new project? (y/N/s) y
Name: appName
Organization: com.morroni
Version [1.0]:
Scala version [2.7.7]: 2.8.1
sbt version [0.7.4]:
...
>*lifty is org.lifty lifty 1.6
>*sbtIdeaRepo at http://mpeltonen.github.com/maven/
>*idea is com.github.mpeltonen sbt-idea-processor 0.3.0
>lifty create project-blank with user
>reload
>update
>idea
>~jetty-run

References:

http://lifty.github.com/Lifty/

https://github.com/mpeltonen/sbt-idea

If you’re developing lift in IntelliJ, often you get popup inspector errors all over your XHTML markup because the namespaces of your snippet classes, etc. are not valid. To turn it off, you can click on the inspector in the bottom right of the intelliJ window, Configure Inspections, and turn off that specific XML setting inspection in the XML options. Nothing huge, but it saves some annoyance.

This may not seem like a difficult task for many of the more experienced Scala/Lift developers out there but it took me some time to write this little piece and I thought I would share it.
I basically needed a way to redirect clients running IE6 to a single page which explained that the site does not support their browser and here is how to upgrade. To do this, I used the LiftRules object’s dispatch field inside the boot.scala file. Here’s the line of code:

LiftRules.dispatch.prepend {
case Req(path, _, _) if (path != List("unsupported-browser") && S.request.dmap(false)(_.isIE6)) => () => {Full(RedirectResponse("unsupported-browser"))}
}

So I showed this line to my co-worker, Jeff, and his eyes almost popped out of his head. I am digging Scala and Lift and I do see the power once I get a grasp on the syntax. However, ramping up in this language is no small task. It has actually been quite difficulty for me and while I may not be the sharpest developer in the world, I think I am relatively capable. Anyway, enough of a rant. Here’s what is going on above. If any Scala masters are reading this and want to correct my explanation, please feel free.
We are prepending a new rule to the dispatch field. The format of the case statement is basically case pattern if guard => {/*do something*/}
The part that I got stuck on was binding a variable in the pattern that could be used in the guard. So here’s how it breaks down.
Pattern: Req(path, _, _)
This grabs the current dispatch request and binds the path variable to the current path list.

Guard: if (path != List("unsupported-browser") && S.request.dmap(false)(_.isIE6))
The guard takes the binded path variable and checks to make sure it is any single path on the site EXCEPT the /unsupported-browser path. That is an important part since we do not want a infinite loop redirect. The second half of the guard takes the current session request box and uses dmap to open it and check if the current browser is indeed ie6.

Action: If the pattern and guard are satisfied then we do a redirect to the unsupported browser page.

Hopefully some people find this information useful.

Update: This is easier now. See this post: http://blog.morroni.com/2011/03/11/the-best-lift-sbt-intellij-startup-process/
This post describes how to get IntelliJ, Git, SBT(Scala Build Tool) and Lift playing nicely together. This post assumes you have Maven and SBT already installed since you will need them in order to make this work. More information about the sbt setup is here: http://code.google.com/p/simple-build-tool/wiki/Setup. Information about installing maven is available here: http://maven.apache.org/run-maven/index.html

Install GIT

  1. Browse to http://code.google.com/p/git-osx-installer/
  2. Install the git package.
  3. After installation, you need to run a shell command to finish things properly. it sets paths and what not.
  4. Open up a terminal.
  5. Change directories to the mounted image
  6. bash$ cd /Volumes/Git\ 1.6.4.4\ Intel\ Leopard/
  7. bash$ ./setup\ git\ PATH\ for\ non-terminal\ programs.sh
  8. Close your terminal and reopen it. Now type git and confirm it is installed.

Download archetype

  1. Open up terminal and browse to a folder where you will store your project.
  2. Type the following:
  3. mvn archetype:generate -U \
    -DarchetypeGroupId=net.liftweb \
    -DarchetypeArtifactId=lift-archetype-basic \
    -DarchetypeVersion=2.0 \
    -DremoteRepositories=http://scala-tools.org/repo-releases \
    -Dversion=0.1 \
    -DgroupId=com.myCompany.myProject -DartifactId=myProject
  4. Change into the folder where the project was created and type <code>sbt update</code>.  this will download the libraries and crate the sbt project folder.

Open IntelliJ

I did a pretty verbose post on using IntelliJ with lift here:  http://blog.morroni.com/2010/07/14/setup-intellij-9-for-lift-framework-development/. This assumes you have installed the Scala and SBT plugins in IntelliJ.

  1. Now we open up IntelliJ and import the maven project.  File -> New Project ->Import Project From External Model.
  2. Let IntelliJ do its thing and when it is done, we will need to add a class describing sbt build information.  Create a folder inside project/build and create a file called LiftProject.scala.  Place the following inside that file.
    import sbt._
    class LiftProject(info: ProjectInfo) extends DefaultWebProject(info) {
    val liftVersion = "2.0"

    override def libraryDependencies = Set(
    "net.liftweb" % "lift-webkit" % liftVersion % "compile->default",
    "net.liftweb" % "lift-mapper" % liftVersion % "compile->default",
    "org.mortbay.jetty" % "jetty" % "6.1.22" % "test->default",
    "junit" % "junit" % "4.5" % "test->default",
    "org.scala-tools.testing" % "specs" % "1.6.2.1" % "test->default",
    "com.h2database" % "h2" % "1.2.138"
    ) ++ super.libraryDependencies
    }

  3. Open up a terminal and inside your project folder type sbt ~jetty-run
  4. Open up your web browser and browse to http://localhost:8080
  5. Hopefully, you see your project.  if not, it’s probably because my post was too terse.  I apologize, but a lot of these posts are just so I do not forget certain processes :)

I am making an assumption here that you already know the normal forward-usage of the patch command. If you’re unversed In case you didn’t want to decipher the entire man page just yet, you’re in luck. I came across an instance where I had to remove a previous patch file from the Magento Enterprise code-base. The patch was originally applied as so:

patch -p0 < firstpatch.patch

Problems ensued, and I was given a new patch, however it was a cumulative patch so it couldn’t be laid over the first patch. So how to remove? After a man-page reading, it’s quite a breeze. You need the original patch to be removed, and use the patch number you used in the first patching instance. In this case it equates to the following:

patch -R -p0 < firstpatch.patch

now you can add the new patch.

patch -p0 < secondpatch.patch

Hopefully this will save someone a man-page reading on a small terminal in a dimly lit server room. :-)