Fork me on GitHub
#hoplon
<
2016-01-19
>
thedavidmeister13:01:17

@micha: this is the response from the auth0 support in their slack channel:

thedavidmeister13:01:59

i was just trying to get the auth0-lock cljsjs extern working with Hoplon

thedavidmeister13:01:20

but I ended up needing to manually add the script from their CDN into the page using Hoplon

micha13:01:52

doesn't auth0 have a function you can call to start it up?

thedavidmeister13:01:07

this happens before that

micha13:01:15

like have it wait for you to initialize it, rather than just stomping around in the dom?

thedavidmeister13:01:27

no, it does not wait

thedavidmeister13:01:29

not for this bit

micha13:01:41

seems like that would be something they could support

thedavidmeister13:01:05

so, it does have an "init" style thing that you do, by passing in the client ID for the app you're working on

micha13:01:12

because i'm sure there are a lot of ways just inserting random stuff into the dom whenever you want can interfere with things

thedavidmeister13:01:29

but it also messes with the DOM before you init it, like as soon as the script is pulled into the page

micha13:01:58

yeah that seems like an issue with their design that could be fixed

thedavidmeister13:01:25

i agree that it's not how I'd make a library, or a pattern that I've seen elsewhere for that matter

thedavidmeister13:01:45

but who knows if there's some reason why they did it this way

micha13:01:23

another option is you can see what the style tag is

micha13:01:26

and add it yourself

thedavidmeister13:01:42

they also suggested that I add the CSS straight from the CDN, as an option

micha13:01:53

yeah also that

micha13:01:16

although probably downloading it from the cdn and just pasting it in the page would be good

micha13:01:36

you can wrap that in your cljs wrapper for the library anyway

thedavidmeister13:01:09

which is fine, but... I don't trust everyone in the chain of development to keep the CSS version from the CDN and the CSS written by the script to the page 100% identical

thedavidmeister13:01:50

it would be so easy to grab version 8.x.y of the CSS and 8.x.z of the script, with a bung git branch

thedavidmeister13:01:59

and not notice until some weird bug crops up later

micha13:01:02

does it add an id or something to the style tag?

micha13:01:08

so you can identify it?

thedavidmeister13:01:31

ummm, i can check pretty easily

thedavidmeister13:01:01

not developer friendly at all

thedavidmeister13:01:21

just vomits minified inline css into the page

micha13:01:27

you can get that, put it in a css file

micha13:01:35

then do like

micha13:01:48

i guess then make a link tag in the page to load it

micha13:01:07

with prerendering there shouldn't be any flashing of unstyled content or anything

thedavidmeister13:01:18

yeah i could, but the day that someone changes the script by a minor version and forgets to update that CSS file

thedavidmeister13:01:39

i'm opening myself up to issues

micha13:01:39

is there a function in their code that generates the css?

micha13:01:44

at least?

micha13:01:04

or is it all just at the top level with no functions or anything

micha13:01:11

php yolo style

thedavidmeister13:01:44

