sugar-framework / sugar

Modular web framework for Elixir
https://sugar-framework.github.io/
MIT License
430 stars 29 forks source link

Including JavaScript and CSS #83

Closed ghost closed 8 years ago

ghost commented 8 years ago

I couldn't find any information about where to put your CSS/JS. is it in /priv/static/ ? /priv/main/ ? Somewhere else?

slogsdon commented 8 years ago

I think Plug.Static is what you want. :) It defaults to priv/static, but you can change that if you like.

ghost commented 8 years ago

Thanks :) That's a bit weird, because I keep having 404s on the files… My files are

.
├── css
│   ├── bootstrap.css
│   ├── bootstrap.css.map
│   ├── bootstrap.min.css
│   ├── bootstrap.min.css.map
│   ├── bootstrap-theme.css
│   ├── bootstrap-theme.css.map
│   ├── bootstrap-theme.min.css
│   ├── bootstrap-theme.min.css.map
│   └── cover.css
├── fonts
│   ├── glyphicons-halflings-regular.eot
│   ├── glyphicons-halflings-regular.svg
│   ├── glyphicons-halflings-regular.ttf
│   ├── glyphicons-halflings-regular.woff
│   └── glyphicons-halflings-regular.woff2
├── index.html
└── js
    ├── bootstrap.js
    ├── bootstrap.min.js
    └── npm.js

And here's the content of index.html's <head>

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="css/cover.css" rel="stylesheet">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDme
zHubeNikyKGVyQ==" crossorigin="anonymous">
  <title>Exon mess manager</title>
</head>

The HTML renders well, no problems on this side. But it's just bleak HTML. :/

My router has the default setting, that is to say plug Plug.Static, at: "/priv/static", from: :exon

YellowApple commented 8 years ago

I don't think that at: is right. It should be the route used to access the resource, not where it's being stored. So (assuming :exon is the name of your app) you should try plug Plug.Static, at: "/", from: :exon (which seems to work on my end (aside from some unrelated bug with Plug.HotCodeReload using non-lowercase response headers and Plug being a jerk about it) without any further configuration, using an EEx template that links in css/yellowapple.css).

ghost commented 8 years ago

okay, thanks :)

CharlesOkwuagwu commented 8 years ago

Please it would be helpful if you can share a full working example properly setup to use common stuff like bootstrap and jQuery, possibly with a few pages and navigation too.

Thanks.

YellowApple commented 8 years ago

AFAIK, JS/CSS should work exactly the same way as it would in plain HTML, the difference being that your JS/CSS files are stored in your app's priv/static (and accessible through the /static route if you use the recommended Plug.Static configuration). This would include Bootstrap and jQuery.

I'll see about whipping up a more complete example (or perhaps just reupdating the "simple" example). It's possible that the workflow there could be made easier.

CharlesOkwuagwu commented 8 years ago

@YellowApple Thanks. I was able to get static js/css/images working...

I'm battling with file uploads now :( see some of my failed attempts

It would really be helpful to see a guide/example with alot more everyday use-cases for Sugar-Framework

Thanks.

YellowApple commented 8 years ago

Agreed, and thanks for the feedback. The docs for Plug.Upload might be of interest to you there until one of us gets around to writing more complete documentation on some of these more "real-world" topics.

YellowApple commented 8 years ago

On another note, it looks like your file upload route (where the upload form is pointing) is a GET in your router (when it should be a POST). That might also be an issue.

CharlesOkwuagwu commented 8 years ago

I had tried both, I get the same error, that Plug is not started for the upload... I guess the request does not get as far as the get/post for the :file_upload function

YellowApple commented 8 years ago

I'll take a closer look when I get back to a proper workstation, but can you submit that as a new bug? I think I know what the issue is.

CharlesOkwuagwu commented 8 years ago

I made this change to my template file

From:

  <form enctype="multipart/form-data" action='/file/upload' method='post'>
    <input type='file' name='image'>
    <input type='submit'>
  </form>

To:

  <form  action='/file/upload' method='post'>
    <input type='file' name='image'>
    <input type='submit'>
  </form>  

I got rid of enctype="multipart/form-data", and i'm now able to get this in my file_uploadfunction

    IO.puts "conn: #{inspect conn}"
    IO.puts "args: #{inspect args}"
conn: %Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{}, before_send: [], body_params: %{"image" => "pp.jpg"}, cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "localhost", method: "POST", owner: #PID<0.461.0>, params: %{"image" => "pp.jpg"}, path_info: ["file", "upload"], peer: {{127, 0, 0, 1}, 4848}, port: 4000, private: %{action: :file_upload, controller: Simple.Controllers.Main, handler: Simple.Controllers.Main, plug_route: #Function<0.127663505/1 in Simple.Router.do_match/2>, plug_session_fetch: #Function<0.26782855/1 in Plug.Session.fetch_session/1>}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %Plug.Conn.Unfetched{aspect: :cookies}, req_headers: [{"host", "localhost:4000"}, {"connection", "keep-alive"}, {"content-length", "12"}, {"cache-control", "max-age=0"}, {"accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"}, {"origin", "http://localhost:4000"}, {"upgrade-insecure-requests", "1"}, {"user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2657.0 Safari/537.36"}, {"content-type", "application/x-www-form-urlencoded"}, {"dnt", "1"}, {"referer", "http://localhost:4000/"}, {"accept-encoding", "gzip, deflate"}, {"accept-language", "en-US,en;q=0.8,ms;q=0.6,ig;q=0.4"}, {"cookie", "ASP.NET_SessionId=dm0jgukswqmzdvwvlgf432bh"}], request_path: "/file/upload", resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"content-type", "application/x-www-form-urlencoded"}], scheme: :http, script_name: [], secret_key_base: nil, state: :unset, status: nil}

args: []

Not sure how to proceed from there.

YellowApple commented 8 years ago

The issue is still that the :plug application is not running (as stated in the original error). Try adding :sugar to your applications in your mix.exs, like so:

def applications do
  [ applications: [ :sugar ],
    mod: {Simple, []} ]
end

This will automatically spin up the relevant Plug processes (as well as some other included OTP apps, like Ecto and Postgrex).

Note to self: document this.

CharlesOkwuagwu commented 8 years ago

Ok, this works now, thanks.

But instead of writing this: "image[file_name] was saved" back to my browser, it puts the text in a file named uploadand downloads it.

YellowApple commented 8 years ago

Hm. Again, do you mind opening up a separate issue for this?

CharlesOkwuagwu commented 8 years ago

sure will do now