How to access assets with webpacker gem - ruby-on-rails

Could you explain me how to access assets from webpacker gem within vue.js components? For example - how to create div with background image. I've tried use /app/assets/images and /app/javascripts/assets folders but images is only available in template section, but not in style section :(
in my case
<template>
<div id="home">
<div id="intro">
<img src="assets/cover-image-medium.png" alt="">
</div>
</div>
</template>
works fine, but
<style scoped>
#intro {
height: 200px;
background: url("assets/cover-image-medium.png");
}
</style>
not working :(
Whats wrong?

New Rails' webpacker stuff is pretty raw, so that's the configuration that works for me:
config/webpacker.yml (for webpacker 3):
resolved_paths: ['app/javascript/images', 'app/javascript/src']
compile: false
# ...
JS files:
/app
/javascript
/packs
# only entry point files
vue_application.js
/src
some_component.vue
/images
logo.svg
in component:
<script>
import 'images/logo.svg'
</script>
in template:
<img src='~images/logo.svg' />
point the tilde here - it means that the image is a module dependency
in CSS:
<style lang='sass'>
#app
background: url('../images/logo.svg')
</style>
For some reason tilde does not work here, so relative path is used.

If I understand your question correctly, you will have to find the webpack.base.conf.js file inside your build folder, then find the code that looks like this:
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'#': resolve('src')
}
}
Then add the following line to the alias object: 'assets': resolve('src/assets/'), which will work for the assets folder being right below the src folder. You can also change the key string from assets to whatever alias name you desire.
EDIT:
I forgot to mention, to access aliases in style code, you have to prefix it with a ~ (telda) so that assets becomes ~assets.

Since this is tagged with Vue.js I will answer for that. None of the other answers worked with Vue 2.x.
For Attributes
A webpacker require statement returns the full URL of the required asset (resolved based on your resolved_paths inside webpacker.yml). Based on that, you can do something like this:
<img :src="require('images/what-a-pain.png')" alt="Finally working" />
Please note the colon causing the src attribute to be bound to the result of the javascript expression.
You can also use ID anchors by appending them, for example with SVG:
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<use :href="require('images/icons.svg') + '#copy'" />
</svg>
Vue templates are generally pre-compiled to javascript equivalents, so a require statement is needed to pull the assets in at compile time, not runtime.
For CSS urls, scoped or not
Simply use a tilde ~ and a path. The path must be relative to either the file including it or the resolved_paths from webpacker.yml.
.relative-pathed {
background: url(~../../../assets/images/quitethepath.svg) center center no-repeat;
}
.works-after-editing-webpackeryml {
background: url(~images/quitethepath.svg) center center no-repeat;
}
For this usage there is no need to require() the asset.
Please note: there is a difference in paths between development and production, especially if Sprockets is also used. Simply doing src="/assets/image.png" will sometimes work in developement, but not production.

You can try
background: url("/assets/cover-image-medium.png");
Instead of
background: url("assets/cover-image-medium.png");

If you have installed sass-rails gem, try this:
<style scoped>
#intro {
height: 200px;
background: image-url("cover-image-medium.png");
}
</style>

Related

Encore webpack or assets generating wrong path to image in symfony 4

