Play Framework How to Compile Views for Distribution - scala

I have common views that I want to share across multiple Play Framework 2.2.1 applications. I'm thinking packaging them up into a single library and publishing them to our Maven repo is the way to go, but something isn't working correctly during the compile phase.
My project has a single file My/Namespace/myView.scala.html. After compiling my package jar has a file named exactly as my view. My/Namespace/MyView.scala.html I was expecting to see some class files.
The play framework seems to do something very similar https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/views/helper/twitterBootstrap/twitterBootstrapFieldConstructor.scala.html and looking at their Maven package this seems to compile into a twitterBootstrapFieldConstructor class (along with all the meta classes scala generates):
I'm guessing i'm missing something in my SBT configuration that makes it compile scala.html files...but i'm just not seeing it.
Anyone have some insight into what i should be doing?

It appears the best option at this time is to make use of the Twirl library https://github.com/spray/twirl which is the template engine wrapped up into a similar but distinct API.
sbt .13 support is in a testing phase see https://github.com/spray/twirl/issues/15#issuecomment-32272389 as it appears there's going to be some reconciliation of this project & play's templating libraries (one using the other)

Related

Assemble transitive closure of a main file in scala sbt project

I'm working on a scala sbt project, and I am at a point where I want to assemble the whole thing to share a .jar-file with others, so that they can use it on their side. For my local testing, I'm doing so using the sbt-assembly plugin, that works nicely.
When sharing, I would though prefer to only share the parts that are important for the other party (the project has huge components that irrelevant at the current point, and I'd prefer not to share these for various reasons). Concretely, they will be executing one particular main file, so it would be enough to pack everything that this file depends on.
Is there a way to accomplish this? I'd also be interested in doing this on the code level (i.e., create a copy of the project that only contains dependencies of that main file), but also while assembling or even modifying the jar file after assembly is okay. I did not find the tools to achieve any of these.
As I said, I'm dealing with a scala sbt project, and I'm working with IntelliJ IDEA; I'd also be happy with an IDE tool that does the job.

How do you use play framework as a library, in a scala project

Use Play Framework as a component got a server up, but configuring the file system paths for routes file, views, etc, give or take having to take care of a thread pool for the embedded play server is a different story. Basing on the aforementioned, I started a template for including play as a library, but it remains unclear how to wire the paths, hopefully in an IDE-import friendly way too, so that Play can be nicely used in an existing non-play project, as a library.
How do you configure the file system paths for the routes file and views?
What else should be handled for being as robust as running as the framework?
Anything special for bundling the project for deploy with Play now included?
Motivation: Adding Play to a project, in the current state of affairs, means wrapping the project definition and structure around Play, and losing full compilation in sbt (because only run completes the compilation when using the play sbt plugin). As future Spray support is vague and Akka http is beta-ish, using Play as a library seems to plug a hole.
Somehow this didn't pop up in google, until someone suggested the link on gitter: https://www.playframework.com/documentation/2.5.x/ScalaEmbeddingPlay
Note that an application.conf file containing the required crypto secret can simply sit under src/main/resources in this embedded mode (up until you want to override it for production as per the documentation about it). This is quite enough for a REST server.
However now back to the docs, in case you want more than REST:
This can be used in conjunction with the Twirl template compiler and Play routes compiler
So for Play view templates (which are twirl templates really), refer to the repo I mention in the question body, in which #JonasAnso kindly enabled exactly that.

Writing sbt plugin that exports itself to child projects?

I'd like to write a plugin that makes its code available to projects that uses the plugin.
The plugin would be defined as follows:
package mypackage
object MyPlugin extends sbt.Plugin {
...
}
trait MyInterface {
...
}
A client code should be able to export and instantiate mypackage.MyInterface to make possible for plugin distinguish MyInterface instances during parsing Analysis API info.
I should add that I would like to create separate config for doing some code testing (existing test are not suited for me) and plugin would be exported only to this config's classpath.
If someone would like to ask if this approach is legitimate I answer that sbt itself uses this method for working with plugins. I've found almost no documentations for writing sbt plugins and was forced to peek inside the sbt code. There I found similar cases and some hints. But the code is too complicated full of macroses and DSL with lack of documentation strings, so I grasp only part of it.
My rather limited knowledge about sbt lets me argue about the merits of your question and what you're going to achieve.
Since a plugin is a part of the build and should (merely) help the project's artifact(s) see the light of production release, it should in no way be the artifact's dependency as you'd have to release the dependency (that's a sbt plugin in its current form) so others would be able to download it, too.
What you'd rather do is to have a plugin that wraps a dependency and when included in a build makes the dependency a dependency of your project. That's acceptable in my opinion.
How much do I differ from your use case? I'd happy to refine the answer after having heard some additional information.

