call twirl template from ScalaJs - sbt

The play framework documentation says (https://www.playframework.com/documentation/2.6.x/ScalaTemplates): You can then call this from any Scala code as you would normally call a method on a class:
val content = views.html.Application.index(c, o)
Is there an easy way to call twirl templates within ScalaJs for a
crossProject(JSPlatform, JVMPlatform).crossType(CrossType.Pure)

Given that Twirl, the templating framework of Play, supports Scala.js, it should relatively simple. The only thing is that, by default, Twirl will not look for templates in the shared source directory. So you'll need to configure its source directories, as explained in its readme, using something like:
sourceDirectories in (Compile, TwirlKeys.compileTemplates) +=
baseDirectory.value.getParentFile / "src/main/twirl"

Related

Publishing Custom Elements, naming conventions, best practices?

I am about to make my Custom Element <card-t> public
pre-release is at: https://github.com/card-ts/playingcardts
Suggestions and enhancements much appreciated!
Couple of questions:
Naming Custom Elements
There is: https://www.webcomponents.org/community/articles/how-should-i-name-my-element
but it doesn't get past "must include a hyphen"
I went with element.card-t.js for sorting purposes.
Other best practices ??
Wrapping in IIFE & ES Modules?
The Custom Elements gets created in the Global Namespace, and doesn't return anything like a library does.
Wrapping in an IIFE should be enough?
Is there value in loading it as module?
<script type="module" src="element.card-t.js">
Extending Custom Elements
Should we by default return the class definition so extending is easier?
Since this is an opinion question these are my opinions:
Naming Custom Elements
I always name my JS file based on my class name and my class name is just the tag name but capitalized. So my tag <my-thing> would have a class name of MyThing and my filename would be components/MyThing.js
Wrapping in IIFE & ES Modules?
I create all of my code in ES6+ and then I create an additional ES5 CommonJS version and an ES5 IIFE version and let people load what they want.
I use rollup and my component-build-tools to create my various versions. component-build-tools component-build-tools also combines all dependencies of a component into the output file. This can lead to some replication, but most of the time that is small enough I don't mind.
My components end up with their templates and locale strings embedded into the published files. This is a feature of component-build-tools.
Extending Custom Elements
As a general rule I expose the class name in all three formats of my files. This does help with extending my components, yet I doubt that many people will ever want to do that.
Where to place the files.
The hardest thing is where to place the files so they are easily accessed by the web page.
I have a build step that copies my files from the node_modules folder into a dist folder. This was the easiest thing for me to know exactly where my files are located.
Doing this allows me to npm install anything and then still get their files into a location I know and can use. But it also has lead to me not worrying greatly about where my files end up in my repo.
I do tend to have a dist folder and in there I have:
dist
+- js
+- components
+- MyThing.js
+- MyThing.min.js
+- AnotherThing.js
+- AnotherThing.min.js
+- SoOn.js
+- SoOn.min.js

Why do we need to instantiate a type at run time?

I am new to the usage of reflection in Java/scala. It is not quite clear to me why we need to instantiate a type at runtime. An example would be the best. Thanks a lot.
I will give you a general example of where runtime type instantiation or in general inspection of a types is useful. Think of the Plugin Pattern. Assume you want to create an application that allows users to create plugins. You don't have the plugins the users are going to make in the future, at hand. How are you able to use their plugins after you have released your application? You need to be able to inspect their plugins for a method your application requires and then call said method.
In order to enable this, language designers create a platform in which you are able to query a module (jar in java, assemblies in .net) for the types it defines and the methods, fields, etc it contains. You can then call any method, instantiate any type you want and basically interact with the module as if you had the module at compile time and you were referencing it(well not exactly but you get the point).
Here's and example of a method call that happens at runtime. You can assume that we have already created foo from a string we get from a configuration file at runtime. foo was specified as the name of the jar file containing the plugin types. I don't want to provide the instantiation code as it would make this too bloated, but here is the method:
Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);
As you see, we basically got the type of the class foo, we queried it for a method using the method's name and then called it. By doing so we extended the functionality of our program with the plugin at runtime.

Metadata for Exceptions thrown by a class

Flash builder lets me insert metadata for events fired by a class, example:
[Event("myEvent", "flash.events.Event")]
public class MyClass() {
}
Is there any way to do the same for Exceptions?
Currently I have checked here, and can't see it documented. Perhaps it's not even worthwhile, what are your thoughts.
There are ways to create your own metadata; and add that into your app at compile time. Use the keep-as3-metadata compiler argument.
It will be up to you to write code to do something with it at runtime; or to build IDE extensions to make use of the code while writing the code.
To access such metadata at runtime, you'll need to perform some type of introspection. Here are some docs and another StackOverflow Question about this.
Many Flex Frameworks make use of custom metadata.

Is it possible to retrieve the swf metadata within the actionscript of a flex project?

