How to serve images from subfolders in Javascript via Asset pipeline - javascript

So I have a folder in my assets/javascripts folder that runs an image slideshow called galleryview. Inside this folder is a themes directory holding images for my "next" and "previous" buttons thus...
assets/javascripts/galleryview/themes/
now the javascript running this, links to these images via this....
//Determine path between current page and filmstrip images
//Scan script tags and look for path to GalleryView plugin
$('script').each(function(i){
var s = $(this);
if(s.attr('src') && s.attr('src').match(/jquery\.galleryview/)){
img_path = s.attr('src').split('jquery.galleryview')[0]+'themes/';
}
});
HOWEVER, I'm using this in a Rails app now, so I need to point this img_path line to
assets/images/
so what should my imag_path look like now?
img_path = ?
Here is the entire javascript file code on jsfiddle....copy and past this into an editor and
the area I'm interested in is around line 389.
http://jsfiddle.net/thefonso/Sqmxa/

Not sure this code will exactly work, but I think you can use the image_path helper to get you close. Something like:
img_path = <%= image_path 'images/'%>;
Put this inside a .js.erb file and the ERB shown above should be parsed and output the string "/assets/images/", assigning img_path to the value "/assets/themes/"
Of course, you could also just do:
img_path = "/assets/images/";
...but the upside of using the helper, I guess, is in case that the "assets" path ever changes you won't need to update a hard-coded string.

Related

ajax call not working when deployed in live domain

My ajax call is working on localhost but not when i upload the files in domain. Using ajax I am searching all jpg/png files in a folder called 'images' and showing them in my webpage. The code is -
<script>
//Use ajax to load all images (jpe?g|png|gif) from a folder to a page called Gallery
//images folder should be in the same folder as the file
var folder = "../images/";
$.ajax({
url : folder,
success: function (data) {
$(data).find("a").attr("href", function (i, val) {
if( val.match(/\.(jpe?g|png|gif)$/) ) {
// create 'img' element using JS and dynamically add image source and class
var imgSrc = document.createElement('img');
imgSrc.src= folder + val;
imgSrc.className = 'imageThumbnails';
$("#spanImage").append(imgSrc);
}
});
}
});
</script>
please change
var folder = "../images/";
to
var folder = "images/";
hope this helps.. cheers
Ok, so as you saw when you tried accessing the folder directly in your browser, your web server does not allow this, which is common on web servers. Very few people actually want visitors to be able to see a list of all files in a folder, for security reasons.
The quick and dirty way to do this would be to allow listing files in that folder, through a htaccess file, using Options +Indexes, but I strongly recommend you do not do that
Instead, I would suggest you place a file inside your images folder called index.php and have that file build you a list of files placed alongside it, in the images folder. That way you have control over which files you show and which ones you don't. The index.php file can return a simple text output, one file name per line or something like that. Then your ajax call should work as it used to.
Hope this helps!

store and access image file paths when templating (from cloudinary or other service)

