Skip to content

Commit

Permalink
add clojure-luminus example
Browse files Browse the repository at this point in the history
  • Loading branch information
FarazPatankar committed Nov 13, 2024
1 parent 112264a commit a4ee902
Show file tree
Hide file tree
Showing 28 changed files with 805 additions and 0 deletions.
21 changes: 21 additions & 0 deletions examples/clojure-luminus/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/target
/lib
/classes
/checkouts
pom.xml
dev-config.edn
test-config.edn
*.jar
*.class
/.lein-*
profiles.clj
/.env
.nrepl-port
/.clj-kondo/.cache/
/.lsp/.cache/
/.calva/output-window/

/node_modules
/log


28 changes: 28 additions & 0 deletions examples/clojure-luminus/Capstanfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

#
# Name of the base image. Capstan will download this automatically from
# Cloudius S3 repository.
#
#base: cloudius/osv
base: cloudius/osv-openjdk8

#
# The command line passed to OSv to start up the application.
#
cmdline: /java.so -jar /clojure-luminus/app.jar

#
# The command to use to build the application.
# You can use any build tool/command (make/rake/lein/boot) - this runs locally on your machine
#
# For Leiningen, you can use:
#build: lein uberjar
# For Boot, you can use:
#build: boot build

#
# List of files that are included in the generated image.
#
files:
/clojure-luminus/app.jar: ./target/uberjar/clojure-luminus.jar

21 changes: 21 additions & 0 deletions examples/clojure-luminus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# clojure-luminus

generated using Luminus version "4.50"

FIXME

## Prerequisites

You will need [Leiningen][1] 2.0 or above installed.

[1]: https://github.com/technomancy/leiningen

## Running

To start a web server for the application, run:

lein run

## License

Copyright © 2024 FIXME
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(ns clojure-luminus.dev-middleware
(:require
[clojure-luminus.config :refer [env]]
[ring.middleware.reload :refer [wrap-reload]]
[selmer.middleware :refer [wrap-error-page]]
[prone.middleware :refer [wrap-exceptions]]))

