Fork me on GitHub
#clojure
<
2015-12-12
>
amacdougall01:12:23

I'd like some advice about compojure-api. I began with a routes list like this:

(context* "/api" []
  (context* "/users" []
    <many routes>)
  (context* "/videos" []
    <many routes>))
But over time, that form got so huge that vim start to give up on highlighting and indenting it. Yes, that's an editor issue, but I took it as a sign that I should split the file up into namespaces... now I discovered that if I put the subcontexts into defs, I can do this:
(context* "/api" []
  users-context
  videos-context)
...but the API no longer has Swagger-UI documentation. This is probably some macro processing issue. It's a long shot, but if anyone knows what's going on here...

ikitommi07:12:47

@amacdougall instead of def + context*, try defroutes*. plan in to move swagger-doc generation from compile time to runtime soon, so the the def + context* would work too. There is a #C06GSN6R2 if you'd like to chat more. cheers.

roelof08:12:53

@sveri: thanks, im just awake and will look into it

roelof08:12:07

@sveri: looks nice, if I only want to use selmer and the login , autherisation part without reagent. Do I have to use only the clj directory in src ?

roelof08:12:22

sorry for so many questions but im eager to learn

sveri08:12:19

@roelof yes, the backend stuff is in clj folder and the templates are in resources/templates

roelof08:12:25

oke, thanks, I will play today with it

roelof08:12:03

@sveri if I want to start clean I can do lein new compojure app-name

sveri08:12:11

Yes, that is one way to do it

roelof08:12:34

oke, and the other is ?

sveri08:12:49

Starting with an empty leiningen template or adapting an existing one like closp or luminus

sveri08:12:47

No matter which route you take, understanding all the moving parts will take months

roelof09:12:22

that is no problem

roelof09:12:41

As I said yesterday this is a hobby project of mine

roelof09:12:07

I like to closp one but then I have to delete a whole part

roelof09:12:27

I still have to learn things like cljs , figwheel and so on

roelof09:12:59

So I will start with just clojure , my first goal is to set up the login part and the templates

sveri09:12:50

then maybe it's best to start with compojure

sveri09:12:05

and add the libraries step by step by following the documentation on their page

sveri09:12:31

However, there is one thing that will speed up development much more, especially when learning things

sveri09:12:48

By using component or mount you will be able to reload code without restarting the repl everytime

sveri09:12:59

this is especially useful to find compile errors as a reload will show them

sveri09:12:15

and after you fixed the error you can just reload again and see if it works

roelof09:12:51

oke, thanks

roelof09:12:10

I wil dive in component first

sveri09:12:38

you might as well take a look at mount:https://github.com/tolitius/mount might be easier to get

roelof09:12:11

Thanks, looks difficult

sveri09:12:58

of course this is always subjective, but getting component to work was one of the hardest parts of all for me starting with clj / cljs and compared to that mount looks easier to understand, but, like I siad, that's just my point of view

dm309:12:17

component is very un-lispy compared to mount

dm309:12:57

with mount you just have a var in a namespace

roelof09:12:21

maybe I ask for help if im ready to use databases and sessions

roelof09:12:06

and will study the closp source code well

roelof09:12:27

First task : settting up the project and translate the layout to selmer

roelof11:12:08

I have this :