I’m using gulp and nunjucks to automate some basic email templating tasks.
I have a chain of tasks which can be triggered when an image is added to the images folder e.g.:
images compressed
new image name and dimensions logged to json file
json image data then used to populate template when template task is run
So far so good.
I want to be able to define a generic image file path for each template which will then concatenate to each image name (as stored in the json file). So something like:
<img src="{{data.path}}{{data.src}}" >
If I want to nominate a distinct folder to contain the images for each template generated then cloudinary requires a mandatory unique version component to be applied in the file path. So the image path can never be consistent throughout a template.
if your public ID includes folders (elements divided by '/'), the
version component is mandatory, (but you can make it shorter. )
For example:
http://res.cloudinary.com/demo/image/upload/v1312461204/sample_email/hero_image.jpg
http://res.cloudinary.com/demo/image/upload/v1312461207/sample_email/footer_image.jpg
Same folder. Different path.
So it seems I would now need to create a script/task that can log and store each distinct file path (with its unique id generated by cloudinary) for every image any time an image is uploaded or updated and then rerun the templating process to publish them.
This just seems like quite a convoluted process so if there’s an easier approach I’d love to know?
Else if that really is the required route it would great if someone could point me to an example of the kind of script that achieves something similar.
Presumably some hosting services will not have the mandatory unique key which makes life easier. I have spent some time getting to know cloudinary and it’s a free service with a lot of scope so I guess I'm reluctant to abandon ship but open to all suggestions.
Thanks
Note that the version component (e.g., v1312461204) isn't mandatory anymore for most use-cases. The URL could indeed work without it, e.g.,:
http://res.cloudinary.com/demo/image/upload/sample_email/hero_image.jpg
Having said that, it is very recommended to include the version component in the URL in cases where you'd like to update the image with a new one while keeping the exact same public ID. In that case, if you'd access the exact same URL, you might get a CDN cached version of the image, which may be the old one.
Therefore, when you upload, you can get the version value from Cloudinary's upload response, and store it in your DB, and the next time you update your image, also update the URL with the new version value.
Alternatively, you can also ask Cloudinary to invalidate the image while uploading. Note that while including the version component "busts" the cache immediately, invalidation may take a while to propagate through the CDN. For more information:
http://cloudinary.com/documentation/image_transformations#image_versions
This is the solution I came up with. It's based on adapting the generic script I use to upload images from a folder to cloudinary and now stores the updated file paths from cloudinary and generates a json data file to publish the hosted src details to a template.
I'm sure it could be a lot better semantically so welcome any revisions offered if someone stumbles on this but it seems to do the job:
// points to the config file where we are defining file paths
var path = require('./gulp.path')();
// IMAGE HOSTING
var fs = require('fs'); // !! not installed !! Not required??
var cloudinary = require('cloudinary').v2;
var uploads = {};
var dotenv = require('dotenv');
dotenv.load();
// Finds the images in a specific folder and retrurns an array
var read = require('fs-readdir-recursive');
// Set location of images
var imagesInFolder = read(path.images);
// The array that will be populated with image src data
var imgData = new Array();
(function uploadImages(){
// Loop through all images in folder and upload
for(var i = 0; i < imagesInFolder.length;i++){
cloudinary.uploader.upload(path.images + imagesInFolder[i], {folder: path.hosted_folder, use_filename: true, unique_filename: false, tags: 'basic_sample'}, function(err,image){
console.log();
console.log("** Public Id");
if (err){ console.warn(err);}
console.log("* Same image, uploaded with a custom public_id");
console.log("* "+image.public_id);
// Generate the category title for each image. The category is defined within the image name. It's the first part of the image name i.e. anything prior to a hyphen:
var title = image.public_id.substr(image.public_id.lastIndexOf('/') + 1).replace(/\.[^/.]+$/, "").replace(/-.*$/, "");
console.log("* "+title);
console.log("* "+image.url);
// Add the updated src for each image to the output array
imgData.push({
[title] : {"src" : image.url}
});
// Stringify data with no spacing so .replace regex can easily remove the unwanted curly braces
var imgDataJson = JSON.stringify(imgData, null, null);
// Remove the unwanted [] that wraps the json imgData array
var imgDataJson = imgDataJson.substring(1,imgDataJson.length-1);
// Delete unwanted braces "},{" replace with "," otherwise what is output is not valid json
var imgDataJson = imgDataJson.replace(/(},{)/g, ',');
var outputFilename = "images2-hosted.json"
// output the hosted image path data to a json file
// (A separate gulp task is then run to merge and update the new 'src' data into an existing image data json file)
fs.writeFile(path.image_data_src + outputFilename, imgDataJson, function(err) {
if(err) {
console.log(err);
} else {
console.log("JSON saved to " + outputFilename);
}
});
});
}
})();
A gulp task is then used to merge the newly generated json to overide the existing json data file:
// COMPILE live image hosting data
var merge = require('gulp-merge-json');
gulp.task('imageData:comp', function() {
gulp
.src('src/data/images/*.json')
.pipe(merge('src/data/images.json'))
.pipe(gulp.dest('./'))
.pipe(notify({ message: 'imageData:comp task complete' }));
});

Accessing file with JS when files are a folder deeper than domain

We have a MVC site which uses subdomains. Not in the traditional sub.domain.com but instead we are using domain.com/sub. The source files all exist in the sub folders of each sub domain because each might have some slightly different things. This causes the Dev team to have to place JS directly into the razor pages so the razor code was able to update URLs like below.
var temp = $('div').load('#Url.Content("~/Images/Excel.png")');
Unfortunately using a code like below in a separate JS file tries loading from domain.com and not domain.com/sub
var temp = $('div').load('/Content/Templates/warning.html');
Theses add on to the domains and can change with clients. Is there a way to get the domain plus sub when the files are loaded like that in the JS without needing to place the code into the razor? I'd prefer a separation of concerns because we are loading scripts sometimes which aren't even used because of it.
what I always do when in similar situations is that I create a function in the main.js or whatever name your using for your shared js file, modify the URL in the function and use the function as the initiator:
in the main.js:
var loadFile = function(selector,path){
$(selector).load('/sub'+path);
}
and then whenever and wherever you wanna load a file:
var temp = loadFile('div','/Content/Templates/warning.html');
UPDATE
you can upgrade your loadFile function to let it know if it has to load from the root of the website if needed:
var loadFile = function(selector,path,loadFromRoot){
var root=(loadFromRoot) ? '' : '/sub';
$(selector).load(root+path);
}