I am trying to learn to use encore webpack.
Well, following this guideEncore + webpack + bootstrap sass and this guide Symfony 4+ enconre + Bootstrap 4 I got symfony to use the scss and js assets I use.
But the problem is when I insert an image in my scss code (for a bg) the relative url I see in the browser is wrongly generated.
Webpack is generating the image here:
public\build\images\2.f26e9a05.jpg
But the url in the browser ends up like this:
/public/build/build/images/2.f26e9a05.jpg
(if I delete the second "build/" the image loads like it should)
this is my folder estructure:
assets:
css:
app.scss
js:
app.js
public:
images:
2.jpg
app.scss:
#import '~bootstrap/scss/bootstrap';
...
.parallax {
background-image: url("images/2.jpg");
}
Webpack.config.js:
var Encore = require('#symfony/webpack-encore');
Encore
// the project directory where compiled assets will be stored
.setOutputPath('public/build/')
// the public path used by the web server to access the previous directory
.setPublicPath('build')
// the public path you will use in Symfony's asset() function - e.g. asset('build/some_file.js')
.setManifestKeyPrefix('build/')
.cleanupOutputBeforeBuild()
.enableSourceMaps(!Encore.isProduction())
// the following line enables hashed filenames (e.g. app.abc123.css)
//.enableVersioning(Encore.isProduction())
// uncomment to define the assets of the project
.addEntry('app', './assets/js/app.js')
//.addStyleEntry('css/app', './assets/css/app.scss')
// uncomment if you use TypeScript
//.enableTypeScriptLoader()
// uncomment if you use Sass/SCSS files
.enableSassLoader()
// uncomment for legacy applications that require $/jQuery as a global variable
.autoProvidejQuery()
;
module.exports = Encore.getWebpackConfig();
index.html.twig:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}100Monos{% endblock %}</title>
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('build/app.css') }}">
{% endblock %}
</head>
<body>
<div class="container">
{% block body %}
<div id="Nosotros" class="pantalla d-flex align-items-center parallax">
<div class="contenido">
<h1>100Monos</h1>
<h3>Nuestra Web es mala porque pasamos todo el tiempo haciendo la suya</h3>
<img src="{{ asset('images/1.jpg') }}">
</div>
</div>
{% endblock %}
{% block javascripts %}
<script src="{{ asset('build/app.js') }}"></script>
{% endblock %}
</div>
</body>
</html>
I am responding to this rather old question, because I assume some things have changed in the meantime concerning yarn watch and the setting of the public path:
If I do a:
.setPublicPath('./')
yarn watch feels offended, and shows a:
WARNING The value passed to setPublicPath() should *usually* start with "/" or be a full URL (http://...). If you're not sure, then you should probably change your public path and make this message disappear..
So I think the way this is meant to be is more like this:
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath('/public/build')
// only needed for CDN's or sub-directory deploy
.setManifestKeyPrefix('public/build/')
So the public path should still be absolute while the "manifest prefix" takes care of the set up as a subdirectory.
Information on this can be found here:
webpack-encore-readme
webpack-encore-issue-13
Just added this for correctness, as I stumbled over it and others might as well...
I resolved it at the end, after testing many things. There was 2 problem I kept repeating.
First, the path was generated in a not relative way, solve it changing webpack with this:
.setPublicPath('./')
But then the scss didn't load, what happen? Well, the prefix was the problem, because when you put the prefix in the asset function it takes the prefix and change it for the public path... so I changed the prefix for
.setManifestKeyPrefix('webpack/')
(something random really)

Bundling Styles doesn't work, but straight Link tag works

In my _Layout page, following works:
<link rel="stylesheet" href="#Url.Content("~/Kendo/Content/kendo/2013.2.918/kendo.common.min.css")" />
<link rel="stylesheet" href="#Url.Content("~/Kendo/Content/kendo/2013.2.918/kendo.blueopal.min.css")" />
<link rel="stylesheet" href="#Url.Content("~/Kendo/Content/kendo/2013.2.918/kendo.dataviz.min.css")" />
<link rel="stylesheet" href="#Url.Content("~/Kendo/Content/kendo/2013.2.918/kendo.dataviz.blueopal.min.css")" />
This doesn't work (the styles do get applied, however images referenced in the css don't render):
#Styles.Render("~/bundles/kendoStyle")
here's the Bundle def in App_start -> BundleConfig.cs:
//Kendo Styles:
bundles.Add(new StyleBundle("~/bundles/kendoStyle").Include(
"~/Kendo/Content/kendo/2013.2.918/kendo.common.min.css"
, "~/Kendo/Content/kendo/2013.2.918/kendo.blueopal.min.css"
, "~/Kendo/Content/kendo/2013.2.918/kendo.dataviz.min.css"
, "~/Kendo/Content/kendo/2013.2.918/kendo.dataviz.blueopal.min.css"
//, "~/Kendo/Content/contextMenu.css"
));
What am I doing wrong here? (please note, "Kendo" is setup as an mvc4.5 web app under my main website
Image paths are relative to the folder in which styesheets are located. For example, an image might be referenced like this:
.k-icon {
background-image: url('BlueOpal/sprite.png');
}
Because your bundle redefines the path to your stylesheets, the browser attempts to download the image from ~/bundles/BlueOpal/sprite.png, which doesn't exist. The actual path to the image is ~/Kendo/Content/kendo/2013.2.918/BlueOpal/sprite.png.
Everything works fine when you link to your stylesheets directly (without the bundle) because relative paths correctly point to images on your server. However, because your bundle redefines the virtual path in which the stylsheets are located the relative paths to images no longer work.
If you want to use a bundle you must define it with a path that will not break relative image paths in the stylesheets. In your case, since the KendoUI stylesheets are located at ~/Kendo/Content/kendo/2013.2.918, you should define the bundle with that same path:
bundles.Add(new StyleBundle("~/Kendo/Content/kendo/2013.2.918/bundle").Include(
"~/Kendo/Content/kendo/2013.2.918/kendo.common.min.css",
"~/Kendo/Content/kendo/2013.2.918/kendo.blueopal.min.css",
"~/Kendo/Content/kendo/2013.2.918/kendo.dataviz.min.css",
"~/Kendo/Content/kendo/2013.2.918/kendo.dataviz.blueopal.min.css"
));
I hope that helps.
Hi I hat the same problem. but I saw that the page was able to get the sprite file, but does not show some symbols. The temporally solution was set the bundle EnableOptimizations property to false.
BundleTable.EnableOptimizations = False

Zurb Foundation icons general enclosed

I'm trying to use the Zurb Foundation General Enclosed font icons. I downloaded the files, they have filename extenstions of "sgv", "ttf", "woff". I'm not sure how to include them in the page. I'm completely new to this.
I've searched google and read a few blogs on this but I'm still confused.
I'm not sure how to set up the files to get them to work.
My platform is asp.net mvc.
Thank you
I downloaded the files, they have filename extenstions of "sgv",
"ttf", "woff". I'm not sure how to include them in the page.
After you downloaded the files you will have the following Foundation Fonts folder structure:
- foundation_icons_general_enclosed
--- fonts
--- saas
--- stylesheets
In an ASP.net project it's better that you have the styles in a separate file so you can update quickly in case there are updates from Foundation. You can copy them into their own folders too. So you have a Content folder by default, and you can have the following structures:
- Content
--- fonts - copy `eot`, `sgv`, `ttf`, and `woff` files
--- addon - copy `general_enclosed_foundicons.css`
After you copied the files you need to adjust the styles to point to the correct font files, for example:
#font-face {
url("../fonts/general_foundicons.eot")
Then reference the files so you could use them in your project
<link href="#Url.Content("~/Content/addon/general_foundicons.css")"
rel="stylesheet" type="text/css" />
And you can start using them by doing <i class="foundicon-[icon]"></i> as shown on the playground. For example:
<i class="general foundicon-add-doc"></i>
// to use it as a link
<i class="general foundicon-add-doc"></i>
Additional Tip for Deployment
If its the first time you used fonts in a website, the fonts will not work after deployment. If you encounter that issue make sure you have the following MIME types in your IIS. I forgot which ones are in by default but I'm sure you won't have the following by default:
File name extension: .svg
MIME type: image/svg+xml
File name extension: .ttf
MIME type: application/octet-stream
File name extension: .eot
MIME type: application/octet-stream
You can leave out .woff and it will work.
When you download the fonts, you'll be able to simply merge the stylesheets and fonts folders straight into Foundation. Here's what the CSS looks like:
#font-face {
font-family: '[set]Foundicons';
src: url('fonts/[set]_foundicons.eot');
src: url('fonts/[set]_foundicons.eot?#iefix') format('embedded-opentype'),
url('fonts/[set]_foundicons.woff') format('woff'),
url('fonts/[set]_foundicons.ttf') format('truetype'),
url('fonts/[set]_foundicons.svg#[set]Foundicons') format('svg');
font-weight: normal;
font-style: normal;
}
[class*="foundicon-"] {
display: inline;
width: auto;
height: auto;
line-height: inherit;
vertical-align: baseline;
background-image: none;
background-position: 0 0;
background-repeat: repeat;
}
[class*="foundicon-"]:before {
font-family: "[set]Foundicons";
font-weight: normal;
font-style: normal;
text-decoration: inherit;
}
This is how you use it.
<i class="foundicon-[icon]"></i>
From the Foundation documentation.
phantom edit
Just after posting a blurb on zurb icon fonts not working on F4... viola, I fixed it. So I'm redoing my post to add some much needed clarification:
The instructions on the Zurb site are typically a bit on the vague side. It requires general knowledge of sass, and for sass noobs it gets confusing fast. So here we go:
1) After downloading the files, copy them over to the applicable directories in your Foundation folder. I'm using Zend, so wherever you have your Foundation Sass setup is where you are going to put these. Just like the docs say, copy the .scss files over to their appropriate folder, copy the entire new fonts directory over to the Foundation folder, at the same directory level (right there next to Sass and Stylesheets, etc).
Note: one reason why such a simple step may be confusing for some is because the Zurb documentation uses the term "merging" instead of "adding" the files. Only one file is in fact merged: _settings.scss
2) So whats up with the _settings.scss file? Open it up and check it out! It's just a mixin for the fonts. Take that code and add it near the top of your existing _settings.scss folder. It did not work for me when added toward the bottom.
3) That snip of CSS from the Zurb documentation page needs to be added at the top of your app.scss file. I put it just under all of my #import declarations.
4) Make sure that Compass is on and you have it watching your Foundation folder! Yow.
Ok, I've done my good deed for the day.
No need to over complicate this. What I did:
download icons
move the downloaded folder "foundation-icons" into your css folder
put the following line into the <head> section of your html <link rel="stylesheet" href="css/foundation-icons/foundation-icons.css" />
Then put in an up-arrow (or other icon) anywhere in the <body> of your html with <i class="fi-up-arrow"></i>