How best to structure and build Clojure apps with plugins?

I think (see below) that I would like to structure a Clojure project as multiple modules, with ordered dependencies - just like Maven lets me do with multi-modules projects.
But I can't see how to do this with Leiningen - all I can see is the checkouts fix described in the FAQ which doesn't seem to be as powerful.
Will lein do this? Should I be using Gradle instead? Or is this kind of thing not needed?
Some more context: I am wondering how to architect a modular application that supports plugins (which I imagine means jars dumped on the classpath). And am wondering to what extent I can structure that as a core + plugins (I am thinking I should be able to do something with Clojure's dynamic code loading and not have to go with Java/OSGi). So I guess the driving motivation for a single project comes from wanting some way of packaging everything (the core + default plugins) as a single blob that is easy for the end user, but which can also be divided up (and which is built and tested in fragments, testing the logical independence of each module). More general advice about this is welcome
Update
A possible solution that wasn't mentioned below is using a Maven plugin - I assume that supports everything Maven does, but compiles Clojure, so will work with nested modules, etc.
First, it does not seem like Leiningen supports a module hierarchy like Maven does. The checkouts are the next closest thing it has. It should be sufficient though to develop a modular application in Clojure though.
For the project structure, I would have an API project, a "core" project, the plugins themselves, and a separate packaging project. The core and the plugins should only depend on the API. Which build tool you use to create the packaging project is up to you. Gradle would probably be more effective at handling the packaging, however having the "checkout" functionality Leiningen offers could make development of the system as a whole easier.
I would take a look at the code for Leiningen and Noir to figure out how to effectively handle this.
For dynamically loading the plugins, I would start with looking how Noir handles it in two of their files:
server.clj has namespace loading for all files under a particular namespace. Under the hood it uses tools.namespace, but you can easily see how it's used to require every namespace under a particular base. This is how Leiningen handles custom tasks as well - the base definition for the task should be in the leiningen.$task namespace.
core.clj has what I would use for plugin registration. In summary, use a map under an atom and add plugins to that map. I would advice wrapping the registration with a macro to keep your code cleaner.
What I listed above should be sufficient if you don't need to handle adding plugins at run time. If you don't have every plugin on the classpath during start-up, I would recommend utilizing pomegranite to add entries to the classpath. You can see an example in classpath.clj.

Basic maven issue- building a java/scala library

I'm sure I'm just being obtuse but I've bought the OA book, a couple of others and I'm still just as dense as before....I'm trying to build a scala library with maven and the scala plkugin, but I think this applies to Java as well.
It has no main code module, it's just a library. If I have a class such as com.busygeeks.binklebots and source files under it, I created
src
scala
com
busygeeks
binklebots
sourcefies.....
When I try a maven:compile, it completes successfully, but doesn't actually build anything.
I know it's very basic -- but I'm missing it. How can I say "Take everything under src/scala and build and jar it"
It looks like you might just need a main directory in there between src and scala.
If you really wanted to, you could specify a custom layout with the java and scala directories immediately under src. But you almost certainly don't want to, for the reasons given in the Maven documentation linked above.