grails - Recurso no encontrado Error y qué pasa con el complemento de recursos
resources (5)
Estoy usando grails durante casi un año. Desde ahora cuando quiero vincular un archivo css o js en un gsp. Hice lo siguiente:
Creé un nuevo archivo (por ejemplo, el archivo de recursos) en la carpeta de la aplicación web y coloqué todos mis archivos de carpetas (por ejemplo, al importar bootstrap, tenía un archivo de arranque de la carpeta principal en recursos y bajo bootstrap había carpetas css, img y js con sus archivos).
Luego, para importar un archivo CSS, hice lo siguiente ( aquí hay documentación para esto ):
<link rel = "stylesheet" href = "$ {resource (dir: ''resources / bootstrap / css'', archivo: ''bootstrap.min.css'')}" type = "text / css">
<script src = "$ {resource (dir: ''resources / bootstrap / js'', archivo: ''bootstrap.min.js'')}"> </ script>
Esto funcionó muy bien, pero cuando traté de crear un nuevo proyecto en Grails 2.2.4 tuve un error de recurso no encontrado (404 en el navegador y el siguiente en la consola).
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
Como me di cuenta de que estos errores en la consola fueron una vez desde la función de recursos y una vez desde el GET que solicitó el cliente (navegador).
Al mirar el plugin de recursos veo que sugieren usar las carpetas js y css. ¿Es significativo dividir una herramienta (por ejemplo, Twitter bootstrap) en estos dos directorios?
Estoy empezando a pensar que la forma más flexible es servir contenido estático utilizando un proxy frente a Tomcat / Grails como Nginx (para todos los URI ''resources / *'') y dejando que Grails maneje todo el material dinámico (para el resto de URI).
Después de todo, debería ser más eficiente usar Nginx para servir archivos estáticos que dejar que Tomcat / Grails lo haga.
Pero, como una ocurrencia tardía, debería ser una pena que el Complemento de recursos lo obligue a dividir los recursos en tres directorios, lo que hace que Grails resulte engorroso para escenarios simples como Ext.js, editores WYSIWIG, etc. que tienen miríadas de archivos para incluir ...
Los directorios /css
y /js
forman parte de los patrones de "recursos adhoc" predeterminados que el complemento de recursos agrega a Config.groovy
. Si desea una estructura diferente para sus recursos estáticos, tendrá que crear un archivo de definición de recursos (por ejemplo, BootstrapResources.groovy
) o agregar su estructura de directorios a los patrones adhoc:
// What URL patterns should be processed by the resources plugin
grails.resources.adhoc.patterns = [''/images/*'', ''/css/*'', ''/js/*'', ''/plugins/*'', ''/resources/*'']
Esto haría que todo en /web-app/resources
un recurso ad hoc y esté sujeto al procesamiento del plugin de recursos.
Tuve el mismo problema, no sé exactamente qué configuración tiene, pero tengo esto en la parte superior de mi mail.gsp-page:
<link rel="stylesheet" href="${resource(dir: ''css'', file: ''bootstrap.css'')}" type="text/css">
(Dentro de la etiqueta)
Si necesita importar archivos .js, esto es lo que funciona para mí:
<script src="${resource(dir: ''js'', file: ''bootstrap.js'')}"></script>
Esto está en la parte inferior de la página dentro de la etiqueta.
Estoy usando Grails 2.1.1.
ok, creo que tengo una solución (semi) de trabajo:
Supongamos que necesitamos incluir tanto Twitter Bootstrap 3 como TinyMce
En el directorio de webapp, creo los siguientes directorios:
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
Luego declaro mis recursos en 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''
}
}
Y en 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
*/
Luego, en 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"><a href="http://grails.org"><img src="${resource(dir: ''images'', file: ''grails_logo.png'')}" alt="Grails"/></a></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>
Y en 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>
Usando lo anterior, tengo JQuery, Bootstrap3 y TinyMCE completamente operativos, pero si configuro un en Config.groovy
grails.resources.debug=true
Recibo 404 errores relacionados con los recursos de grails.resources.adhoc.excludes que TinyMce obtiene dinámicamente después de la carga de la página.
¿Alguna pista? Estoy muy cerca de encontrar la solución, así que me complacerá recibir su opinión. Este proyecto de prueba se puede descargar desde aquí: https://docs.google.com/file/d/0B8epX7R4j7jeaVh5OTFiQlV4V0U/edit?usp=sharing
Otra respuesta a la pregunta es la siguiente:
- Limpia tu proyecto
- Cambie ''BuildConfig.groovy'' y use una versión más nueva del complemento de recursos
- Realice una actualización de las dependencias de su proyecto
y todo está funcionando bien ahora