Grails - migrating from the resources to the asset-pipeline plugin - grails

I've been trying to install the angularjs/restangular js libraries in my Grails app based on a chapter in Grails In Action. The problem is that the code in this book uses the resources plugin which has been replaced in the version of Grails I'm using (2.4) by the asset-pipeline plugin.
I've tried to implementing the book code using the official documentation as a guide, but the required javascript is not getting included in my gsp files. Also, references to <r:layoutResources/> and <r:require module="core"/> in my gsp files, are being highlighted as "unknown tags" in the GGTS editor.
Can anyone advise on where I've gone wrong migrating from the resources plugin to the asset-pipeline? Specifically I have copied the following js libraries into my web-app/js folder:
And I want to define dependencies between those modules and so I have created the following conf\ApplicationResources.groovy:
modules = {
angularjs {
resource url:'js/angular-1.3.15.js', disposition: 'head'
}
restangular {
dependsOn 'angularjs'
resource url:'js/restangular-1.4.0.js'
}
lodashjs {
resource url:'js/lodash-3.6.0.js'
}
core {
dependsOn 'restangular, lodashjs'
resource url:'/js/custom.js'
}
}
And views\layout\main.gsp contains:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title><g:layoutTitle default="Grails"/></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="${assetPath(src: 'favicon.ico')}" type="image/x-icon">
<link rel="apple-touch-icon" href="${assetPath(src: 'apple-touch-icon.png')}">
<link rel="apple-touch-icon" sizes="114x114" href="${assetPath(src: 'apple-touch-icon-retina.png')}">
<asset:stylesheet src="application.css"/>
<asset:javascript src="application.js"/>
<g:layoutHead/>
<r:layoutResources/> <-- why is this highlighted as 'unknown'?
</head>
And views\post\singlepage.gsp:
<head>
<title>Timeline for ${ user.userid }</title>
<meta name="layout" content="main"/>
<content tag="htmlAttrs">ng-app="testsparestang"</content>
<r:require module="core"/> <-- again, this is unknown!
</head>

If you want to use resource plugin please comment the asset-pipeline plugin code from your BuildConfig.groovy file.
And if you want to use asset-pipeline then just comment the resources plugin from the BuildConfig.groovy.
Now see to it that you remove the tag from your layout as this will work only with resources plugin and is not required with asset-pipeline.
Also the tag is from resources plugin. So change it as per the asset-pipeline

Related

PNG files not found in ASAR

I have an Electron (1.7.10) application that is reporting it can't find 5 of 7 PNG files in my ASAR. All 7 PNGs are in the same folder, and 2 of them are displayed on screen fine. The other 5 report net::ERR_FILE_NOT_FOUND.
All src attributes for the img tags are dynamically generated and use relative paths (assets/images/MyImage.png). If I extract the ASAR, I can see the files in there, in the correct folder (as referenced by the src attribute).
If I use the console to set the location of my browser to one of the images (document.location.href = "file:///path/to/app.asar/dist/assets/images/MyImage.png") I get the same results - 2 of 7 show OK.
Before packaging my application (with electron-builder), all images show correctly.
Let me guess, you are building a react SPA using react-router, and BrowserRouter?
If so, use HashRouter instead. Electron does not work with SPA's route by default, because a SPA route changes, but the resource path is always relative to index.html.
I haven't evaluated the other answers, but for my particular case, an extremely solution worked. I don't believe this is well documented, so it might be fairly common for people to still encounter this issue. For my particulars, the relevant problem and solution were identified here.
To address, add <base href='./' /> to the index.html (or whatever your starting html file is that hosts your SPA). This is a complete example of mine:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<base href="./" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<meta
http-equiv="Content-Security-Policy"
content="script-src 'Self' 'unsafe-inline';"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
const path = require('path');
path.join(__dirname, 'assets/images/MyImage.png');

I can't serve css files ASP MVC

