Slide 1

Slide 1 text

Simple Front-End Development with Pedestal Chad Taylor, @tessellator

Slide 2

Slide 2 text

What is Pedestal? (http://pedestal.io)

Slide 3

Slide 3 text

A collection of libraries for web development in Clojure and ClojureScript A collection of tools to help ease the development by keeping concerns separated

Slide 4

Slide 4 text

Two pieces: pedestal-service & pedestal-app (inc ring) front-end framework

Slide 5

Slide 5 text

Today, we discuss pedestal-app

Slide 6

Slide 6 text

pedestal-app tutorial is... available at https://github.com/pedestal/app-tutorial/ dense complete sometimes hard-to-follow due to the number of concepts presented

Slide 7

Slide 7 text

My goals are two-fold: Prepare you for the tutorial if you haven’t tried it Clarify some of the fuzzier details if you have

Slide 8

Slide 8 text

How is Pedestal different from X.js?

Slide 9

Slide 9 text

These are mostly view-concerned. Pedestal provides more infrastructure for building large applications, supporting separation of concerns throughout the development cycle. Pedestal decouples the concept of rendering from the DOM and even decouples event registration.

Slide 10

Slide 10 text

This results in more flexibility - ranging from automatic rendering to building tools that record and playback application events. Since the application model is decoupled from the DOM, the application is also more testable.

Slide 11

Slide 11 text

These break an application down into the familiar MVC model. Mutation is handled locally within services and controllers. Complexity begins to ramp when dealing with dynamic data (e.g., from web sockets). Pedestal breaks the problem down differently. It constrains mutation to be localized within the Pedestal library and keeps complexity low, even with highly interactive applications.

Slide 12

Slide 12 text

Another way to say this is that X.js makes development easy, while Pedestal makes it simple. Complexity with X.js can ramp quickly - especially when building highly interactive applications. Complexity with Pedestal stays relatively flat.

Slide 13

Slide 13 text

Just remember: Simple ain’t easy.

Slide 14

Slide 14 text

(Whew.)

Slide 15

Slide 15 text

Okay, I’m convinced. Now what?

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

That’s it!

Slide 18

Slide 18 text

Whelp...my job here is done.

Slide 19

Slide 19 text

Okay, okay. I kid.

Slide 20

Slide 20 text

Before we get started, a quick Clojure syntax tutorial:

Slide 21

Slide 21 text

:keyword “string” [“a” “vector”] #{:a :set} {:a :map :key :value} (op args)

Slide 22

Slide 22 text

Let’s follow some data through the app

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

Collects messages to be processed by the application

Slide 25

Slide 25 text

Messages can theoretically come from anywhere, such as an AJAX call resolving or an event in the UI occurring

Slide 26

Slide 26 text

Messages are just data

Slide 27

Slide 27 text

Messages have a type and a topic type - The type of the message topic - The data with which the message is concerned path in data model

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

root node :my :counter

Slide 30

Slide 30 text

Messages can also have additional data elements. Add whatever you need - it’s just data!

Slide 31

Slide 31 text

When a message is being handled, we want to transform the data element in the data model based on the message. To do this, we write a pure function and let Pedestal handle the data model mutation for us.

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

current value in data model the transform logic protect against nil behavior.clj A Transform Function the message from the input queue

Slide 34

Slide 34 text

First Run

Slide 35

Slide 35 text

Second Run

Slide 36

Slide 36 text

I don’t actually care about the message! indicates “don’t care” HINT

Slide 37

Slide 37 text

But...how do I tie the message to use that transform? You configure the application Dataflow

Slide 38

Slide 38 text

Dataflow is... described implicitly in the tutorial the app wiring, connecting functions & data sometimes used as a proper noun, sometimes not (I will strive to use it as a proper noun) defined with a map

Slide 39

Slide 39 text

I think of the Dataflow as the arrows... HINT

Slide 40

Slide 40 text

Dataflow definition Since the definitions are in a vector, order matters. A message is handled by the first matching transform. behavior.clj

Slide 41

Slide 41 text

the message type to match against the topic the transform function

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

That was a lot of work. Let’s see our progress!

Slide 46

Slide 46 text

...but I {{ mustache }}, what about templates? No worries, we don’t need any right now. Why the HTML not?! Pedestal provides some pretty cool tools that help keep application logic and rendering separated.

Slide 47

Slide 47 text

To show the aspects, move the cursor to the page’s lower-right. http://localhost:3000

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

Cool tooling, bro.

Slide 50

Slide 50 text

Hmm, I’m not sure what happened there...

Slide 51

Slide 51 text

Wait, I’ve got it! If the input queue started out empty, then the data model must be empty!

Slide 52

Slide 52 text

Let’s add a message to the queue during application startup...

Slide 53

Slide 53 text

start.cljs the input queue the message to enqueue

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

Okay, so we’ve set up a data model. Now what?

Slide 56

Slide 56 text

Well, now we need to define an application model. • distinct model for rendering concerns • derived from data model

Slide 57

Slide 57 text

The application model is defined by emitted deltas generated from functions that observe changes to the data model. The deltas are passed to the renderer.

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

Most of the time, this is just a pass-through. Pedestal provides a default emitter for this case.

Slide 60

Slide 60 text

Dataflow Emitter Configuration behavior.clj

Slide 61

Slide 61 text

a set of paths in the data model to watch for changes a function to generate application model deltas from the data model changes

Slide 62

Slide 62 text

a higher-order function that creates an emitter function a prefix to attach to changed nodes (e.g., [:my :counter] in the data model becomes [:main :my :counter] in the application model)

Slide 63

Slide 63 text

HINT The term Data UI is somewhat misleading. It renders the application model, not the data model. It took me awhile to pick up on this little detail... Now, an aside:

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

If you look at your browser’s developer tools, you can see the rendering deltas in the console.

Slide 66

Slide 66 text

Can you guess what each step is doing?

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

Okay, this is cool and all, but I’m bored. When can make it do something?

Slide 69

Slide 69 text

To do this, we need to tell the renderer that it can initiate a transform to the application model by sending messages to the input queue. We achieve this by sending a delta to the renderer informing it about the transform.

Slide 70

Slide 70 text

behavior.clj

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

indicates that the delta should be sent at application startup the function that will provide the deltas

Slide 73

Slide 73 text

(Technically, the deltas will be sent when Focus changes, but that’s a topic for later...)

Slide 74

Slide 74 text

Meanwhile, in the Data UI renderer...

Slide 75

Slide 75 text

this is what causes the button to appear in the Data UI

Slide 76

Slide 76 text

It’s a button...Push it! What’s the worst that could happen?

Slide 77

Slide 77 text

No content

Slide 78

Slide 78 text

No content

Slide 79

Slide 79 text

Now we’re getting somewhere! Now, if only we could make it so that my designer won’t puke when she sees it...

Slide 80

Slide 80 text

tutorial-client.html Okay, let’s start with some HTML:

Slide 81

Slide 81 text

Now, let’s look at the design without the app

Slide 82

Slide 82 text

Click “Design” to view the template

Slide 83

Slide 83 text

http://localhost:3000/design.html

Slide 84

Slide 84 text

http://localhost:3000/design/tutorial-client.html

Slide 85

Slide 85 text

Okay, so the markup appears fine...but how can I make sure that everything is wired up correctly?

Slide 86

Slide 86 text

Well, let’s record the application model deltas and play them back to a renderer.

Slide 87

Slide 87 text

In the Data UI, press Alt-Shift-R. (Yes, even on OS X.) Press the button a few times, then press Alt-Shift-R again. When prompted, provide a :keyword and a description of what you did during the recording session.

Slide 88

Slide 88 text

This creates a file with all the deltas saved into it. The deltas can be replayed later.

Slide 89

Slide 89 text

Now go to the “Render” aspect. runs all deltas immediately runs one transaction at a time (press -> to advance) runs one delta at a time (use <- and -> to update)

Slide 90

Slide 90 text

How in the world is this useful?

Slide 91

Slide 91 text

Let me start by showing you the generated file:

Slide 92

Slide 92 text

No content

Slide 93

Slide 93 text

It’s just data!

Slide 94

Slide 94 text

Now, imagine a really hard-to-duplicate sequence of events that you want to ensure are rendered properly. This tool lets you write that sequence, and then step through it!

Slide 95

Slide 95 text

No more wasting time attempting to generate the situation in the browser. No more succumbing to non-repeatability. No more crying yourself to sleep while wondering how to duplicate that bug deep down in the dark asynchronous abyss in your project.

Slide 96

Slide 96 text

No content

Slide 97

Slide 97 text

(I am skipping Template Slicing here to save time. Check it out in the tutorial!)

Slide 98

Slide 98 text

Configuring the renderer rendering.cljs

Slide 99

Slide 99 text

the delta operation to handle the application model path to watch the handling function

Slide 100

Slide 100 text

(This pattern should be feeling familiar now.)

Slide 101

Slide 101 text

Send the messages from the previously defined :transform-enable to be sent to the input queue when “#inc-button” is clicked.

Slide 102

Slide 102 text

Now we’re nearing the end of the presentation. What have we covered?

Slide 103

Slide 103 text

No content

Slide 104

Slide 104 text

So...Pedestal is a big subject. ...and I ramble.

Slide 105

Slide 105 text

Please check out the tutorial. It is super awesome. But keep this presentation handy, too! It will help with some of the tricky bits.

Slide 106

Slide 106 text

Special thanks to Eric Pritchett for guiding me through some edge cases...

Slide 107

Slide 107 text

Questions? @tessellator