I need to access a local JSON file. Since Grails 2.4 implements the AssetPipeline plugin by default, I saved my local JSON file at:
/grails-app/assets/javascript/vendor/me/json/local.json
Now what I need is to generate a URL to this JSON file, to be used as a function parameter on my JavaScript's $.getJSON() . I've tried using:
var URL.local = ""${ raw(asset.assetPath(src: "local.json")) }";
but it generates an invalid link:
console.log(URL.local);
// prints /project/assets/local.json
// instead of /project/assets/vendor/me/json/local.json
I also encountered the same scenario with images that are handled by AssetPipeline1.9.9— that are supposed to be inserted dynamically on the page. How can I generate the URL pointing this resource? I know, I can always provide a static String for the URL, but it seems there would be a more proper solution.
EDIT
I was asked if I could move the local JSON file directly under the assets/javascript root directory instead of placing it under a subdirectory to for an easier solution. I prefer not to, for organization purposes.
Have you tried asset.assetPath(src: "/me/json/local.json")
The assets plugin looks in all of the immediate children of assets/. Your local.json file would need to be placed in /project/assets/foo/ for your current code to pick it up.
Check out the relevant documentation here which contains an example.
The first level deep within the assets folder is simply used for organization purposes and can contain folders of any name you wish. File types also don't need to be in any specific folder. These folders are omitted from the URL mappings and relative path calculations.
Related
Is it possible somehow to do a general configuration for Eleventy so that 'my_file.html' in the input folder ends up just as 'my_file.html' in the _site folder, not '/my_file/index.html'?
I know I can do it on a file by file basis with permalinks. But I'd like it configured for the site as a whole, if possible.
Unfortunately, since this behavior isn't encouraged, there isn't a simple configuration option to disable the directory output.
However, since permalink is part of the data cascade, you can set a global default, and in combination with the filePathStem computed data, you can set the output to be .html files.
To set a permalink using a global data file, add a permalink.js file to your global _data directory.
// _data/permalink.js
module.exports = '/{{ page.filePathStem }}.html'
There is also a config global data option coming soon to v1.0.0. I am not sure if it will handle the {{ page.filePathStep }} preprocessing, but if it does, that could be an option too, especially since it will keep config-related things inside the config file.
Yes, you can control where Eleventy writes things out by specifying a permalink value in the front matter. This is covered here: https://www.11ty.dev/docs/permalinks/#remapping-output-(permalink)
An example would be:
---
permalink: "/my_file.html"
---
I'm sharing a configuration yml file client side, that I need to also load on the server side, I've placed it inside app/assets/javascripts/configuration.yml
I can use #{asset_path 'configuration.yml'} inside a view to get the path, but I can't inside a controller. I could access directly using "#{Rails.root}/app/assets/javascripts/configuration.yml" but when deploying the filename gets the digest string appended.
How can I get the same path from a controller?
ActionController::Base.helpers.asset_path("configuration.yml")
Might also be good to put configuration.yml in a different folder to separate javascript from non-javascript files.
We're trying to pull files and folders from the locker, but the command (/d2l/api/le/(D2LVERSION: version)/locker/myLocker/(string: path)) doesn't like spaces in the file or folder name. It returns either Bad Request or Invalid Token depending on how we attempt to handle the spaces on our end (i.e. string replace with %20).
How would we retrieve files/folders with spaces in the name?
I can think of some possible problems you're encountering.
When you provide the API path to your D2LUserContext object, you need to pass in only the API path, with internal spaces, not escaped characters. So, a proper route to a file named test file name might look like this:
/d2l/api/le/1.0/locker/myLocker/firstFolderBelowRoot/test file name
to create the authenticated URL for this, you'd invoke
yourD2LUserContext.createAuthenticatedUri('/d2l/api/le/1.0/locker/myLocker/firstFolderBelowRoot/test file name', 'GET')
That would fashion an authenticated URL you can use to fetch that file named test file name from your locker. To fetch its containing folder:
yourD2LUserContext.createAuthenticatedUri('/d2l/api/le/1.0/locker/myLocker/firstFolderBelowRoot/', 'GET')
Note that when you want to identify a folder in the locker, the path parameter must end with a trailing slash. (If you're trying to fetch a folder, and you don't have the trailing slash, that might be a source of your issue.)
Once you have that URL, you'll need to use some sort of HTTP library to actually make the call. Our internal PHP devs have recommended using HttpRequest rather than cURL with PHP. Most notably, the URL you should make the call with should preserve the space in the file or folder name in the path component of the URL.
When I test against a 9.4.1 instance using the Python client to do fetches/puts from the locker, or to generate URLs using the user context object and then feeding those URLs into a browser, things seem to work fine. Testing against a 10.0.0 test instance using the Python client also seems to be working.
I'm using JSFL to writing some script, I need parse json string from some config files, so I need the JSFL can parse json string, but JSFL seems can't do this. then I thinks to include some json lib, like json.js, to JSFL file.
Way can I include the json.js file to my JSFL file?
Sorry for my english.
The absolute bare minimum would be:
// #include Config._jsfl
var scriptPath = FLfile.uriToPlatformPath(fl.scriptURI);
var scriptPathEnd = scriptPath.lastIndexOf("\\");
scriptPath = scriptPath.slice(0, scriptPathEnd + 1);
fl.runScript(FLfile.platformPathToURI(scriptPath + "Config._jsfl")); /*jsl:import Config._jsfl*/
This is more or less copied from my code, JSL tags included. I make the extensions on any libraries to be ._jsfl so that if it's in Flash's Commands folder, they don't show up in the menu.
I wrote a set of static classes (a Logging system, URI conversions, array utility functions) and wrote a global include function using them to automatically convert a relative path to an absolute URI based upon the running scripts location so that I could just say include("file._jsfl"); to simplify my scripts. HOWEVER all my scripts have to do that first include as shown above to gain the include function. Since my include function relies on a handful of static classes, I've not pasted it here.
Edit: spelling error.
If the library is local, you can store it in a subfolder of your Flash config path, i.e.
C:\Users\username\AppData\Local\Adobe\Flash CS6\language\Configuration\jslibs
Then, it is quite easy to include it in a single line:
fl.runScript(fl.configURI + "jslibs/file.js");
In my Grails app, I have a dir web-app/images/carousel/slides that contains files such as:
foo.png
foo.thumbnail.png
bar.png
bar.thumbnail.png
My app is using the resources Grails plugin, and the main images are loaded in a GSP using one of it's tags:
<r:img file="carousel/slides/foo.png"/>
which generates:
<img src="/myapp/static/images/carousel/slides/foo.png">
I attempt to load the thumbnail images from JavaScript by constucting a path such as /myapp/static/images/carousel/slides/foo.thumbnail.png. But when I attempt to display one of these images, I get a 404.
Similarly, if enter the following path in the browser's address bar
http://localhost:8080/myapp/static/images/carousel/slides/foo.png
the image displays correctly, but if I enter
http://localhost:8080/myapp/static/images/carousel/slides/foo.thumbnail.png
I get a 404. Why are my thumbnail images not available at the same path at runtime, given that they're in the same source directory? I suspect the answer has something to do with the fact that the main images are loaded using the resources framework whereas I attempt to load the thumbnails from JavaScript.
You mostly answered your own question: if you don't reference the images using resources in some way, then they don't get processed.
Your best bet is to create a resources module that contains a list of all the images. The add this resource to the page.
// grails-app/conf/CarouselResource.groovy
modules = {
carousel {
resource url:'/images/carousel/foo.jpg'
resource url:'/images/carousel/foo.thumbnail.jpg'
...
}
}
then in your GSP
<r:require module="carousel"/>
Now, the module description is a DSL, so you might be able to use some sort of file loop to automatically add all the files, but I'm not 100% sure how. You also might try something like '/images/carousel/**', but the docs don't say if that would work or not.
Also, I should mention, if you use any of the caching-based resources plugins, this won't help. You will then need to manually call r.img() and set it within your JavaScript, something like this (if it works):
<r:script>
var images = [
'${r.img(...)}'
];
</r:script>
This is because the URLs generated using, for example, cached-resources, are often hashes of the file content to allow for long-term caching. They usually are only indirectly related to the original filename.
Update based on comment below:
To load a common JS remotely, but include the images, you could do something like this. Realize, I don't know your carousel code, and you will almost certainly have to modify the carousel library to handle these changes.
<r:script>
window.carouselImages = [
{
image: '${r.external(url:'images/carousel/image1.jpg'}.encodeAsJavaScript();}',
thumbnail: '${r.external(url:'images/carousel/image1.thumbnail.jpg'}.encodeAsJavaScript();}'
},
...
];
</r:script>
<r:resource url="js/carousel.js"/>
Then in carousel.js you reference window.carouselImages to get your array of images. It also should be possible it flip the order, and use some method within carousel.js to add images, like this:
<r:script>
carousel.addImage('${r.external(url:'images/carousel/image1.jpg'}.encodeAsJavaScript();}', '${r.external(url:'images/carousel/image1.thumbnail.jpg'}.encodeAsJavaScript();}');
...
</r:script>
You can improve this by looping over the file list instead of encoding each image explicitly (and example was given in the JIRA I posted below).
Finally, if you aren't going to use any of the caching or file manipulation plugins (so the files always end up at the same URL), you could just simply loop over the files from within the controller or a service method, calling r.img() on each one. This would ensure that they are copied to the static directory. The return value from r.img() can be ignored.
You can use HTML5's data-* Attribute
<element data-*="somevalue">
Here is an example if your image is located at /grails-app/assets/images:
In page (i.e. index.gsp) you have to add the following:
And from the javascript all you have to do is:
<script>
var calImg = document.getElementById('calendar-icon').getAttribute('data-calendaricon');
</script>
Pretty straightforward, moreover it is a clean approach :)