Is it possible in Rails/Asset pipeline compress several SVGs to one file?

As you know you can compress several CSS files to one (or JS files). I was wondering if it's possible to compress several SVG to one external file, so the server makes just one request
Basically SVG files are just XML text so it's theoretically possible, however there is a catch how to render several of those images on different places
I'm just wondering
Check the answer to this question, which describes how to configure the filetypes the Asset Pipeline will manage: Using fonts with Rails asset pipeline (despite the title, it applies to more than fonts).
Thx for answer but in the end I ended up doing it like this:
In my case I wanted to use my SVG as a background image of div tag so I don't needed to precompile SVGs, I just put the compress format directly to background-image: url('here')
so for multiple SVG background:
width: 600px:
height: 400px:
background-image: url('data:image/svg+xml ...first svg '), url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjY0MCIgaGVpZ2h0PSI0ODAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8IS0tIENyZWF0ZWQgd2l0aCBTVkctZWRpdCAtIGh0dHA6Ly9zdmctZWRpdC5nb29nbGVjb2RlLmNvbS8gLS0+CgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxwb2x5bGluZSBpZD0ic3ZnXzMiIHBvaW50cz0iNTM4LjUsMzMzLjU2OTU2NDgxOTMzNTk0IDMyMi4yNSwyNzguMjg0NzgyNDA5NjY3OTcgMTA2LDIyMyAiIHN0cm9rZT0iIzAwMDAwMCIgc3Ryb2tlLXdpZHRoPSI1IiBmaWxsPSJub25lIi8+CiAgPGVsbGlwc2UgZmlsbD0iI0ZGMDAwMCIgc3Ryb2tlPSIjMDAwMDAwIiBzdHJva2Utd2lkdGg9IjUiIGN4PSIzNDMiIGN5PSIxNzAiIGlkPSJzdmdfMSIgcng9IjE0MCIgcnk9IjEwNSIvPgogPC9nPgo8L3N2Zz4=')
check it here: http://codepen.io/equivalent/full/ymefJ
raw svg format:
<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<g>
<title>Layer 1</title>
<polyline fill="none" stroke-width="5" stroke="#000000" points="538.5,333.56956481933594 322.25,278.28478240966797 106,223 " id="svg_3"/>
<ellipse transform="translate(-402 -120)" ry="105" rx="140" id="svg_1" cy="290" cx="745" stroke-width="5" stroke="#000000" fill="#FF0000"/>
</g>
</svg>
editor: http://svg-edit.googlecode.com/svn/trunk/editor/svg-editor.html
I believe that the link in Tom Harrison answer is on to something and from what I saw it might work, but I didn't try it myself. So if you want to truly precompile SVG with assets pipeline I encourage you to use that tactic.

