{ ;; Components declared here are the external reusable building blocks ;; of modules. :components [ {:component :modular.http-kit/webserver :library-dependencies [[juxt.modular/http-kit "0.5.4"]] :constructor modular.http-kit/new-webserver :options [:port] :using [:request-handler]} {:component :modular.bidi/router :library-dependencies [[juxt.modular/bidi "0.9.4"]] :constructor modular.bidi/new-router} {:component :modular.bidi/web-resources :library-dependencies [[juxt.modular/bidi "0.9.4"]] :constructor modular.bidi/new-web-resources} {:component :modular.bidi/redirect :library-dependencies [[juxt.modular/bidi "0.9.4"]] :constructor modular.bidi/new-redirect} {:component :modular.template/static-template-model :library-dependencies [[juxt.modular/template "0.6.3"]] :constructor modular.template/new-static-template-model} {:component :modular.template/aggregate-template-model :library-dependencies [[juxt.modular/template "0.6.3"]] :constructor modular.template/new-aggregate-template-model} {:component :modular.clostache/templater :library-dependencies [[juxt.modular/clostache "0.6.3"]] :constructor modular.clostache/new-clostache-templater} {:component :modular.less/compiler :library-dependencies [[juxt.modular/less "0.1.3"]] :constructor modular.less/new-less-compiler} {:component :modular.less/bootstrap-compiler :library-dependencies [[juxt.modular/less "0.1.3"]] :constructor modular.less/new-bootstrap-less-compiler} {:component :modular.cljs/module :library-dependencies [[juxt.modular/cljs "0.6.0"]] :constructor modular.cljs/new-cljs-module} {:component :modular.cljs/builder :library-dependencies [[juxt.modular/cljs "0.6.0"]] :constructor modular.cljs/new-cljs-builder} {:component :modular.async/channel :library-dependencies [[juxt.modular/async "0.5.3"]] :constructor modular.async/new-channel} {:component :modular.http-kit-events/event-service :library-dependencies [[juxt.modular/http-kit-events "0.6.0"]] :constructor modular.http-kit.events/new-event-service} {:component :modular.email/log-emailer :library-dependencies [[juxt.modular/email "0.0.1"]] :constructor modular.email.log-emailer/new-log-emailer} ;; Menus #_{:component :modular.menu/menu-index :library-dependencies [[juxt.modular/menu "0.5.3"]] :constructor modular.menu/new-menu-index} #_{:component :bootstrap-menu :library-dependencies [[juxt.modular/bootstrap "0.2.0"]] :constructor modular.bootstrap.menu/new-bootstrap-menu} ;; Security components {:component :cylon/email-user-store :library-dependencies [[cylon "0.6.0-SNAPSHOT"] ;; temp while in checkouts #_[cheshire "5.4.0"] ] :constructor cylon.user.email-user-store/new-email-user-store } {:component :cylon/buddy-user-authenticator :library-dependencies [[cylon "0.6.0-SNAPSHOT"] ;; temp while in checkouts #_[buddy "0.5.1"] ] :constructor cylon.user.buddy-user-authenticator/new-buddy-user-authenticator } {:component :cylon/file-storage :library-dependencies [[cylon "0.6.0-SNAPSHOT"]] :constructor cylon.storage.file-storage/new-file-storage} {:component :cylon/cookie-session-store :library-dependencies [[cylon "0.6.0-SNAPSHOT"] ;; temp while in checkouts #_[cheshire "5.4.0"] ] :constructor cylon.session.cookie-session-store/new-cookie-session-store} {:component :cylon/atom-backed-token-store :library-dependencies [[cylon "0.6.0-SNAPSHOT"] ;; temp while in checkouts #_[cheshire "5.4.0"] ] :constructor cylon.token-store.atom-backed-store/new-atom-backed-token-store} {:component :cylon/login :library-dependencies [[cylon "0.6.0-SNAPSHOT"] ;; temp while in checkouts #_[cheshire "5.4.0"]] :constructor cylon.user.login/new-login } {:component :cylon/signup :library-dependencies [[cylon "0.6.0-SNAPSHOT"]] :constructor cylon.user.signup/new-signup } ;; Project-local components {:component :website :library-dependencies [[hiccup "1.0.5"] [juxt.modular/bidi "0.9.4"]] :constructor {{name}}.website/new-website :using [:template-model]} #_{:component :example-page :constructor {{name}}.example-page/new-example-page ;; TODO The args should belong to the instance :args [:title "First example page" :content "Example page (A) generated by modular." :path "/example-page-a" ]} #_{:component :example-page-menu-items :constructor {{name}}.example-page/new-example-page-menu-items ;; TODO The args should belong to the instance :args [:label "First example page" :target :example-page-a]} #_{:component :example-page-b :constructor {{name}}.example-page/new-example-page :args [:title "Second example page" :content "Example page (B) generated by modular." :path "/example-page-b"]} #_{:component :example-page-b-menu-items :constructor {{name}}.example-page/new-example-page-menu-items :args [:label "Second example page" :target :example-page-b]} #_{:component :restricted-page :constructor {{name}}.restricted-page/new-restricted-page}] ;; Modules can define collections of instances of components. The same ;; component may be referenced by multiple modules, different modules ;; may provide different arguments. Modules are the building blocks of ;; templates. :modules [ ;; lein new modular app +httpkit ;; lein new modular app +httpkit:80 ; because there's only one possible option in this case ;; lein new modular app +httpkit:port:80 ;; lein new modular app full-featured-website {:module :core ; :core is special, it's always selected ;; temporary, while bidi is in checkouts, to allow for (reset) :library-dependencies [[org.clojure/clojure "1.7.0-RC2"] [prismatic/schema "0.4.3"] [aero "0.1.0"]] :files [{:template "project.clj" :target "project.clj"} {:template "system.clj" :target "src/{{sanitized}}/system.clj" :close-parens? true} {:template "main.clj" :target "src/{{sanitized}}/main.clj" :close-parens? true} {:template "dev.clj" :target "dev/dev.clj"} {:template "user.clj" :target "dev/user.clj"} {:file "gitignore" :target ".gitignore"}]} {:module :component :library-dependencies [[com.stuartsierra/component "0.2.3"]]} {:module :co-dependency :library-dependencies [[juxt.modular/co-dependency "0.2.1"]]} {:module :http-listener :components {:listener {:component :modular.http-kit/webserver :config-path [:http-listener] :config-schema {:port s/Int}}}} {:module :hello-world-website :components {:handler {:constructor {{name}}.hello-world-website/new-handler}} :dependencies {[:http-listener :listener] {:request-handler :handler}} :files [{:template "hello_world_website.clj" :target "src/{{sanitized}}/hello_world_website.clj"}]} {:module :modular-bidi-router :components {:webrouter {:component :modular.bidi/router}} :dependencies {[:http-listener :listener] {:request-handler :webrouter}} :dev-snippets [{:template "dev/routes.clj"}]} {:module :simple-bidi-website :components {:website {:constructor {{name}}.simple-bidi-website/new-website}} :dependencies {[:modular-bidi-router :webrouter] [:website]} :files [{:template "simple_bidi_website.clj" :target "src/{{sanitized}}/simple_bidi_website.clj"}]} {:module :aggregate-template-model :components {:template-model {:component :modular.template/aggregate-template-model}}} {:module :logback-logging :library-dependencies [[org.clojure/tools.logging "0.3.1"] [ch.qos.logback/logback-classic "1.0.7" :exclusions [org.slf4j/slf4j-api]] [org.slf4j/jul-to-slf4j "1.7.2"] [org.slf4j/jcl-over-slf4j "1.7.2"] [org.slf4j/log4j-over-slf4j "1.7.2"]] :files [{:template "logback.xml" :target "resources/logback.xml"}]} {:module :clostache-templater :components {:templater {:component :modular.clostache/templater }}} {:module :public-resources :components {:public-resources {:component :modular.bidi/web-resources :args [:uri-context "\"/static\"" :resource-prefix "\"public\""]}} :dependencies {[:modular-bidi-router :webrouter] [:public-resources]}} {:module :templated-bidi-website :components {:website {:constructor {{name}}.website/new-website} :application-template-model {:constructor {{name}}.website/new-application-template-model}} :dependencies {[:modular-bidi-router :webrouter] [:website] :website {:templater [:clostache-templater :templater] :template-model [:aggregate-template-model :template-model]} [:aggregate-template-model :template-model] [:application-template-model] } :files [{:template "templated-bidi-website/website.clj" :target "src/{{sanitized}}/website.clj"} {:template "templated-bidi-website/page.html.mustache" :target "resources/templates/page.html.mustache"} {:template "templated-bidi-website/content.html.mustache" :target "resources/templates/content.html.mustache"}]} {:module :bootstrap-cover-website :components {:website {:constructor {{name}}.website/new-website}} :dependencies {[:modular-bidi-router :webrouter] [:website] :website {:templater [:clostache-templater :templater]}} :co-dependencies {:website {:router [:modular-bidi-router :webrouter]}} :library-dependencies [[hiccup "1.0.5"]] :files [{:template "bootstrap-cover/website.clj" :target "src/{{sanitized}}/website.clj"}]} {:module :bootstrap-theme :files [{:file "resources/theme.css" :target "resources/public/theme.css"}]} {:module :twitter-bootstrap :docstring "Serve Twitter Bootstrap CSS, Javascript and other resources from a web-jar." :library-dependencies [[org.webjars/bootstrap "3.3.0"]] :components {:service {:component :modular.bidi/web-resources :args [:uri-context "\"/bootstrap\"" :resource-prefix "\"META-INF/resources/webjars/bootstrap/3.3.0\"" :key :bootstrap-resources]}} :dependencies {[:modular-bidi-router :webrouter] {:twitter-bootstrap :service}}} {:module :bootstrap-cover-resources :files [{:template "bootstrap-cover/page.html.mustache" :target "resources/templates/page.html.mustache"} {:file "resources/cover.css" :target "resources/public/cover.css"}]} {:module :dashboard-resources :components {:static {:component :modular.bidi/web-resources :args [:uri-context "\"/static/\"" :resource-prefix "\"public/\""]}} :dependencies {[:modular-bidi-router :webrouter] [:static]} :files [{:template "dashboard/dashboard.html.mustache" :target "resources/templates/dashboard.html.mustache"} {:file "dashboard/dashboard.css" :target "resources/public/dashboard.css"}]} {:module :single-cljs-module :components {:cljs-core {:component :modular.cljs/module :args [:name :cljs-core :mains ['cljs.core] :dependencies #{}]} :cljs-app {:component :modular.cljs/module :args [:name :default :mains ['{{name}}.core] :dependencies #{:cljs-core}]} :cljs-builder {:component :modular.cljs/builder :args [:source-path "\"src-cljs\""] :using [:single-cljs-module-cljs-core :single-cljs-module-cljs-app]}} :files [{:template "core.cljs" :target "src-cljs/{{sanitized}}/core.cljs"}] :dependencies {[:modular-bidi-router :webrouter] [:cljs-builder]}} {:module :dashboard-website :components {:website {:constructor {{name}}.website/new-website}} :dependencies {[:modular-bidi-router :webrouter] [:website] :website {:templater [:clostache-templater :templater] :cljs-builder [:single-cljs-module :cljs-builder]}} :co-dependencies {:website {:router [:modular-bidi-router :webrouter]}} :library-dependencies [[hiccup "1.0.5"] ;; Not sure what to do with 'cljs components', there's no component model [om "0.8.0-alpha2"] [sablono "0.2.22" :exclusions [com.facebook/react]]] :files [{:template "dashboard/website.clj" :target "src/{{sanitized}}/website.clj"} ]} {:module :jquery :docstring "Serve JQuery resources from a web-jar." :library-dependencies [[org.webjars/jquery "2.1.0"]] :components {:resources {:component :modular.bidi/web-resources :args [:uri-context "\"/jquery\"" :resource-prefix "\"META-INF/resources/webjars/jquery/2.1.0\"" :key :jquery-resources]}} :dependencies {[:modular-bidi-router :webrouter] {:jquery :resources}}} {:module :reactjs :docstring "Serve Facebook React resources from a web-jar." :library-dependencies [[org.webjars/react "0.11.1"]] :components {:resources {:component :modular.bidi/web-resources :args [:uri-context "\"/reactjs\"" :resource-prefix "\"META-INF/resources/webjars/react/0.11.1\"" :key :react-resources]}} :dependencies {[:modular-bidi-router :webrouter] {:reactjs :resources}}} #_{:module :sse-demo-mult-channel :components {:channel {:component :modular.async/channel :args [:size 32]} :mult {:component :modular.async/mult :size 32}} :dependencies {:mult {:channel-provider :channel}}} {:module :sse-demo-website :components {:website {:constructor {{name}}.website/new-website}} :dependencies {[:modular-bidi-router :webrouter] [:website]} :library-dependencies [[hiccup "1.0.5"] [org.clojure/core.async "0.1.346.0-17112a-alpha"]] :files [{:template "sse-demo/website.clj" :target "src/{{sanitized}}/website.clj"}]} {:module :sse-demo-events :components {:events {:constructor {{name}}.events/new-events-website}} :dependencies {[:modular-bidi-router :webrouter] [:events]} :library-dependencies [[hiccup "1.0.5"] [org.clojure/core.async "0.1.346.0-17112a-alpha"]] :files [{:template "sse-demo/events.clj" :target "src/{{sanitized}}/events.clj"} {:file "sse-demo/events.js" :target "resources/events.js"}]} {:module :less-compiler :docstring "Compile LESS files to CSS." :components {:compiler {:component :modular.less/compiler ;; TODO: modules need to be parameterized :args [:source-dir "\"resources/less\"" :source-path "\"clean-blog.less\""]}} :library-dependencies [[org.webjars/bootstrap "3.3.0"]] :dependencies {[:modular-bidi-router :webrouter] [:compiler]} } {:module :bootstrap-less-compiler :docstring "Compile Bootstrap LESS files to CSS." :components {:compiler {:component :modular.less/bootstrap-compiler :args []}} :library-dependencies [[org.webjars/bootstrap "3.3.0"]] :dependencies {[:modular-bidi-router :webrouter] [:compiler]} } {:module :clean-blog-resources :components {:static {:component :modular.bidi/web-resources :args [:uri-context "\"/static\"" :resource-prefix "\"public/\""]} } :dependencies {[:modular-bidi-router :webrouter] [:static]} :files [{:file "clean-blog/less/clean-blog.less" :target "resources/less/clean-blog.less"} {:file "clean-blog/less/variables.less" :target "resources/less/variables.less"} {:file "clean-blog/less/mixins.less" :target "resources/less/mixins.less"} {:file "clean-blog/js/clean-blog.min.js" :target "resources/public/js/clean-blog.min.js"} {:template "clean-blog/html/page.html.mustache" :target "resources/templates/page.html.mustache"} {:file "clean-blog/img/home-bg.jpg" :target "resources/public/img/home-bg.jpg"} {:file "clean-blog/img/post-bg.jpg" :target "resources/public/img/post-bg.jpg"} {:file "clean-blog/img/about-bg.jpg" :target "resources/public/img/about-bg.jpg"} {:file "clean-blog/img/post-sample-image.jpg" :target "resources/public/img/post-sample-image.jpg"}]} {:module :clean-blog-website :docstring "A redirect component is added which ensures that / will redirect to the blog index. Remove this component (and this docstring) if you don't want this." :components {:pages {:constructor {{name}}.pages/new-pages :args [:title "\"My blog\"" :subtitle "\"Musings on adventures in the amazing world of Clojure\""]} :redirect {:component :modular.bidi/redirect :args [:to :{{name}}.pages/index]}} :dependencies {[:modular-bidi-router :webrouter] [:pages :redirect] :pages {:templater [:clostache-templater :templater]}} :co-dependencies {:pages {:router [:modular-bidi-router :webrouter]}} :library-dependencies [[clj-time "0.9.0"]] :files [ {:template "clean-blog/pages.clj" :target "src/{{sanitized}}/pages.clj"} {:template "clean-blog/generate.clj" :target "src/{{sanitized}}/generate.clj"} {:template "clean-blog/posts/explore.md" :target "posts/explore.md"} {:template "clean-blog/posts/failure.md" :target "posts/failure.md"} {:template "clean-blog/posts/human.md" :target "posts/human.md"} {:template "clean-blog/posts/science.md" :target "posts/science.md"} {:template "clean-blog/html/index.html.mustache" :target "resources/templates/index.html.mustache"} {:template "clean-blog/html/about.html.mustache" :target "resources/templates/about.html.mustache"} {:template "clean-blog/html/post.html.mustache" :target "resources/templates/post.html.mustache"}]} {:module :endophile :library-dependencies [[endophile "0.1.2"]]} ;; TODO Add support for general webjars.org support in modular ;; How to? ;; #_{:module :example-pages :components #{:example-page-a :example-page-a-menu-items :example-page-b :example-page-b-menu-items} :dependency-map {:webrouter [:example-page-a :example-page-b] :example-page-a {:template-model :template-model} :example-page-b {:template-model :template-model} :menu-index [:example-page-a-menu-items :example-page-b-menu-items]}} #_{:module :webmeta :components #{:webmeta} :dependency-map {:template-model [:webmeta]}} {:module :cylon :components { :user-store {:component :cylon/email-user-store} :buddy-user-authenticator {:component :cylon/buddy-user-authenticator} :session-store {:component :cylon/cookie-session-store} :login-session-token-store {:component :cylon/atom-backed-token-store} :login {:component :cylon/login} } :dependencies {:session-store {:token-store :login-session-token-store} :login {:user-store :user-store :user-authenticator :buddy-user-authenticator :session-store :session-store} } :dev-snippets [{:template "dev/cylon/user.clj"}]} {:module :cylon/file-storage :components {:file-storage {:component :cylon/file-storage :args [:file "(io/file (System/getProperty \"user.home\") \".{{name}}-userstore.edn\")"]}} :dependencies {[:cylon :user-store] {:storage :file-storage}}} {:module :cylon/signup :components {:signup {:component :cylon/signup} :verification-code-store {:component :cylon/atom-backed-token-store} } :dependencies {:signup {:user-store [:cylon :user-store] :user-password-hasher [:cylon :buddy-user-authenticator] :session-store [:cylon :session-store] :verification-code-store :verification-code-store}}} ;; A log emailer which can be diminished in favour of a real emailer (e.g. sendgrid) {:module :cylon/log-emailer :components {:emailer {:component :modular.email/log-emailer}} :library-dependencies [ ;; temp while cylon in checkouts, because cylon already depends on juxt.modular/email [juxt.modular/email "0.0.1"]] :dependencies {[:cylon/signup :signup] {:emailer :emailer}}} {:module :protected-site-website :components {:website {:constructor {{name}}.website/new-website} :static {:component :modular.bidi/web-resources :args [:uri-context "\"/static\"" :resource-prefix "\"public/\""]}} ;; cylon temps :library-dependencies [[camel-snake-kebab "0.1.4"] [yada "0.3.3"] ] :dependencies {[:modular-bidi-router :webrouter] {:website :website :static :static :cylon-login [:cylon :login] :cylon-signup [:cylon/signup :signup]} :website {:templater [:clostache-templater :templater] :session-store [:cylon :session-store]} [:aggregate-template-model :template-model] [:website] [:cylon :login] {:renderer :website} [:cylon/signup :signup] {:renderer :website}} :co-dependencies {:website {:router [:modular-bidi-router :webrouter] :template-model [:aggregate-template-model :template-model]} [:cylon :login] {:router [:modular-bidi-router :webrouter]} [:cylon/signup :signup] {:router [:modular-bidi-router :webrouter]}} :files [{:template "protected-site/website.clj" :target "src/{{sanitized}}/website.clj"} {:template "protected-site/html/page.html.mustache" :target "resources/templates/page.html.mustache"} {:template "protected-site/html/index.html.mustache" :target "resources/templates/index.html.mustache"} {:template "protected-site/html/dialog.html.mustache" :target "resources/templates/dialog.html.mustache"} {:template "protected-site/html/protected.html.mustache" :target "resources/templates/protected.html.mustache"} {:file "protected-site/style.css" :target "resources/public/style.css"} ]} {:module :intro-website :components {:website {:constructor {{name}}.website/new-website} :static {:component :modular.bidi/web-resources :args [:uri-context "\"/static\"" :resource-prefix "\"public/\""]}} :dependencies {[:modular-bidi-router :webrouter] [:website :static] :website {:templater [:clostache-templater :templater]} [:aggregate-template-model :template-model] [:website]} :library-dependencies [[hiccup "1.0.5"] [org.clojure/data.csv "0.1.2"] [cheshire "5.4.0"]] :co-dependencies {:website {:router [:modular-bidi-router :webrouter] :template-model [:aggregate-template-model :template-model]}} :files [{:template "intro/website.clj" :target "src/{{sanitized}}/website.clj"} {:template "intro/page.html.mustache" :target "resources/page.html.mustache"} {:template "intro/index.html.mustache" :target "resources/index.html.mustache"} {:file "intro/style.css" :target "resources/public/style.css"} {:file "intro/weather.csv" :target "resources/weather.csv"} {:file "intro/animals.json" :target "resources/animals.json"} ]} {:module :aleph :library-dependencies [[juxt.modular/aleph "0.1.2"]]} {:module :yada-examples :docstring "Simple examples demonstrating how to use yada in various ways" :components {:examples {:constructor {{name}}.examples/new-examples :config-path [:standalone-examples] :config-schema {:port s/Int} :args []} :swagger-ui {:constructor {{name}}.swagger-ui/new-swagger-ui :config-path [:swagger-ui] :config-schema {} :args []}} :dependencies {[:modular-bidi-router :webrouter] [:swagger-ui]} :co-dependencies {:swagger-ui {:router [:modular-bidi-router :webrouter]}} :library-dependencies [[yada "0.5.0-SNAPSHOT"]] :files [ {:template "yada/examples.clj" :target "src/{{sanitized}}/examples.clj"} {:template "yada/swagger_ui.clj" :target "src/{{sanitized}}/swagger_ui.clj"} ]} #_{:module :dev-browser :components #{} :dependency-map {}}] ;; These are the templates that the user chooses as the argument in ;; lein new modular :application-templates {"hello-world-web" {:description "A simple website that displays \"Hello World!\"" :modules #{:component :http-listener :hello-world-website}} "bidi-hello-world" {:description "A simple website that uses a bidi route" :modules #{:component :http-listener :modular-bidi-router :simple-bidi-website}} "templated-bidi-website" {:description "A simple wesbite that demonstrates a bidi route and Mustache templating" :modules #{:component :http-listener :modular-bidi-router :public-resources :templated-bidi-website :clostache-templater :aggregate-template-model :bootstrap-theme :logback-logging :twitter-bootstrap :jquery}} ;; A clean and simple website for homepages, etc. "bootstrap-cover" {:description "A rendition of Bootstrap's 'cover' template" :modules #{:component :co-dependency :logback-logging :http-listener :modular-bidi-router :public-resources :twitter-bootstrap :jquery :clostache-templater :bootstrap-cover-resources :bootstrap-cover-website} :files [{:template "bootstrap-cover/README.md" :target "README.md"}]} ;; A course on highly-concurrent async HTTP for the BBC "sse" {:description "A JUXT training module, demonstrating HTML5 Server Sent Events with http-kit" :modules #{:component :logback-logging :http-listener :modular-bidi-router :sse-demo-website :sse-demo-events :jquery} :files [{:template "sse-demo/README.md" :target "README.md"}]} "dashboard" {:description "A rendition of Bootstrap's 'dashboard' template" :modules #{:component :co-dependency :logback-logging :http-listener :modular-bidi-router :dashboard-resources :twitter-bootstrap :jquery :reactjs :clostache-templater :dashboard-website :single-cljs-module :bootstrap-less-compiler} :files [{:template "dashboard/README.md" :target "README.md"} {:file "custom-less/custom-bootstrap.less" :target "resources/less/custom-bootstrap.less"} {:file "custom-less/custom-variables.less" :target "resources/less/custom-variables.less"} {:file "custom-less/custom-other.less" :target "resources/less/custom-other.less"} ]} "clean-blog" {:description "A responsive blog site based on Start Bootstrap's 'Clean Blog'" :modules #{:component :co-dependency :logback-logging :http-listener :modular-bidi-router :twitter-bootstrap :jquery :clostache-templater :less-compiler :clean-blog-resources :clean-blog-website :endophile} :files [{:template "clean-blog/README.md" :target "README.md"}]} "protected-site" {:description "A demonstration of securely protecting web pages from unauthorized users" :modules #{:component :co-dependency :logback-logging :http-listener :modular-bidi-router :twitter-bootstrap :jquery :clostache-templater :cylon :cylon/signup ; enable on with +signup switch :cylon/log-emailer ; enable on with +signup switch :cylon/file-storage ; TODO should be configurable :aggregate-template-model :protected-site-website } :files [{:template "protected-site/README.md" :target "README.md"} ]} ;; TODO: It would be better for modules to have dependencies. Therefore, :cylon/signup would depend on :cylon/log-emailer. +sendgrid would augment with :sendgrid-emailer and diminish :cylon/log-emailer "intro" {:description "An introduction to Clojure (training course content)" :modules #{:component :co-dependency :logback-logging :http-listener :modular-bidi-router :twitter-bootstrap :jquery :clostache-templater :aggregate-template-model :intro-website } :files [{:template "intro/README.md" :target "README.md"} ]} "yada" {:description "Yada examples" :modules #{:component :co-dependency :aleph :yada-examples :modular-bidi-router :http-listener :logback-logging } :files [{:template "yada/README.md" :target "README.md"} {:template "yada/config.edn" :target "config.edn"} ]} ;; TODO Let's add some example pages ;; TODO Let's add some menu bars } } ;; TODO Show documentation, like this :- ;; lein new modular basic-website --help