Are there any best practices for using Google Web Fonts in a Google Web Toolkit application? My initial inclination is to simply add the css reference directly in my .html file, a la
<link href='http://fonts.googleapis.com/css?family=Josefin+Sans:light,regular,bold' rel='stylesheet' type='text/css'>
But I'm not sure if this is the best way to do it. Is there any advantage to (or any way to) use ClientBundle here?
Google discourages the direct inclusion of css files on host pages for a mere fact that in this case GWT code has an external (detached) dependence. This only matters if you share a GWT module with other developers - note that this might happen in the future when your project gets refactored by some other people that took over the development. So it's still a good practice to make GWT modules with type-safe external dependencies.
As you know you can simply use one of the recommended ways:
Using a CssResource contained within a ClientBundle.
Using an inline <ui:style src="http://fonts.googleapis.com/css?family=Josefin"> element in a UiBinder template.
Related
I am new in GWT. I want to ask some questions about UI binder:
<ui:with field='res' type='com.my.app.widgets.logoname.Resources'/>
(1) Refer to code above. What is the meaning of type? Is meant the file location?
(2) Why need to use external resource for the UI binder?
(3) When I write css, in java file should I need to write the "extends CssResource" word?
I really don't understand. Please help me to answer the question. Thanks.
<ui:with field='res' type='com.my.app.widgets.logoname.Resources'/>
Refer to code above. What is the meaning of type? Is meant the file location?
Here type is equivalent to below java code
Resources res = new com.my.app.widgets.logoname.Resources();
Why need to use external resource for the UI binder?
Sometimes your template will need to work with styles or other objects that come from outside of your template.
When I write css, in java file should I need to write the "extends CssResource" word?
Yes you have to use extends CssResource
For detailed explaination and samples please have a look at GWT UIBinder - Using an external resource.
Find a sample code here about GWT - Using UiBinder.
Here is the key points of using UIBinder:
The UiBinder is a framework designed to separate Functionality and View of User Interface.
The UiBinder framework allows developers to build gwt applications as HTML pages with GWT widgets configured throughout them.
The UiBinder framework makes easier collaboration with UI designers who are more comfortable with XML, HTML and CSS than Java source code
The UIBinder provides a declarative way of defining User Interface.
The UIBinder seperates the programmic logic from UI.
The UIBinder is similar to what JSP is to Servlets.
Right now, I am using <%- assets.js() %> to include all the javascript files on all pages. So, it means all the functions will be initialized on all pages.
I am wondering how can I disable a javascript file on a specific web page? Or, if there is a way to include some of the javascript files on a specific web page but not all the javascript files.
The trouble with the auto-loading is that it's really hard to dictate the ordering of the source files in any meaningful way-- it really comes down to how you've structured the front-end.
In v0.8.x (the version you're working with, from what I can tell), you can use the config/assets.js to control the ordering of folders that get loaded in. This is not ideal, but is a decent workaround that my team used on several projects.
In v0.9, we've removed rigging/asset-rack in favor of tight integration Grunt, which has a large community and some really cool and well maintained packages for most types of asset bundling, etc.
In any case, here are the different approaches you can investigate for serving assets in the new version of Sails.js:
Treat it just like anything else
In your layout.ejs file, create <link /> and <script></script> tags to link in your css and javascript files like you would normally.
Use AMD (Require.JS)
I think lots of folks would say this is actually the best option. Require is a pretty powerful tool. And I'm mostly in agreement-- if you're working with front-end javascript that could be coming from anywhere, and is going to be extended by other developers who may be using a different framework, AMD is a great way to make sure you stay safe. If you're using Require, each js file is its own module, and declares its own dependencies, so asset dependency management becomes a thing of the past. Then in production mode, there are a couple of different options to compile and minify your CSS and JS. You can even dynamically load templates and CSS from JS with Require, which is pretty neat. AMD/RequireJS is a hands-down winner if you're interested in loading some or all of your assets asynchronously. It's also an all-client-side solution, which is pretty cool.
The only downside in my mind is the complexity. If you have control over the framework being used, you really shouldn't have to manually enter dependencies for each file-- it can figure that out itself (see https://github.com/balderdashy/mast/blob/2.x/lib/raise.js)
Use Grunt
When you make a new project with sails new foo in Sails v0.9, a file called Gruntfile.js is created. It has lots of stuff in it, a lot of which isn't being used by default. You can do almost anything with Grunt, but in particular, you'll want to look at how it's set up to copy files from assets/* to .tmp/public/.
sails new foo --linker (Sails v0.9 only)
Linker is a lot like what asset-rack/rigging does currently. It creates the same Gruntfile as #3 above, but utilizes more of the contents. It will auto-link files in the order you specify. Instead of view partials (e.g. <%= %>), the scriptlinker plugin allows you to customize the delimiters where js, css, and templates will be injected. By default, the Gruntfile is set up to use JST precompiled templates, but again, you can set it up however you like.
Hope that helps guys, and best of luck!
-Mike
PS- v0.9 is coming out very very soon, I've just been working through tests and issues to make sure we're 100% there. If you'd like to try it out, check out:
https://gist.github.com/mikermcneil/5930330
The lead for Sailsjs replied to this issue (though it was about selecting CSS files):
"For now, you can (a) bring in all styles all the time and make only the relevant ones apply (b) use another tool (like Grunt) to bundle assets like you would in a vanilla node.js project or (c) link the stylesheets manually (put them in your public folder)."
See: choosing assets sailsjs
Similar, more complex questions have been asked in the Google group:
https://groups.google.com/forum/#!topic/sailsjs/yt9EpJlfzXA
Considering the above, you may want to have a separate layout.ejs for each page. You can specify the layout.ejs you want for each page with
res.view({ layout: "different_layout" })
The layout.ejs would (a) not call assets.js() but have < script > for all the js files needed, or (b) call assets.js() to serve all the common js files in ./assets/js plus < script > to serve the page dependant ones residing elsewhere.
I have a wrapper around assets.js() that allows you to include all assets except for specified files. You can also use it to include only specific assets elsewhere. So you could load your common assets in layout and include other assets only on pages where they are required.
See my answer to How can I include javascript assets selectively in SailsJS?
I really like the approach in GWT where you can define "divs", "spans" etc in a regular html page, then in the GWT entry point simply push a button or some other component inside the div.
So small example, here is a snippet of a gwt html page:
<body class='page'>
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position: absolute; width: 0; height: 0; border: 0"></iframe>
<div>
Query Terms: <span id="txtQuery"></span>
<span id="btnQuery"></span><br>
...
</div>
</body>
And here is a small java snippet contained in the gwt entry point:
ClickHandler clickHandler = ...
TextBox txtQuery = new TextBox();
Button btnQuery = new Button("Query", clickHandler);
RootPanel.get("txtQuery").add(txtQuery);
RootPanel.get("btnQuery").add(btnQuery);
One of the reasons I like this approach is that it allows non java coders to design / write the html stuff, and I also like the separation between GWT / java code and the html code.
However... this may work well for a simple web page, but how do you scale this approach up into many webpages? From what I understand, the "GWT way" of doing things is to have one webpage and use history to hide and show various GWT components. I have built 2 projects in GWT using this standard technique, but recently discovered that you can do the sort of thing I showed above.
Is there any way of scaling the above 2 snippets into multiple html pages, where GWT injects its components into standard html pages?
here is no GWT way. At least not in GWT mission statement. If you want to pursue your aproach there are multiple ways how you can do it.
GWT app per page. (e.g. on each page a gwt app specific for this page is included). You simply compile a new GWT module for each page where you need some GWT functionality. You can use few of them together on one page, or none. This approach is good if you GWT apps are going to be really simple, and you don't need to use stuff like GXT Grid on every single page with different settings, otherwise you will waste user browser will have to download large chunks of JS code over and over, and this will be a big problem if you have a lot of pages.
One big GWT app for all pages. Just put everything into single GWT app, create some kind of switch (some js variable) so the app knows what it has to create. Some code splitting might be used, so on each page only things which are really required will be downloaded. Since the same JS will be used on each page, caching should solve the problem with downloading application code over and over (but you still have the problem with actually parsing/running the code very time user changes the page)
There is also a third approach, the most effective of all, but the hardest as well. As soon as the user loads one of the pages, there is no more navigation, gwt module simply takes template for page to which user wants to navigate, and replaces current html code with newly generated template. This is quite easy to achieve, if you will use TextResource from ClientBundle and HTMLPanel. The problem is with navigation in address field (GWT app will have to be responsible for changing the address, so the users can create bookmarks or send the link to their friends). You will use one single GWT script for this and some code splitting is recommended.
All three approaches are totally valid, depending on your requirements you can pick any of them. Also if all you want is to provide people ability to use HTML to layout GWT screens, you might want consider using combination of HtmlPanel and ClientBundle's TextResource.
If the goal is to have designers work on HTML rather than Java, then how about UiBinder? It'd give you what you want (separate HTML –or rather, XHTML-like– code from Java code) inside a GWT project.
I have a Grails plugin which I’m using as basically a container for some shared static resources that will be used by various other Grails projects in-house (CSS, JS files, etc). The idea of using a plugin was just to share these things — the plugin doesn’t really do anything else very interesting. What is the best way to directly reference resources inside the plugin? I’d rather not create custom taglibs, since I’m not really adding any functionality here; I just want access to the resources inside the plugin — something like this, e.g., to reference a CSS file from a GSP:
<g:link rel="stylesheet" url="${resource(dir:'css', file:'mycss.css',
plugin:'myplugin')}"/>
Does this idea violate the concept of plugins, where only certain aspects of it should be exposed, and the rest is a black box? Alternative approaches to sharing static resources among related Grails projects are also welcome, in case I’m headed down an insane, wrong-headed path by even trying this. :)
First, in Grails, a plugin is not considered a black box. To the contrary, all the code is exposed; if you really want to make it a black box, then you should use another plugin, Binary Artifacts.
Secondly, your approach is very sensible. To access plugin resources, I would have created a taglib like:
def res = { attrs ->
attrs.dir=pluginContextPath
//Do whatever you want here
out << g.resource(attrs)
}
and call it the same way as <g:resource>. That way, you don’t even have to expose your plugin’s resources path. The Nimble plugin is using this approach.
Also you might have a look at the Grails Resources plugin, which is trying to handle the nightmare of static resource dependencies among Grails plugins and projects. I have never used it, but for sure in my next Grails project, I will integrate it (BTW, it will be included into Grails 1.4).
can i design my web pages in html and css instead of java methods and use gwt only in parts of page that i need ajax? and which one is better gwt, extgwt, vaadin(it run apps in server-side.can i also use it in client-side?), etc...? do i also need to know javascript for using gwt?
thanks
can i design my web pages in html and
css instead of java methods and use
gwt only in parts of page that i need
ajax?
Yes, you can. You can create a div on your HTML page and insert your GWT widget there.
which one is better gwt, extgwt,
vaadin(it run apps in server-side.can
i also use it in client-side?)
I don't know about vaadin but Ext-GWT is a set of ready made components to use with GWT which make your life easier especially if you want to build an web app that looks and feels like a desktop application.
do i also need to know javascript for
using gwt?
No, it can be useful sometimes but is not necessary.