asset_path rails helper using only the dns of assethost given - css

Hi following is the how the asset-host is defined.
config.action_controller.asset_host = 'cdn.com/site1'
Scss file example:
.home-ntf-headline.ntf-img {
background-image: url(asset_path('ntf-logo.png'));
}
The actual url frame for above Scss is cdn.com/assets/ntf-logo-b1a1fa585e8393a621c8ac16d515d96560d469afd8b9aadb36dc290acc4e9c42.png.
But what i actually expects
cdn.com/site1/assets/ntf-logo-b1a1fa585e8393a621c8ac16d515d96560d469afd8b9aadb36dc290acc4e9c42.png.
The static assets in request life cycle(i.e css, js, images) are framed correctly.

The "host" here is limited to the top level host, rather than a prefix to the full asset path. If you specify anything after cdn.com then it will be stripped before being applied as the asset_host in Actionview Helpers.
If you're looking to have multiple sites on the same CDN then you're going to have to look at subdomains rather than paths, or some kind of per-site unique naming convention for your assets (I'd advise against that).

Related

How to keep relative paths in CSS for images and fonts in Laravel Mix

When Laravel Webpack/Mix executes and converts SASS to CSS, it changes the relative paths like url('../images/background.png'); to absolute paths like url('/images/background.png');.
Is it possible that the paths are not updated and kept as relative?
The reason is that the deployment could be in different folders on different servers so that the relative paths will work on all folder structures. E.g., it will work on http://www.example.com/ as well as http://www.example.com/subfolder/. But if an absolute path is used, then in the case of the subfolder, the CSS will not find the images and fonts.
Is there some other best practice to handle this situation?
From the docs:
By default, Laravel Mix and Webpack will find example.png, copy it to your public/images folder, and then rewrite the url() within your generated stylesheet. As such, your compiled CSS will be.
As useful as this feature may be, it's possible that your existing folder structure is already configured in a way you like. If this is the case, you may disable url() rewriting like so:
mix.sass('resources/assets/app/app.scss', 'public/css')
.options({
processCssUrls: false
});
https://laravel.com/docs/5.5/mix#working-with-stylesheets

Fixing jsDelivr "multiple files" approach that breaks CSS' image URI's

jsDelivr ( http://jsdelivr.com ) has Multiple File mode:
https://github.com/jsdelivr/jsdelivr#load-multiple-files-with-single-http-request
Problem is, libraries with CSS such as Gritter and Font Awesome use images in their interface components.
This leads to 404 errors when doing something like this:
//cdn.jsdelivr.net/g/jquery#2.1.0,bootstrap#3.1.1,summernote#0.5.0,mousewheel#3.1.6,jquery.timeago#1.3.0,jquery.gritter#1.7.4,jquery.unveiljs#1.0,jquery.waypoints#2.0.2,bootstrap.tagsinput#0.3.9,bootstrap.datepicker-fork#1.3.0,jquery.jqote2#0.9.8,portal#1.1.1
How can we use multiple libraries off the one CDN pageload, but change the paths CSS files reference to use the appropriate jsDeliver.net URI?
Is this a job for post-processing CSS in-browser, by jQuery or pure JavaScript, or is one forever doomed to one CDN pageload per CSS file referencing images, plus one remaining pageload for the CDN served CSS without image references?
Yes, unfortunately /g/ does not work with files that contain relative paths.
You can load this kind of files individually and use /g/ for the rest of them normally.

app-relative paths in url() in dotless

I have a bunch of .less files that contain image backgrounds:
.header {
background-image:url(~/images/some_image.png);
}
In debug mode, these .less files are served directly, but in release mode they're served as a part of a bundle. The path depths between the bundle URL and the individual file URLs are not always the same, so I can't just use relative URLs.
The default options for the dotless nuget package do not parse app-relative paths. Is there an option to make it do the right thing?
Edit: There is a potentially fatal flaw in this approach. The apppath.less file has to be in a certain location which isn't necessarily known, which creates a chicken-egg scenario. Still, it may be helpful to some extent.
One approach is to use an #import rule that declares a variable containing the app path like this:
#import "apppath.less"
If you can't use a .less extension, you should be able to use (less) to force .less interpretation.
#import (less) "apppath.ashx"
Instead of being a static file, apppath.less could simply use Response.Write to echo the application path, producing an output like this:
#app-path: "http://yourserver/app/path";
Then you'd use it like this:
.header {
background-image:url("#{app-path}/images/some_image.png");
}

Checking if a css loads an external file

I am building a tool to minify and compile CSS files on-demand. The files can be in different folders, and I need them to be called from their original folder if they are referring to an external file (image, other css, font maybe?).
I wonder which strings I should look for. I only see url( and #import, but am pretty sure I am missing some.
I can think of proprietary CSS: behavior which loads .htc (.js on some servers) for that browser. Also exists as -ms-behavior.
EDIT: oops, behavior will use url() too, not behavior() as I previously wrote... My mistake. Ex:
.ie67 * {
behavior: url('htc/boxsizing.htc');
}
I don't think that filter / -ms-filter can load an external resource; it'll rather apply to images and such (somebody correct me if I'm wrong).
In CSS2.1, external resources are URIs so except #import (that must appear before anything else), I think your list is complete.

Can you reference images from css without using relative paths?

I'd like to create a div with a background image css:
#mydiv {
background-image:url('/public/images/foo.png');
background-repeat: repeat-x;
}
Now, I can't use routes in css, so as a result I have to use a relative path, or my app will break if installed at a non-root path.
Is there a way around this? Something like
background-image:url('#{publicFolder}/images/foo.png');
I did find this thread from a year ago that claims it's impossible. Is this still the case?
Edit: I know I can inline the css in the page, that's not really an acceptable solution, but rather a work around.
Since the play framework compiles all the files in /public, I used the following statement in the css to acces background images.
background: url("/assets/images/my-image-background.jpg");
It worked for me so far, not sure if it's a good practice though! Hope it can be of help.
Cheers.
The path always goes from your stylesheet. So why don't you use relative paths?
Example, your css is in /public/css/, so your path in your css file has to be ../images. That's it.
But maybe less.css has something similiar you're looking for.
The way around /is/ possible.
The problem is that CSS files are static, so Play! does not do anything on them - except serving them to the clients.
Just make your css files into views, write a generic controller that takes the filename as a parameter and they will be served as Play! Templates.
something in the lines of (beware: PSEUDOCODE!):
ROUTE:
get /css/{filename} Application.getCSS
CONTROLLER
class public void getCSS(filename)
{
renderTemplate(filename);
}
Then in your css you can use any groovy template feature you want.
The installation path is available as http.path in the conf
This will be very inefficient though, so you will have to add nginx or similar frontend to do some caching and set high expiration values for those files.
I'm not sure if it's worth doing it just to avoid relative paths!
I definitely think that the relative path is better suited generic deployment, and you are more likely to break things with this dynamic absolute approach.
A better overall deployment strategy
Anothe important point is that if you do like absolute URLs, there's no problem.
I actually do too.
But when I deploy my web applications (be them play!, django, pure wsgi, or whatever else) I always put a web frontend.
Usually nginx.
This means that your play framework will be an upstream server, and you can do everything you want with the URLs on your :80 port - and manage several services with subdomains or subfolders...
but when you access your play application on its own port(s) everything will be absolute.
Finally, if you were deploying Play! as a war I would have the feeling you have chosen the wrong framework or the wrong deployment pattern! But then your jboss or whatever other application webserver will do some magic on the subfolders...
take a look at conf/routes file.
in it you will find the following something like
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path="/public", file)
which means in order to access resources in the public folder,
you would use /assets in your url.
so in your css you do
url(/assets/images/myimage.png)
and it will work.

Resources