prev/next icons not showing in customized jquery datepicker theme

I implemented jQuery DatePicker in my VS2010 project and it works fine with one small issue. When I implemented a custom theme, I lost my prev and next icons (for moving through the months).
Here's the image:
Here are the jquery library references:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>
<script type="text/javascript" src="~/lightbox/js/prototype.js"></script>
<script type="text/javascript" src="~/lightbox/js/scriptaculous.js?load=effects,builder"></script>
<script type="text/javascript" src="~/lightbox/js/lightbox.js"></script>
<link type="text/css" rel="stylesheet" href="~/lightbox/css/lightbox.css" media="screen" />
<link type="text/css" rel="Stylesheet" href="~/Scripts/jquery-ui-1.8.9.custom.css" />
Here are my image references in jquery-ui-1.8.9-custom.css
/* states and images */
.ui-icon { width: 16px; height: 16px; background-image: url(~/images/jquery/ui-icons_469bdd_256x240.png); }
.ui-widget-content .ui-icon {background-image: url(~/images/jquery/ui-icons_469bdd_256x240.png); }
.ui-widget-header .ui-icon {background-image: url(~/images/jquery/ui-icons_d8e7f3_256x240.png); }
.ui-state-default .ui-icon { background-image: url(~/images/jquery/ui-icons_6da8d5_256x240.png); }
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(~/images/jquery/ui-icons_217bc0_256x240.png); }
.ui-state-active .ui-icon {background-image: url(~/images/jquery/ui-icons_f9bd01_256x240.png); }
.ui-state-highlight .ui-icon {background-image: url(~/images/jquery/ui-icons_2e83ff_256x240.png); }
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(~/images/jquery/ui-icons_cd0a0a_256x240.png); }
I modified the path to be sure it pointed to the files. Not sure what I'm missing.
Any help would be greatly appreciated.
Thanks.
Are you sure your paths are pointing correctly (AKA, are you seeing the jQuery UI icons elsewhere in your site)? That is the first thing I would check...particularly because you modified the path. You may have inadvertently screwed something up.
Update
I think you need to fix your paths - I don't think they are pointing correctly. From what I see, they have to be relative to your .custom.css file. So, for example, my jquery-ui-1.8.9.custom.css file exists in my Content folder. My states and images are referenced like this:
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_cccccc_256x240.png); }
Therefore, I have to place an images folder at the same level as the jquery-ui-1.8.9.custom.css and place all the images inside that folder. Try that and see if it fixes the problem for you.
For me, the issue was that the Themeroller was adding double quotes around the image paths. I just removed those from my custom CSS file, and everything worked.
i.e. I changed:
url("images/ui-bg_highlight-hard_100_fafaf4_1x100.png")
to:
url(images/ui-bg_highlight-hard_100_fafaf4_1x100.png)
throughout the whole CSS file.
I also was having this problem. I was pulling my hair out. But yes, JasCav is correct, you must put an "images" folder at the same level as your query-ui-1.8.9.custom.css (or in my case jquery-ui-1.8.16.custom.css) file. And inside this folder copy your *.png files from your jquery ui download.
I had the exact same problem and finally solved it.
The problem was coming from the rights on the 'images' directory. I had to make the directory browsable for 'others' by using chmod:
chmod o+rx images
I hope this helps
I had the same problem. Created an images directory under my theme name, and dragged all the gif files and png files from the theme into the new images directory. worked like a charm, no messing with the paths.
I think the themeroller app at JQuery_ui doesn't package the images into an image directory, and it should.
Anyway, revert your pathing back to the way it was, and give it a try. Good luck.
By the way, it appears you put your custom.css into your scripts folder, that gets messy, I just pointed mine to the themes folder copy. i.e.
link href="../../Content/themes/humanity/jquery-ui-1.8.13.custom.css" rel="stylesheet" type="text/css"
I also fell foul of this. I have read the answers given above and they do not tally 100% with my experience as of July 2012. I do not know if the UI custom ThemeRoller has been changed at all since this question was first raised which may explain the previous comments/answers. However for me these answers over complicate what needs to be done and were therefore a confusion to me.
What worked for me :-
Use ThemeRoller to create you customised theme.
Download the theme - for example to directory my_Work_Area outside of your project.
Unzip the download to my_Work_Area
Review the index.html after unzipping - check that the datepicker style reflects the style tested in the ThemeRoller. If not go back to the ThemeRoller and repeat 1-3.
copy my_Work_Area/js/jquery-ui-1.8.21.custom.min.js to your jquery folder within your project for example _public/_jquery/jquery-ui-1.8.21.custom.min.js
if required similarly copy jquery-1.7.2.min.js
copy my_Work_Area/css/custom-theme/jquery-ui-1.8.21.custom.css to your css folder within your project for example _public/_css/jquery-ui-1.8.21.custom.css
copy the folder my_Work_Area/css/custom-theme/images to your css folder within your project for example _public/_css/images
as per the documentation ensure that the following is included in your html
<link rel="stylesheet" type="text/css" href="../_public/_css/jquery-ui-1.8.21.custom.css" />
<script type="text/javascript" src="../_public/_jquery/jquery-1.7.1.js"></script>
<script type="text/javascript" src="../_public/_jquery/jquery-ui-1.8.21.custom.min.js"></script>
That is all you need to do.
Whether it is appropriate to have a folder called images inside your css folder might need to be considered. Changing the location of this folder would involve considering of the paths employed.
But if you just want the ui to work 'out of the box' the above works with no need to make anything complicated.
I hope that this helps.
Place image folder with icons files, in that location, where the .css file exists.
who reading this question,
If you use this dateime picker
http://www.malot.fr/bootstrap-datetimepicker/
You add this option: bootcssVer : 3
$( ".date" ).datepicker( "option", "changeMonth", true, **"bootcssVer" : 3** );
The icon will show!!!
Let me share the solution for my case. My ASP.NET MVC project has the following directory structure:
Content
themes
base
images
icon1.png
icon2.png
jquery-ui.css
Other directories
When I run application locally via Visual Studio, in the jquery-ui.css I can refer to the icons using the following url: url("images/icon1.png"). But when I run application on the Azure server, I must refer to this icon with: url("themes/base/images/icon1.png"). It turned out, that the real "working"/"current" directory for jquery-ui.css is Content directory. That is because in cshtml I load jquery-ui.css using the bundle, which I create in the following way:
bundles.Add(new StyleBundle("~/Content/cssjqryUi").Include("~/Content/themes/base/jquery-ui.css"));
It seems like VS is "super intelligent" and looks for referred images also inside subdirectories.
The solution can be to use inside jquery-ui.css file the absolute url to the images: url("/Content/themes/base/images/icon1.png") (or proper path relative to the Content directory in my case, i.e. url("themes/base/images/icon1.png"), as I mentioned above) or to create bundle with more nested path:
bundles.Add(new StyleBundle("~/Content/themes/base/cssjqryUi").Include("~/Content/themes/base/jquery-ui.css"));
Another (worse in my opinoin) solution is to load css file into cshtml using <link> element:
<link rel="stylesheet" href="~/Content/themes/base/jquery-ui.css" />

Resources