` (ns clcommerce.routes.home
(:require [compojure.core :refer [defroutes GET]]
          [clcommerce.layout :as layout]
          [ring.util.response :refer [response]]))

(defn home-page []
  (layout/render "home/index.html"))

(defn contact-page []
  (layout/render "home/contact.html"))

(defroutes home-routes
           (GET "/" [] (home-page))
           (GET "/contact" [] (contact-page)))

roelof11:12:36

but now I see this error message : No such var: layout/render

roelof11:12:52

what do I miss in the require part

solicode11:12:34

The require looks fine to me. If it was wrong, I would expect you to get an error there or something like “No such namespace: layout”. What does clcommerce.layout look like. Are you sure there’s a render in it? Or maybe you haven’t loaded the latest changes in that file?

roelof11:12:13

@solicode: you mean the layout.clj file

roelof11:12:03

That one has this into it :

(ns clcommerce.layout
  (:require [selmer.parser :as parser]
    )
)

(parser/set-resource-path!  ( "templates")) 

roelof11:12:33

so no render function

solicode11:12:48

Okay, yeah, that’s the problem

roelof11:12:03

Where can I find a good example of a render function for selmer templates ?

solicode11:12:45

Selmer seems to have its own render function. So I’m not sure if you would need to define your own like this in layout. Can’t you use Selmer’s render directly?

roelof11:12:51

I think I can . So I have to change layout/render to render ??

roelof11:12:12

I do not use cljs or reagent so I think it can work

roelof11:12:28

Im a beginner in this

solicode11:12:15

There's an example here: https://github.com/yogthos/Selmer#templates So Selmer has a render-file function which seems to be the one you want.

solicode11:12:34

So you can require selmer and use that function directly.

roelof11:12:03

oke, I will experiment with it but still adding (ns clcommerce.layout (:require [selmer.parser :as parser] does not solve it. Still render-file cannot be resolved

solicode11:12:25

Are you calling it with parser/render-file?

roelof11:12:39

nope, only render-file

roelof11:12:43

oke parser/render-file does it

solicode11:12:28

Right, that’s what :as parser is doing. You can call it whatever you want.

roelof11:12:30

now trying to find out why (parser/render-file "home/base.html")) gives a wrong arity

solicode11:12:08

In the example, it shows you can pass variables to the template. So it looks like it’s not overloaded. You can pass an empty map to it.

solicode11:12:38

(parser/render-file "home/base.html" {})

solicode11:12:10

Eventually, I’m assuming you’ll put stuff in that map, like: (parser/render-file "home/base.html" {:name "Whatever”})

solicode11:12:45

Then in your template, I think you can do {{name}} and use it.

solicode11:12:16

I’m not too familiar with Selmer, but it seems like that’s how you use it.

roelof11:12:38

I found that out already

roelof11:12:40

yes, my first template is running

roelof11:12:58

it costs me the whole morning but it works simple_smile

roelof11:12:55

now next problem : find out how I can tell the css files are in the resources directory

roelof11:12:49

also solved

roelof11:12:13

now I can work on the rest of the template

roelof11:12:30

@solicode: thanks for the help

borkdude12:12:26

Does the end of Prismatic also mean a big change in Prismatic/Schema being maintained?

roelof12:12:05

@borkdude: maybe a stupid question but what does Prismatic/Schema exactly do ?

borkdude12:12:38

@roelof: check it out here. basically structural validation: https://github.com/Prismatic/schema

roelof12:12:54

oke, can I also use it for input validation ?

roelof13:12:59

oke, maybe a good one to keep a eye on for form validation for my hobby-project

roelof13:12:18

What is the right way to make a java script tag working with Selmer

sveri15:12:44

@martintrojer: Hi, since joplin 0.3 do I understand it correct that I have to define some code to execute migrations? Up to 0.3 I could just define some configuration and then run the migration with the leiningen plugin without one line of clojure code. Is that still possible?

jaen15:12:56

The very least you have to do is to define aliases I think - https://github.com/juxt/joplin/blob/master/example/project.clj#L14-L19

martintrojer15:12:23

@sveri if you want to run migration / seeds from the command-line you need to implement the aliases

martintrojer15:12:48

I tend to only use the ‘joplin repl’ nowadays

sveri15:12:05

@martintrojer: I already commented in one of the issues, pre 0.3 it was possible to run a migration without a line of clj code only by configuration.Now I have to write some helper code. Is there a reason to do it like this?

martintrojer15:12:57

yeah, lein plugins are no good. But like you said in GH#71 some of the boiler plate could be moved into core

sveri15:12:41

I am curious, why you think that lein plugins are no good? Because they are coupling leiningen to your project?

martintrojer16:12:43

Since joplin potentially brings loads of dependencies, I had various hacks in the plugin only to require the databases you were using.

martintrojer16:12:51

Also, I really wanted to move the config out of project.clj

sveri16:12:21

I looked a few minutes into the code and my first understanding of joplin.repl/migrate was that the conf param takes a filename where the configuration resides in the classpath. Later I realized it expects the config map. Would it be ok to accept both? the config map or a filename where the config is inside?

sveri16:12:51

Then I won't need to write some code cause I could just provide the configuration

sveri16:12:46

*The configuration file I mean

martintrojer16:12:01

joplin.repl/load-config

martintrojer16:12:23

its the edn reader with support for the tagged literals

martintrojer16:12:49

The problem with taking the filename is that I want you to control where its coming from, resources / file-path etc

sveri16:12:30

Hm and the problem with this approach is, I have to write clojure code to do migration

martintrojer16:12:48

Yeah, but if we write a helper that take the filename, next week there will be a GH issue that somebody wants to load it from resources rather than filesystem path.

sveri16:12:46

And what if we make it like this that the migrate functions calls load-config if conf is a filename or just executes the existing code if it is a map?

sveri16:12:00

This way we would use the existing load-config function

martintrojer16:12:05

so repl/load-config doesn’t take a filename either.

sveri16:12:34

Ok, then I misunderstood the code

sveri16:12:20

I dont understad that part: https://github.com/juxt/joplin/blob/master/example/src/alias.clj#L9 Why do you add some extra config into the existing one? Is this just an example? Or required everytime?

martintrojer16:12:39

Yeah, only for this particular example

sveri16:12:16

Ok, would you consider a PR where I just grab that example alias.clj and change the functions to parameterize "joplin.edn"?

sveri16:12:49

and place that alias.clj besides repl.clj?

martintrojer16:12:20

I’m here to please simple_smile

sveri16:12:21

😄 thanks for the work btw.

sveri16:12:03

Let's see if I get ready before my family calls. They are still working on the christmas cookies^^

Pablo Fernandez16:12:13

figwheel provides a webserver when you don’t have one, but now I need one, because I want to serve many URLs. What’s the best way to add one that plays nicely with figwheel? Is it possible to not have to run both figwheel and the web server at the same time?

sveri16:12:08

@martintrojer: Hm, I wanted to test the alias namespace and ran this snippet in a repl where I installed joplin.core and joplin.jdbc 0.3.5-Snapshot

sveri16:12:45

Any idea whats going on here? the "here!!!" part is just a test println from me

naomarik16:12:47

oo joplin looks like something i'll want to use soon

sveri17:12:01

@martintrojer: I have the same problem when I try to add the alias.clj to my project using joplin 0.3.4

sveri17:12:20

Hm, could it be that my config is broken?

sveri17:12:05

@martintrojer: Ok, it's a ragtime problem only occurring in windows due to the fileseparator

roelof17:12:29

any Selmer users here. How do I use the javascript tag and the image tag in Selmer

roelof17:12:48

and the meta tag

sveri17:12:53

@martintrojer: I opened this issue: https://github.com/weavejester/ragtime/issues/91 for it. Will have to wait until this is fix so I can try out my PR

roelof18:12:02

@sveri: do you use meta, javascript and /or images in your closp template ?

sveri19:12:40

@roelof: I do sparingly, I think, but never took much care of them, as they are project specific in my opinion

roelof19:12:26

oke, I try to convert a template where a lot of javascript , meta and javascript is used

roelof19:12:11

I try to convert this ; https://laboutique.lemonstand.com/ with selmer

roelof19:12:28

but on these tags I cannot find how I can do that in a template

roelof19:12:05

but im going to sleep early so I will read your answer tomorrow if you give a answer

rcanepa20:12:37

Hey!… I am having a hard time trying to understand how to apply coercion on one of my REST API end point. What I want is to coerce some query parameters based on a schema definition. For example, if I receive a request with some query parameters like “…/foo?status=0&name=“rcanepa”, I would like to transform the status value to an integer and pass to my handler a map like {“status” 0 “name” “rcanepa”}.

rcanepa20:12:50

I forgot to say that I am working with compojure-api.

rcanepa20:12:11

I think that I have to pass my schema in the :query-params keyword of the endpoint.

rcanepa20:12:32

However, I am not sure how can I pass this “coerced” map to the handler.

rcanepa20:12:31

The objective behind all of this, is to provide filtering, pagination and sorting features, so the query params may vary.

rcanepa20:12:21

Now, I am doing this:

rcanepa20:12:24

In that snippet, parse-contact-search-request is a def that calls coercer/coercer.

rcanepa20:12:50

If test it, I will get an error for trying to pass a string as the value of the status keyword.

rcanepa20:12:45

In summary, 1) coercion is not working, and 2) I don’t know how to correctly specify the schema for the :query-params on the endpoint.

ikitommi20:12:17

@rcanepa: try either: :query-params [status :- s/Int name s/Str], binds status and name for the body.

ikitommi20:12:10

@rcanepa: or if you want the whole map: :query [params {:status s/Int, :name s/Str}]; binds params for the body.

ikitommi20:12:34

:query-params uses the Plumbing letk-syntax, :query works like a normal let.

rcanepa20:12:58

Mmm… If I understood correctly, I could use something like

:query [params MySchema]

rcanepa20:12:19

Yes, I can simple_smile

sveri21:12:13

@roelof: I am not sure what exactly your question is?

misha23:12:24

greetings! is there a way to extend defrecord's auto-generated fn's arity? ~ like this:

(defrecord User [email name])

(defn ->User [email]
  (->User email nil))