I'm using dotnetcore and ASP MVC.
The problem is that I don't know how to serve correctly my css and images files.
Here you can see the file structure:
Here is the Shared layout's head.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Galeria de comics">
<title>#ViewBag.Title - Galeria de comics</title>
<link rel="stylesheet" href="~/wwwroot/css/normalize.css">
<link rel="stylesheet" href="~/wwwroot/css/main.css">
</head>
<body>
<header class="main-header"></header>
#RenderBody()
</body>
</html>
I'm called this layout in a View.
#{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Libro comic detalle";
}
What's the problem?
The problem is that the CSS files aren't serve so I can't see the styles.
Any solition?
Seems I miss the href attribute's content. You should skip the wwwroot folder since the static files are served as http://app/css/cssFileName. Example: http://yoursite.com/css/main.css, same with images and js files.
Here I fixed the problem:
<link rel="stylesheet" href="~/css/normalize.css">
<link rel="stylesheet" href="~/css/main.css">
If you want to know more visit this link

Resource not found Error and what about resources plugin

I am using grails for almost a year. Since now when I wanna link a css or js file in a gsp. I did the following:
I created a new file (eg the resources file) under web-app folder and I put there all my files of folders (eg when importing bootstrap I had a parent folder bootstrap under resources and under bootstrap there were css, img and js folders with their files).
Then, to import a css file I did the following (here is documentation for this):
<link rel="stylesheet" href="${resource(dir:
'resources/bootstrap/css', file: 'bootstrap.min.css')}"
type="text/css">
<script src="${resource(dir: 'resources/bootstrap/js', file:
'bootstrap.min.js')}"></script>
This worked great, but when I tried to create a new Project in grails 2.2.4 I had a Resource not found Error (404 to browser and the following to console).
ERROR resource.ResourceMeta - Resource not found: /resources/bootstrap/css/bootstrap.min.css
ERROR resource.ResourceMeta - Resource not found: /resources/bootstrap/js/bootstrap.min.js
ERROR resource.ResourceMeta - Resource not found: /resources/bootstrap/css/bootstrap.min.css
ERROR resource.ResourceMeta - Resource not found: /resources/bootstrap/js/bootstrap.min.js
As I realized these Errors in console were once from the resources function and once from the GET that client(browser) requested.
When looking at resources plugin I see that they suggest using the js and css folders. Is that meaningful to split a tool (eg twitter bootstrap) in these two directories?
ok I believe I have a (semi) working solution:
Suppose we need to include both Twitter Bootstrap 3 and TinyMce
Under webapp directory I create the following directories:
resources/bootstrap/
resources/bootstrap/css/
resources/bootstrap/css/bootstrap.min.css
resources/bootstrap/fonts/
resources/bootstrap/fonts/glyphicons-halflings-regular.eot
resources/bootstrap/fonts/glyphicons-halflings-regular.svg
resources/bootstrap/fonts/glyphicons-halflings-regular.ttf
resources/bootstrap/fonts/glyphicons-halflings-regular.woff
resources/bootstrap/js/
resources/bootstrap/js/bootstrap.min.js
resources/jquery/
resources/jquery/jquery-2.0.3.min.js
resources/tiny_mce/
resources/tiny_mce/langs/ /*many files here*/
resources/tiny_mce/plugins/ /*many files here*/
resources/tiny_mce/themes/ /*many files here*/
resources/tiny_mce/utils/ /*many files here*/
resources/tiny_mce/tiny_mce_popup.js
resources/tiny_mce/tiny_mce_src.js
resources/tiny_mce/tiny_mce.js
Then I declare my resources in ApplicationResources.groovy
modules = {
application {
resource url:'js/application.js'
}
jquery {
resource url:'resources/jquery/jquery-2.0.3.min.js'
}
bootstrap {
dependsOn 'jquery'
resource url:'resources/bootstrap/css/bootstrap.min.css'
resource url:'resources/bootstrap/js/bootstrap.min.js'
}
tinymce {
resource url:'resources/tiny_mce/tiny_mce.js'
}
}
And in Config.groovy
grails.resources.adhoc.patterns = ['/images/*', '/css/*', '/js/*', '/plugins/*'] /*no changes here*/
grails.resources.adhoc.excludes = ['/**/langs/**/*.*', '/**/themes/**/*.*'] /*to permit some Ajax calls from tiny_mce.js to relevant resources*/
grails.resources.debug=true
/*
this is why I call my solution SEMI working.
If set grails.resources.debug to false, TinyMce is NOT working because the above excludes are not active, and I receive 404 errors
*/
Then, in main.gsp
<!DOCTYPE html>
<head>
<g:javascript library="application"/>
<g:javascript library="bootstrap"/>
<g:javascript library="tinymce"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title><g:layoutTitle default="Grails"/></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="${resource(dir: 'images', file: 'favicon.ico')}" type="image/x-icon">
<link rel="apple-touch-icon" href="${resource(dir: 'images', file: 'apple-touch-icon.png')}">
<link rel="apple-touch-icon" sizes="114x114" href="${resource(dir: 'images', file: 'apple-touch-icon-retina.png')}">
<link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}" type="text/css">
<link rel="stylesheet" href="${resource(dir: 'css', file: 'mobile.css')}" type="text/css">
<r:layoutResources />
<g:layoutHead/>
</head>
<body>
<div id="grailsLogo" role="banner"><img src="${resource(dir: 'images', file: 'grails_logo.png')}" alt="Grails"/></div>
<g:layoutBody/>
<div class="footer" role="contentinfo"></div>
<div id="spinner" class="spinner" style="display:none;"><g:message code="spinner.alt" default="Loading…"/></div>
<r:layoutResources />
</body>
</html>
And in index.gsp
<head>
...
<script type="text/javascript">
$(function() {
tinymce.init({selector:'textarea'});
});
</script>
</head>
<body>
...
<h1>Welcome to Grails</h1>
check bootstrap - start
<span class="glyphicon glyphicon-search"></span>
<button type="button" class="btn btn-default btn-lg">
<span class="glyphicon glyphicon-star"></span> Star
</button>
check bootstrap - stop
<textarea>Your content here.</textarea>
...
</body>
Using the above, I have fully operational JQuery, Bootstrap3 and TinyMCE
But if a I set in Config.groovy
grails.resources.debug=true
I am receiving 404-errors related to the grails.resources.adhoc.excludes resources that TinyMce dynamically fetches after page load.
Any clues? I am really close to find the solution so I will glad to get your input
This test project can be downloaded from here: https://docs.google.com/file/d/0B8epX7R4j7jeaVh5OTFiQlV4V0U/edit?usp=sharing
Another answer to the question is the following:
Clean your project
Change 'BuildConfig.groovy' and use a newer version of resources plugin
Do a refresh dependencies to your project
and everything is working great now
I had the same issue, I don't know exactly what setup you have but I have this at the top of my mail.gsp-page:
<link rel="stylesheet" href="${resource(dir: 'css', file: 'bootstrap.css')}" type="text/css">
(Inside the -tag)
If you need to import .js-files this is what works for me:
<script src="${resource(dir: 'js', file: 'bootstrap.js')}"></script>
This is at the very bottom om the page inside the -tag.
I'm using Grails 2.1.1.
The /css and /js directories are part of the default "adhoc resources" patterns that the resources plugin adds to Config.groovy. If you want a different structure for your static resources, you'll either have to create a resource definition file (eg. BootstrapResources.groovy) or add your directory structure to the adhoc patterns:
// What URL patterns should be processed by the resources plugin
grails.resources.adhoc.patterns = ['/images/*', '/css/*', '/js/*', '/plugins/*', '/resources/*']
This would make everything in the /web-app/resources an adhoc resource and subject to the resource plugin's processing.
I am beginning to think that the most flexible way is to serve static content by using a proxy in front of Tomcat / Grails such as Nginx (for all the 'resources/*' URIs)and letting Grails to handle all the dynamic stuff (for the rest URIs).
After all it should be more efficient to use Nginx for serving static files than letting Tomcat / Grails do this.
But, as an afterthought, it should be pity for Resources Plugin to force you splitting the resources in three directories - and driving Grails cumbersome for simple scenarios like using Ext.js, WYSIWIG editors etc which have myriads of files to be included...