I know that it is possible to add swf metadata to the compile command as a command option, but I can't find any documentation on how to access these metadata within the actionscript during runtime. We're trying to add a version number to the swf during compile time and then somewhere in our app we would retrieve it during runtime, here is the command example to add the description metadata.
mxmlc -description "version 1.2.3"
I know the swf metadata is used by search engines and other utilities to gather information about the SWF file, but surely you should be able to retrieve them in the actionscript during runtime?
Have you tried to namespace it like this: http://hasseg.org/blog/?p=165
So maybe "-define+=VERSION::description,"version 1.2.3"
And then access it using the example code:
var VERSION:Namespace = new Namespace("VERSION");
var ver:String = VERSION::description;
EDIT: Hmm. Doesn't work for me in Flex Builder, but I found this: http://livedocs.adobe.com/flex/3/html/help.html?content=compilers_21.html, which seems to confirm the idea.

Optimizing Flex when multiple modules are used

I have a Flex application where load time is extremely important (consumer site). i want to be able to get something up on screen and then allow additional modules to be loaded as necessary.
The issue I'm facing is that the sum total of all the modules is much larger than if i were to include all the components in a single .swf file.
Its pretty obvious why. For instance the classes needed for web service access seem to take about 100kb. If I dont use those classes in my main.swf then they'll be included in EVERY module that uses them. So if I have 5 modules thats an extra 500kB wasted.
In theory I want 3 levels
main.swf - minimum possible layout / style / font / framework type stuff
common.swf - additional classes needed by module 1 + module 2 (such as web services)
module1.swf - module 1 in site
module2.swf - module 2 in site
I dont know if this is even possible.
I'm wondering if I can load swz/swf files for portions of the framework instead of the entire framework.
I really need to get my main app size down to 200Kb. It grows to 450kb when I add web services and basic datagrid functionality.
Any lessons learned would be appreciated.
I know this was awhile ago, but I figured I'd post another response in case anyone is still looking for an answer on this.
I've been looking into optimizing Flex apps and, after some checking into it, have decided to use Modules. Primarily 'cause they have such good options for optimization.
The two mxmlc commands you need are:
mxmlc -link-report=MyAppReport.xml MyApp.mxml
and
mxmlc -load-externs=MyAppReport.xml MyModule.mxml
My external swf (using the Flex Framework) is now only 21k. It's doing much (yet), but even as it does more and more, it will continue to use resources from the main app code.
Here's the batch file I created to speed up the process (you have to have put mxmlc in your Environment Path variable for it to work like this. Control Panel -> System -> Advanced -> Environment Variables, Edit the Path System Variable, adding the path to your mxmlc (requires a reboot)):
cd C:\Projects\MyProject\Develop\Modules
mxmlc -link-report=MyAppReport.xml C:\Projects\MyProject\Develop\Source\Main.mxml
mxmlc -load-externs=MyAppReport.xml MyModule.mxml
move /Y MyModule.swf ..\Runtime\Modules
More info here:
http://livedocs.adobe.com/flex/3/html/help.html?content=modular_4.html
Hope that helps!
Flex is a bit of a pig when it comes to file size. There really is only one way to get your app sizes down and that is to use an external swz for the framework. There is an Adobe Devnet article on Improving Flex application performance using the Flash Player cache which I recommend you read.
On a project I worked on we had problems with our preloading module sucking in classes that we didn't want. What we had to do was create interfaces to the classes that resided in the other modules and reference them that way. When the module is loaded we simply assigned a reference to the IApplicationModule in order to call our initialization code.
Also look into putting your classes into a seperate SWF file and then use ApplicationDomain to get access to the classes
(this code taken from this forum post which explains how to access classes loaded from modules in Flex)
private function loadContent(path:String):void
{
var contentLoader:Loader = new Loader();
contentLoader.contentLoaderInfo.addEventListener(
Event.COMPLETE,
loadContent_onComplete);
contentLoader.load(new URLRequest(path));
}
private function loadContent_onComplete (event:Event):void
{
var content:DisplayObject = event.target.content;
if(content is IFlexModuleFactory)
{
var content_onReady:Function = function (event:Event):void
{
var factory:IFlexModuleFactory = content as IFlexModuleFactory;
var info:Object = factory.info();
var instanceClass:Class = info.currentDomain.getDefinition(
info.mainClassName) as Class;
addChild (new instanceClass ());
}
content.addEventListener ("ready", content_onReady);
}
else
{
addChild (content);
}
}
There is an option on the command-line compiler to exclude class definitions that are already compiled into another swf. It works like this:
Compile the Main Application (which contains a loader) and opt to generate a report.
Compile the Module and opt to exclude classes in the above report.
You could look into the ModuleLoader class, maybe you can load up your core stuff in the first 200kbs then load the rest when and if it's needed.
Also it's worth bearing in mind that any SWC's you use are embedded at compile time whereas any SWF's are loaded at runtime.

Resources