(defn wrap-dev [handler]
(-> handler
wrap-reload
wrap-error-page
;; disable prone middleware, it can not handle async
(cond-> (not (env :async?)) (wrap-exceptions {:app-namespaces ['clojure-luminus]}))))
15 changes: 15 additions & 0 deletions examples/clojure-luminus/env/dev/clj/clojure_luminus/env.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(ns clojure-luminus.env
(:require
[selmer.parser :as parser]
[clojure.tools.logging :as log]
[clojure-luminus.dev-middleware :refer [wrap-dev]]))

(def defaults
{:init
(fn []
(parser/cache-off!)
(log/info "\n-=[clojure-luminus started successfully using the development profile]=-"))
:stop
(fn []
(log/info "\n-=[clojure-luminus has shut down successfully]=-"))
:middleware wrap-dev})
32 changes: 32 additions & 0 deletions examples/clojure-luminus/env/dev/clj/user.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
(ns user
"Userspace functions you can run by default in your local REPL."
(:require
[clojure-luminus.config :refer [env]]
[clojure.pprint]
[clojure.spec.alpha :as s]
[expound.alpha :as expound]
[mount.core :as mount]
[clojure-luminus.core :refer [start-app]]))

(alter-var-root #'s/*explain-out* (constantly expound/printer))

(add-tap (bound-fn* clojure.pprint/pprint))

(defn start
"Starts application.
You'll usually want to run this on startup."
[]
(mount/start-without #'clojure-luminus.core/repl-server))

(defn stop
"Stops application."
[]
(mount/stop-except #'clojure-luminus.core/repl-server))

(defn restart
"Restarts application."
[]
(stop)
(start))


1 change: 1 addition & 0 deletions examples/clojure-luminus/env/dev/resources/config.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
36 changes: 36 additions & 0 deletions examples/clojure-luminus/env/dev/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<charset>UTF-8</charset>
<pattern>%date{ISO8601} [%thread] %-5level %logger{36} - %msg %n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>log/clojure-luminus.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/clojure-luminus.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- keep 30 days of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%date{ISO8601} [%thread] %-5level %logger{36} - %msg %n</pattern>
</encoder>
</appender>
<logger name="org.apache.http" level="warn" />
<logger name="org.xnio.nio" level="warn" />
<logger name="io.undertow.websockets.core.request" level="warn" />
<logger name="io.undertow.request" level="warn" />
<logger name="io.undertow.session" level="warn" />
<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
11 changes: 11 additions & 0 deletions examples/clojure-luminus/env/prod/clj/clojure_luminus/env.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(ns clojure-luminus.env
(:require [clojure.tools.logging :as log]))

(def defaults
{:init
(fn []
(log/info "\n-=[clojure-luminus started successfully]=-"))
:stop
(fn []
(log/info "\n-=[clojure-luminus has shut down successfully]=-"))
:middleware identity})
2 changes: 2 additions & 0 deletions examples/clojure-luminus/env/prod/resources/config.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{:prod true
:port 3000}
34 changes: 34 additions & 0 deletions examples/clojure-luminus/env/prod/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>log/clojure-luminus.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/clojure-luminus.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- keep 30 days of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%date{ISO8601} [%thread] %-5level %logger{36} - %msg %n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-5relative %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.apache.http" level="warn" />
<logger name="org.xnio.nio" level="warn" />
<logger name="io.undertow.websockets.core.request" level="warn" />
<logger name="io.undertow.request" level="warn" />
<logger name="io.undertow.session" level="warn" />
<logger name="io.undertow.request" level="warn" />
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
70 changes: 70 additions & 0 deletions examples/clojure-luminus/project.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
(defproject clojure-luminus "0.1.0-SNAPSHOT"

:description "FIXME: write description"
:url "http://example.com/FIXME"

:dependencies [[clojure.java-time "1.1.0"]
[cprop "0.1.19"]
[expound "0.9.0"]
[funcool/struct "1.4.0"]
[json-html "0.4.7"]
[luminus-immutant "0.2.5"]
[luminus-transit "0.1.5"]
[markdown-clj "1.11.3"]
[metosin/muuntaja "0.6.8"]
[metosin/reitit "0.5.18"]
[metosin/ring-http-response "0.9.3"]
[mount "0.1.16"]
[nrepl "1.0.0"]
[org.clojure/clojure "1.11.1"]
[org.clojure/tools.cli "1.0.214"]
[org.clojure/tools.logging "1.2.4"]
[org.webjars.npm/bulma "0.9.4"]
[org.webjars.npm/material-icons "1.10.8"]
[org.webjars/webjars-locator "0.45"]
[org.webjars/webjars-locator-jboss-vfs "0.1.0"]
[ring-webjars "0.2.0"]
[ring/ring-core "1.9.6"]
[ring/ring-defaults "0.3.4"]
[selmer "1.12.55"]]

:min-lein-version "2.0.0"

:source-paths ["src/clj"]
:test-paths ["test/clj"]
:resource-paths ["resources"]
:target-path "target/%s/"
:main ^:skip-aot clojure-luminus.core

:plugins [[lein-immutant "2.1.0"]]

:profiles
{:uberjar {:omit-source true
:aot :all
:uberjar-name "clojure-luminus.jar"
:source-paths ["env/prod/clj" ]
:resource-paths ["env/prod/resources"]}

:dev [:project/dev :profiles/dev]
:test [:project/dev :project/test :profiles/test]

:project/dev {:jvm-opts ["-Dconf=dev-config.edn" ]
:dependencies [[org.clojure/tools.namespace "1.3.0"]
[pjstadig/humane-test-output "0.11.0"]
[prone "2021-04-23"]
[ring/ring-devel "1.9.6"]
[ring/ring-mock "0.4.0"]]
:plugins [[com.jakemccrary/lein-test-refresh "0.24.1"]
[jonase/eastwood "1.2.4"]
[cider/cider-nrepl "0.26.0"]]

:source-paths ["env/dev/clj" ]
:resource-paths ["env/dev/resources"]
:repl-options {:init-ns user
:timeout 120000}
:injections [(require 'pjstadig.humane-test-output)
(pjstadig.humane-test-output/activate!)]}
:project/test {:jvm-opts ["-Dconf=test-config.edn" ]
:resource-paths ["env/test/resources"] }
:profiles/dev {}
:profiles/test {}})
96 changes: 96 additions & 0 deletions examples/clojure-luminus/resources/docs/docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<h1 class="title">Congratulations, your <a class="alert-link" href="http://luminusweb.net">Luminus</a> site is ready!</h1>

This page will help guide you through the first steps of building your site.

<p class="title is-5">Why are you seeing this page?</p>

The `home-routes` handler in the `clojure-luminus.routes.home` namespace
defines the route that invokes the `home-page` function whenever an HTTP
request is made to the `/` URI using the `GET` method.

```
(defn home-routes []
[""
{:middleware [middleware/wrap-csrf
middleware/wrap-formats]}
["/" {:get home-page}]
["/about" {:get about-page}]])
```

The `home-page` function will in turn call the `clojure-luminus.layout/render` function
to render the HTML content:

```
(defn home-page [request]
(layout/render
request
"home.html" {:docs (-> "docs/docs.md" io/resource slurp)}))
```

The `render` function will render the `home.html` template found in the `resources/html`
folder using a parameter map containing the `:docs` key. This key points to the
contents of the `resources/docs/docs.md` file containing these instructions.

The HTML templates are written using [Selmer](https://github.com/yogthos/Selmer) templating engine.

```
<div class="content">
{{docs|markdown}}
</div>
```

<a class="level-item button" href="https://luminusweb.com/docs/html_templating.html">learn more about HTML templating »</a>



<p class="title is-5">Organizing the routes</p>

The routes are aggregated and wrapped with middleware in the `clojure-luminus.handler` namespace:

```
(mount/defstate app-routes
:start
(ring/ring-handler
(ring/router
[(home-routes)])
(ring/routes
(ring/create-resource-handler
{:path "/"})
(wrap-content-type
(wrap-webjars (constantly nil)))
(ring/create-default-handler
{:not-found
(constantly (error-page {:status 404, :title "404 - Page not found"}))
:method-not-allowed
(constantly (error-page {:status 405, :title "405 - Not allowed"}))
:not-acceptable
(constantly (error-page {:status 406, :title "406 - Not acceptable"}))}))))
```

The `app` definition groups all the routes in the application into a single handler.
A default route group is added to handle the `404` case.

<a class="level-item button" href="https://luminusweb.com/docs/routes.html">learn more about routing »</a>

The `home-routes` are wrapped with two middleware functions. The first enables CSRF protection.
The second takes care of serializing and deserializing various encoding formats, such as JSON.

<p class="title is-5">Managing your middleware</p>

Request middleware functions are located under the `clojure-luminus.middleware` namespace.

This namespace is reserved for any custom middleware for the application. Some default middleware is
already defined here. The middleware is assembled in the `wrap-base` function.

Middleware used for development is placed in the `clojure-luminus.dev-middleware` namespace found in
the `env/dev/clj/` source path.

<a class="level-item button" href="https://luminusweb.com/docs/middleware.html">learn more about middleware »</a>




<p class="title is-5">Need some help?</p>

Visit the [official documentation](https://luminusweb.com/docs/guestbook) for examples
on how to accomplish common tasks with Luminus. The `#luminus` channel on the [Clojurians Slack](http://clojurians.net/) and [Google Group](https://groups.google.com/forum/#!forum/luminusweb) are both great places to seek help and discuss projects with other users.
4 changes: 4 additions & 0 deletions examples/clojure-luminus/resources/html/about.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{% extends "base.html" %}
{% block content %}
<img src="/img/warning_clojure.png"></img>
{% endblock %}
Loading

0 comments on commit a4ee902

Please sign in to comment.