Hanami::Assets does not preserve directory structure
katafrakt opened this issue · comments
I'm creating an app where certain pages are displayed using different themes, based on values from the database. I put theme in apps/assets/stylesheets/themes/orbit/styles.css
directory and then referenced it in the template with <%= stylesheet 'themes/orbit/styles' %>
. However, this does not work. The stylesheet is not available and when I look into public/assets
directory, I see styles.css
in the root directory, not in public/assets/themes/orbit/
as I expected.
Is this a bug/missing feature in Hanami::Assets
or is it by design? If the latter, how can I accomplish what I want. If former, what can I do to help fix/implement it?
I'm using 1.1.0.beta1
version.
@katafrakt Hi and thanks for reporting this problem. It's not possible to keep the structure at this time.
We already discussed some time ago (see #34), and my opinion is 👍 for this enhancement. What's @hanami/core take on this?
@katafrakt would you like to implement this?
@katafrakt if you can't I could give it a try
I would like to and I'll try to do it.
@jodosha Some questions before I actually code:
- Should the PR target master or develop?
- Should there be an option to retain old (current) behaviour? Since Hanami is past 1.0, it might be a good idea, although it will make the code more complex, probably.
Should the PR target master or develop?
Please target develop
Should there be an option to retain old (current) behaviour? Since Hanami is past 1.0, it might be a good idea, although it will make the code more complex, probably.
As long it doesn't require changes in the public API, we can include this change in the next 1.x release. I see compiled assets not as a breaking change, as long they will keep working for people. The directory structure should be irrelevant for devs.
As long it doesn't require changes in the public API, we can include this change in the next 1.x release.
It's really hard for me to tell. Basically the problem I see is that right now there is a mechanism resolving assets from nested paths, i.e. if I have a file in assets/some/directory/bootstrap.js
and do Hanami::Assets::Compiler.compile(@config, 'bootstrap.js')
, it will be found and copied into the root directory of assets as bootstrap.js
. I think this should be removed and only "full relative paths" should be supported. But that sounds like a breaking change. What do you think?
(if you are against removing it, the PR is really simple and I can do it right away, btw)
This is what I am thinking about :
1 - Assets that don't need processing.
Have a list of mime types that pass through assets manager without being modified (jpg, png, woff, svg...)
Example :
assets/images/my-theme/backgrounds/bg_1.jpg => compute hash if needed => public/assets/images/my-theme/backgrounds/bg_1-hash.jpg
2 - Assets that need compilation/preprocessing/whatever
Have a list of assets to release
Example :
assets/stylesheets/my-theme/blue.sass => use sass preprocessor to include dependencies and produce css file => compute hash if needed => public/assets/stylesheets/my-theme/blue-hash.css
Simple, predictable and still configurable.
Am I missing something ?
Since this issue did not make it to 1.1.0 release, I would like to propose a bit more "radical" change instead of what's in my pull request.
Right now every asset from root
is compiled to target directory no matter how deep it is in the file structure. This means the following results (assume root
is web/assets
and target directory is public/assets
):
path | compiled to |
---|---|
web/assets/style.css |
public/assets/style.css |
web/assets/stylesheets/style.css |
public/assets/style.css |
web/assets/foo/bar/style.css |
public/assets/style.css |
The PR mentioned in this issue add an opt-in possibility to mark some paths as nested so they are compiled differently. For example with this added to config:
nested_assets << [
"style/style.css"
]
web/assets/stylesheets/style/style.css
would be compiled to public/assets/style/style.css
.
This solution is backwards compatilble, but in my opinion it is not the best one. Instead, I would like to propose creating a list of directories, where files can be looked up under root. If the file is not in one of them or in nested in a deeper structure, it is treated as relative path.
Assuming that "allowed directories" would be stylesheets
, javascripts
, images
and fonts
it would look like that:
path | compiled to |
---|---|
web/assets/style.css |
public/assets/style.css |
web/assets/stylesheets/style.css |
public/assets/style.css |
web/assets/foo/bar/style.css |
public/assets/foo/bar/style.css |
web/assets/javascripts/bootstrap/main.js |
public/assets/bootstrap/main.js |
I don't know if I described it clearly, but let me know what you think.
ping @jodosha
any news?
I think it's OK if it's not backwards compatible, since the old behavior was buggy.
We should strive for correctness (preserving hierarchy) over keeping compatibility with buggy behavior.
@katafrakt I just ran into an effect from this bug. I'm building an app using Semantic UI, and the CSS included looks for a font at ./themes/default/assets/fonts/icons.woff2
but since we don't nest assets, it cannot find it. By editing it to just ./icons.woff2
, it works. So, I really think this bug fix would be great :)
Also, I personally think we shouldn't white-list folders (stylesheets
, javascripts
, images
and fonts
). We don't do it now, and we'd want to support any arbitrary file structure within assets
. What do you think?
@cllns Perhaps I did not explain it correctly but there is no real "whitelisting" in my concept, more like adding additional root directories for assets. For example:
apps/web/assets/themes/default/assets/fonts/icons.woff2
becomes public/assets/themes/default/assets/fonts/icons.woff2
however apps/web/assets/stylesheets/semantic/semantic.css
would become public/assets/semantic/semantic.css
and not public/assets/stylesheets/semantic/semantic.css
.
stylesheets
, javascripts
, images
and fonts
would be those additional roots.
@katafrakt Ah, I think I get it now. Thanks! Do you think you'll have time to open a PR implementing this fix, against develop
?
@cllns I hope so, but I will take couple of days. I have some work in progress already though.
@cllns There is a new PR (linked above)
Implemented by #88