(function (global){
/**
 * Insert css when first loaded
 */

require('./lib/insert-css');

micha13:01:20

dang, so you can't even call a function to do it later

micha13:01:25

checkmated

micha13:01:30

well played

thedavidmeister13:01:26

yeah it's not like "put the script in your page, then tell it when to init, then use it"

micha13:01:26

haha that is classic php yolo style btw

micha13:01:49

include("foo.php")

thedavidmeister13:01:04

it's like "the script will become your page, then you can ask it for permission to use it, then maybe you can use it"

micha13:01:14

so this is going to be a production app?

micha13:01:26

like you're going to be maintaining it and whatnot?

micha13:01:32

or is this a one off

thedavidmeister13:01:04

yeah, i'll be maintaining it

micha13:01:27

so you can actually use hoplon as a library in this case

micha13:01:34

and make your own index.html page

micha13:01:46

with a div in it in which you "mount" the hoplon stuff

thedavidmeister13:01:55

but i'm cool to refactor things, as long as the refactor isn't wading through a bunch of "being setup to fail" type situations simple_smile

micha13:01:19

no this is straightforward

micha13:01:28

just copy the index.html that hoplon generates

thedavidmeister13:01:31

oh, i didn't know you could do that with Hoplon

micha13:01:41

no, it's always been that way pretty much

thedavidmeister13:01:52

because I saw a thread in the forums about it, but whenever that thread was around it was apparently hard or not fully supported

micha13:01:11

well for the past year at least it's been easy

micha13:01:16

we refactored things a while ago

micha13:01:20

but anyway

micha13:01:28

you can save the index.html page

thedavidmeister13:01:38

i don't think i have to go that far though

micha13:01:50

and instead of making the (page "index.html" ...) you make a regular ns declaration

micha13:01:58

i should make a demo of this

thedavidmeister13:01:16

pragmatically, it appears that auth0 just messes with the head and adds an overlay in the body of the page

micha13:01:21

but basically in hoplon the (div ...) is just a function

micha13:01:55

so you can certainly do (.append (js/jQuery "#mountpoint") (my.page/render))

micha13:01:02

where you have

thedavidmeister13:01:11

that might change in the future, because it could do basically anything to the page, in theory

micha13:01:15

(defn render []
  (div "hello world"))

thedavidmeister13:01:30

but for now i think it's just CSS and an overlay

micha13:01:53

yeah i mean if this application will be around for a while it's worth the investment to refactor

micha13:01:09

and if the auth0 problems are really hard to solve that might be the cleanest fix

thedavidmeister13:01:25

but really, i already have a defelem for "outermost html"

micha13:01:36

yeah so you can call that, no problem

thedavidmeister13:01:39

refactoring that to be like what you describe would be easy

micha13:01:59

the only thing is if you call the head or body functions

thedavidmeister13:01:08

just knowing that I have that option is great

micha13:01:09

those will wipe out anything already in the head or body

micha13:01:22

naturally

thedavidmeister13:01:36

yeah, but i like building head and body in hoplon

micha13:01:50

yeah, being able to program is key

micha13:01:59

messing with html is not fun

thedavidmeister13:01:16

although (html-meta caught me out

thedavidmeister13:01:25

i was expecting it to just be (meta

micha13:01:51

i thought it would be a little too far though, to unmap the cljs.core/meta

micha13:01:05

there is also a html-map

micha13:01:17

because cljs.core/map definitely shouldn't be messed with

micha13:01:27

but there is a <map> element

thedavidmeister13:01:40

yeah, well it makes sense once you know

micha13:01:45

there are like 3 of them, i forget what the 3rd one is

thedavidmeister13:01:06

but when you're in the headspace of "trying to make an html element" you're not necessarily thinking "what core thingos am I conflicting with right now"

thedavidmeister13:01:14

although, it's obvious really

micha13:01:41

meta could have gone either way, especially since it's more common to use it in html than it is to use it in cljs

micha13:01:58

so having to do cljs.core/meta might be okay

thedavidmeister14:01:06

nah, consistency is better

thedavidmeister14:01:35

the way it is now is right

micha14:01:37

head actually used to be a macro that sniffed for calls to meta

micha14:01:45

and rewrote them

micha14:01:49

but that was too far

thedavidmeister14:01:57

i like what it's doing

thedavidmeister14:01:04

i think it's a human problem

thedavidmeister14:01:06

not a code problem

micha14:01:42

i think we could put in the demos like

micha14:01:51

(def meta html-meta)

micha14:01:04

i actually do that usually

micha14:01:15

because i don't like to see html-meta in there, lol

micha14:01:22

it annoys me aesthetically

thedavidmeister14:01:36

what about meta-tag

micha14:01:58

haha i like that

micha14:01:03

or <meta>

micha14:01:20

(<meta> ...)

thedavidmeister14:01:51

honestly, the... obviousness... of cljs and hoplon is what is attracting me and encouraging me to keep going

thedavidmeister14:01:23

i was annoyed that I had to work through a broken link, then a wiki that mentioned nothing about it, then finally read through the autogenerated API docs

thedavidmeister14:01:27

to find html-meta

thedavidmeister14:01:41

but once i knew about it, i liked that it was "no magic"

micha14:01:51

which broken link?

micha14:01:10

the generated api docs were not really good

micha14:01:18

the things have problems with clj and cljs

thedavidmeister14:01:20

i go through the same process every time

thedavidmeister14:01:23

i never learn 😛

micha14:01:49

i made my own doc generator thing though

micha14:01:04

so hopefully i can update the hoplon docs soon

thedavidmeister14:01:46

i should just bookmark it or something

micha14:01:12

the core.cljs file on github is probably the best place to look

micha14:01:58

hopefully have api docs soon though

thedavidmeister14:01:46

where's the hoplon dev at atm?

thedavidmeister14:01:05

like, what's the focus?

micha14:01:59

i think the current state of hoplon is pretty good

micha14:01:22

documentation and stuff is where we need to work on improving things i think

micha14:01:23

although i have been working for a while on fixing one of the problems with the hoplon model, but it's kind of a hard problem to solve

micha14:01:30

so it's taking a while to figure out

micha14:01:53

the problem i want to solve is essentially this:

micha14:01:06

(defelem mylist
  [{:keys [title] :as attr} kids]
  (div
    (h3 :text title)
    (ul
      (map li kids))))

micha14:01:23

now you can do like

micha14:01:49

(mylist :title "a list!" (p "hi") (div (p "yo") (p "lo")))

micha14:01:16

that works fine

micha14:01:28

but if you do this, you don't get what you expect:

micha14:01:08

(def list1 (mylist :title "a list!" (p "hi")))

(list1 (div (p "yo") (p "lo")))

micha14:01:46

because the div you append to list1 doesn't get wrapped in a li and appended to the internal ul in there

micha14:01:12

defelem elements should be the same as primitive html elements

micha14:01:24

like with a regular ul you can do this

micha14:01:58

(def list1 (ul (li "hi")))

(list1 (li "there"))

micha14:01:01

no problem

thedavidmeister14:01:07

why doesn't it work?

micha14:01:19

because defelem just creates a function

micha14:01:33

so when you call the function, kids there is an argument to the function

micha14:01:52

so the things you pass directly as arguments of the mylist function are handled correctly

micha14:01:00

but that function returns a dom element

micha14:01:11

which is also something that can be applied to arguments like a function

micha14:01:31

but when you do that, like in the example (list1 (div ...))

micha14:01:51

that's just appending (div ...) to the element that mylist returned

micha14:01:57

which is a div

micha14:01:09

so the things get appended to the outermost div of the mylist

micha14:01:25

instead of being wrapped in li's and appended to the internal ul

thedavidmeister14:01:39

yeah, i think it's too late for me to be thinking about this

thedavidmeister14:01:44

it's like 2am here

dm315:01:05

it seems you can't really solve this without carrying the original defelem function around

micha15:01:21

the way i want to solve it is at the root

micha15:01:36

by patching .appendChild() and so on

dm315:01:32

so that it would branch inside depending on something?

micha15:01:14

yeah instead of actually appending the element, it would append the element to a ajvelin cell

micha15:01:32

and the defelem would handle it transparently

actsasgeek23:01:06

back to a question I asked a few days ago. If I have (script :type “text/javascript” :src “js/d3.min.js”) in my (head … ). How do I refer to d3 in ClojureScript? I’ve tried to use (-> js/d3 …) and that works sometimes but not other times. It seems that if I simply save my changes, it works but when I’m all done, if I reload the page, it fails. It complains that it can’t find d3.

micha23:01:12

that should work, provided that the js file defines a top level thing in the global object named d3

micha23:01:00

do you have a test case?

micha23:01:36

ah i think i know

micha23:01:56

one of your cljs namespaces could be using it before the script has been inserted into the head

micha23:01:41

@actsasgeek: first question: are you sure you need to include d3 as a script tag in the head?

micha23:01:59

the usual way to use js libraries is by including them as :foreign-deps

micha23:01:56

all packaged up and ready to go

actsasgeek23:01:01

yes but that doesn’t teach me anything simple_smile

micha23:01:17

you can look at the build.boot to see how it's packaged

micha23:01:41

that's the correct way to use js libraries

micha23:01:56

you can package them as jars that will participate in the dependency graph

micha23:01:11

so you can have libraries that come with their own dependencies etc

micha23:01:05

the readme for the cljsjs package explains a bit

micha23:01:29

the foreign libs stuff is the mechanism

actsasgeek23:01:44

so [cljsjs/d3 "3.5.7-1"] would go in build.boot :dependencies?

micha23:01:31

there is a bunch of documentation here: https://github.com/cljsjs/packages

micha23:01:55

example of how to use a cljsjs dependency in your cljs namespace:

micha23:01:09

(ns my.name.space
  (:require [cljsjs.showdown])      ; note, no :as or :refer here

(defn convert-to-html [markdown]
  ;; note the syntax below: js/VarFromExternsFile.property
  ;; the dot on the end is the usual Clojure interop syntax:
  ;; (Constructor. constructor-arg constructor-arg)
  (let [converter (js/Showdown.converter.)]    
    ;; methods you call will generally need to be called out as prototype
    ;; values in the externs
    (.makeHtml converter markdown)))

actsasgeek23:01:11

yeah, that makes sense. When I asked the other day, Alan said if he were doing the Dashboard example over again (without hoplon’s old style automatic importing), he’d just use a (script …) tag so that’s why I started there. The problem, of course, is that when you’re new to everything (ClojureScript, Hoplon, etc.) when there’s a problem, you simply don’t know where the problem is coming from.

micha23:01:52

yeah there are a few things happening simple_smile

micha23:01:17

if you use a script tag though then you have to work around the order in which things are loaded

micha23:01:41

if you use the package then the clojurescript compiler works out the dependency graph for you and makes sure code is loaded in the right order