Grails Resources - cannot add r.script in layout?

I made a script that loads content based on the current request locale. Something like
class ScriptsTagLib {
static namespace = "my"
def loadLangInfo = { attrs ->
Locale locale = RequestContextUtils.getLocale(request)
r.script() {
out << '$(function(){ loadLangInfo("'+locale.language+'") });'
}
}
}
If I add this in my layout, the page throws an error:
Error evaluating expression [my.loadLangInfo()] on line [6]: Cannot
add module [-page-fragments-] which requires disposition [defer] to
this request - that disposition has already been rendered.
Error 2012-11-19 15:13:54,801 [http-bio-8080-exec-5] ERROR
[Tomcat].[localhost] - Exception Processing ErrorPage[errorCode=500,
location=/grails-errorhandler] Message:
java.io.UnsupportedEncodingException: The character encoding [null] is
not supported
But if I add this tag in my page instead of the layout, the page is rendered with success.
It's not possible to add r.script() to a layout?
EDIT: The problem is really with resources in the layout. Another example that fails is:
<g:layoutHead/>
<r:script>
$(function(){ });
</r:script>
<r:layoutResources />
EDIT 2: More info about the context
Grails 2.0.4
Resources 1.2.RC2
Also, it's a layout inside a plugin, and not one app.
Not tested in Grails 2.1, but will do that.
EDIT 3:
Just tested now, with Grails 2.1.1 and Grails 2.0.4 new fresh plugin projects, and the script tag in the layout is ignored!
./views/layout/test.gsp -> Script ignored
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><g:layoutTitle default="Insoft4 UI Plugin"/></title>
<g:layoutHead/>
<r:layoutResources />
</head>
<body>
<g:layoutBody/>
<r:script disposition="defer">
alert('layout!');
</r:script>
<r:layoutResources />
</body>
</html>
./views/index.gsp -> Script OK
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Teste</title>
<meta name="layout" content="teste" />
<r:script disposition="defer">
alert('index!');
</r:script>
<r:layoutResources />
</head>
<body>
<h1>Testing this index!</h1>
<r:layoutResources />
</body>
</html>
I found out that the problem occurs when you have declared <r:layoutResources /> in both, layout and page and you try to add a script in the layout.
To correct I removed the layoutResources from every view, leaving just in the layout.
Try to add tag before the last r:layoutResources on the layout.