Failed To Load Resource Error

I am having trouble viewing 3 different background-image .jpg files through one thumbnailFilePath in javascript. The HTML and CSS coding does recognize all of the files correctly, but the background images will not load into a browser. Therefore, you can not view these images. On the other hand, the browser does recognize to see the javascript videocaption text and the play_icon.png image files correctly.
// JavaScript Document
$(document).ready(function(){
$('a.videoLink').each(function(){
var thumbnailFilePath = 'video/'+$(this).attr('videofile')+'.jpg';
var videoCaption = $(this).attr('videocaption');
$(this).css('background-image','url('+thumbnailFilePath+')');
$(this).html('<div class="caption">'+videoCaption+'</div><img src="../images/play_icon.png" class="play"/>');
});
});
Maybe your video directory is not located in the same directory like your javascript file with this code? Otherwise use a additional slash in front of "video", if it is in the root:
var thumbnailFilePath = '/video/'+$(this).attr('videofile')+'.jpg';
What's the value of the following attribute?
.attr('videofile')
Did you give attention to the file extension? (maybe result is: myvideofile.mpg.jpg)
The answer is that my .jpg files must have the identical file name as my HTML source code. The videofile="bruce_waltke" must have the same .jpg name. So my .jpg file was named bruce waltke.jpg with no underscore in-between. So the .jpg was initially saved as bruce waltke.jpg but it is now saved as bruce_waltke.jpg....So the image file was broken but its now fixed.

random images from a folder

I am trying to rewrite my code below to search a folder for all the images (they will be numbered but there maybe gaps, ie not 1.jpg,2.jpg,3.jpg but instead 1.jpg,15.jpg,60.jpg for this reason i would like to search the folder, put all the images into an array and then pick one randomly each time its looped.
Any help would be greatly appreciated.
Firstly i am currently specifying image total above the main script below:
imgWidth = 160,
imgHeight = 95,
imgTotal = 22,
total = 0,
tiles;
//create the HTML for the tiles and append that to the bg element
function makeTiles(count){
var html = '', imgNum;
while(count--){
imgNum = Math.floor(Math.random()*imgTotal + 1);
html += "<div class='tile' style='background:url(public/images/portfolio/all/"+imgNum+".jpg) 0 0 no-repeat;' ><img style='opacity:0; filter:alpha(opacity=0);' src='public/images/portfolio/all/"+imgNum+"-c.jpg' alt='' /></div>\r";
}
$bg.append(html);
}
You'll need to create a list of available images with something else than javascript, since it has no filesystem access, even though in the end, you are accessing the images via their url.
Workaround: enable some directory listing for the images, then access this page via javascript, parse the image files and construct an array out of them; but frankly, there are shorter and more robust ways to accomplish this ...
pseudocode ..
$ ls -1 *jpg > imagesfilelist.txt
$ cp imagefilelist.txt /some/publicly/accessible/folder
js/jquery ..
$.get("/some/publicly/accessible/folder/imagefilelist.txt", function(data){
alert("My image files: " + data);
});
...
javascript can not access local folders. point.
I repeat: there is no way you can "search folder" to get "array of images" in JS. You could do that part (server only!) in PHP or such server-side language and return results via AJAX.
To do what you want you need to know what the images are called. JavaScript cannot access folder directly as commented above. You would need to use a server side script to provide an array of the images for the JS to pick at random to do this.
Javascript will not be able to browse folders. What you need to do is to create an array of available images and then select a random one. You could do this using any server side technology (php, rails, java, .net ...).
The way you're trying to do it is a wrong one.But iwth a bit of tricks it could work though, but it's very wrong way to do this kind of things.
You can generate file list with php and feed it to your script. You can even create php script which will generate your script already populated with needed data but it's not the best to do this too.
So, the best ways are:
- create html with list of filenames/images(visible or invisible) by php, then manipulate it by javascript;
- create html and javascript wich will do AJAX query to php script which will return filename list(formated as JSON if you wish).
Why not upload your images to a free hosting site (like Flickr) grab the feed from your image group and select the random image from there?

Categories

Resources