How do I prevent grails' default main.css being linked on a specific page

I have a simple web-app that I'm throwing together.
By & large, the default grails main.css is fine for all the scaffolded pages.
However, I want to supress this and use different, in-line css for the landing page.
How do I configure grails not to link main.css on a specific page?
The html is extremely simple, and contains no grails specific markup:
<!doctype html>
<html>
<head>
<meta name="layout" content="main" />
<title>My landing page</title>
<style type="text/css" media="screen">
body
{
background-color: #fff;
}
img {
display: block;
margin: auto;
}
</style>
</head>
<body>
<img alt="Welcome!"
src="${resource(dir:'images',file:'Landing.png') }">
</body>
</html>
Also -- is main.css linked purely out of convention, or is there some configuration lurking somewhere I haven't spotted? (I've done a search but couldn't find it anywhere).
Can someone please reference where in the docs it talks about these conventions?
main.css is included in your landing page because you have specified that your landing page is based on the main layout
<meta name="layout" content="main" />
this layout is defined by grails-app/views/layouts/main.gsp and includes the main.css, most likely with a tag like this in the <head> of the page:
<link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}" type="text/css">
If you remove:
<meta name="layout" content="main" />
your landing page will no longer be based on the main layout, so it will not include anything defined therein (e.g. main.css).
However, rather than removing the layout completely just to prevent main.css from being included, it may be simpler to just override the CSS rules that you want to cusomise on the layout page by including custom rules in a <style> block in the <head> of the landing page
<style type="text/css">
body {
/* styles in here override styles from main.css */
}
</style>
Take a look at the resources plugin in grails 2.0.x. You can define Modules comprising of specific javascript and CSS files which will be compressed, optimized for the web. In the page of your choice, you can include the module you want. In your case, you could add a case like this in your main.gsp
<g:if test="${controllerName == "landing"}">
<link rel="stylesheet" href="${resource(dir: 'css', file: 'custom.css')}"/>
</g:if>
<g:else>
<link rel="stylesheet" href="${resource(dir: 'css', file: 'main.css')}"/>
</g:else>

Resources