Haml: Feature Request: Import Folder

Created on 5 Mar 2010  ·  25Comments  ·  Source: haml/haml

It would be very useful to be able to import all the files inside a folder by only providing:
@import folder_name

Right now, my system has a lot of churn due to the fact that I need to have an extra sass file that imports all the files in a folder. I'm sure I can't be the only one...

Thanks!

Most helpful comment

gah, this sucks... i have a folder called page_specific/ in my rails app's assets...
these should all be compiled into the big asset blob, and they are each wrapped completely in
body#page1 {}, body#page2 {}, etc...

there is zero chance of them being order dependent, and frankly this whole "you'll miss-use it! no!!!!!!" crap is insulting.

if a user of this feature discovers that order is important, they can just import the files in an explicit order, or refactor the styles to not be order-dependent... forcing everybody to manually work around this missing feature is paternalistic garbage >:(

surely we can think of a way to minimize this minor problem of ordering. deterministic ordering is a start. calling it @import-dir, and documentation of the potential ordering problem would also help. rails already provides require_tree, and things there seem to work fine. the one exception there is that files get compiled individually which drops my mixins and variables on the floor. i note that the mixins are the one part that were sited as explicitly order-independent, so why can this not work for sass when it works for everybody else?

All 25 comments

I'm skeptical of the utility of this. I don't think having to manually list all the relevant files is really that burdensome. Also, it seems like it might lead to the danger of not getting actual compile errors when a file you expect to exist doesn't. Instead, styles disappear seemingly arbitrarily.

I understand your argument, however, I don't think you are seeing the other type of situation this is needed. Currently I have a folder that will have 60+ Sass files. Without the ability to @import a folder, I need to maintain a file that imports each file individually.

There are many problems with including each file individually. First, is that if you forget to include a file, you do not get a warning. Next, is if you have a team of developers working on Sass, they each need to remember to import the file manually after creating it in the folder. Depending on people to do the right thing will break eventually.

Also, we have precedence that importing a folder is a "good thing". Java's import statement allows you to import entire packages or specific classes of those packages.

Order of imports is important in the general case because selectors of the same weight resolve according to document order. Globbing means that adding a file can change the global resolution order of selectors unexpectedly.

Such ordering issues are not present in code and where they are (like ruby) there's no such feature.

I would be interested to see if there's a way to do this in Sass without a change to the sass core importing mechanism. This would allow frameworks and individuals using sass to develop their own globbing system as they see fit. For instance:

@import file-list("foo/*.sass");

We used to have special parsing logic for @import that would have precluded this, but we do not anymore.

The problem with allowing truly dynamic imports (such as via functions) is that then the dependency structure of a document becomes impossible to figure out dynamically. This means that caching and selective compilation become much less useful.

For ordering problems, we could always sort the files alphabetically or something to come up with a deterministic (albeit arbitrary) ordering. This still presents the problem that ordering could change and disrupt functionality if the name of a file changes, though.

Presumably, such an approach via globbing would imply using nested selectors to prevent such issues.

In my opinion, importing a whole directory tree of files has only marginal utility over the explicit import approach and encourages the user to consider the precedence issues. If we do add such a feature, I would like it to be more general purpose than just at the directory level.

Lastly, I think you're correct that introducing a glob that was outside of the dependency graph and appears as only single imports to the sass engine means that it's harder to invalidate files when new dependencies appear that match the glob.

I agree that importing a folder would lead to an ambiguous order of files being imported. However, that should be up to the user to decide if it's the right thing for them. It will fit some situations but not others. It is definitely possible to envision a system where the contents of a folder do not target the same elements (mine don't).

Just like importing specific files works. it fits some situations but not others.

The choice should be up to the developer.

It's too easy for a user to have stylesheets that are ordering-dependent and not know it. Anything at all could trigger a re-ordering and create layout bugs that would be very difficult to track down. And it wouldn't be clear enough that importing a directory would leave someone open to such issues. Ordering via filename would probably be a good-enough solution to this, though, so it's not a serious impediment.

The extension I'd consider would be allowing standard file globs -- probably those supported by Dir.glob. This would be resolvable at compile-time, and would provide a reasonable degree of power.

I'm still a ways from convinced as to the utility, though.

It's important to consider that ordering via Dir.glob is filesystem dependent and might change across platforms -- I've actually been bitten by this difference between Mac and Linux. So if we do end up implementing such a feature, it's important for us to sort the list according to a well documented and easily understood approach (E.g. downcased sort)

I'm also still leaning a little against this feature. The importing approach that compass uses has not really been a maintenance burden. However, it's certainly a commonly requested feature. I think it's been brought up on the mailing list and on twitter about 4 or 5 times now.

We'll certainly deterministically order the files somehow. Upcased vs. downcased sort is an interesting question... we should probably do downcased with upcased as a tiebreaker (since it will allow for ties on case-sensitive filesystems).

I agree. I'm kind of against being able to pass a parameter directly to Dir.glob. That truly seems like an unnecessary feature. Can you guys come up with a scenario where it's advantageous to have that degree of control?

It seems like the following two options should be enough:
-Cherry pick files using @import
-Import an entire directory using @import folder_name

Also, I think alphabetical will work out just fine. We just need to make sure its documented.

Importing directories via @import dir is too ambiguous with importing individual files. We should definitely add at least * globs.

Still not convinced, though.

it's usefull if you have different "styles" for a page. example:
generic/ (xx sass files here)
style1/ (xx sass files here which add/overwrite styles to the ones in generic)
style2/ (xx sass files here which add/overwrite styles to the ones in generic)
style1.sass (simply: @import generic/_, style1/_)
style2.sass (simply: @import generic/_, style2/_)

Why couldn't you just have _generic.sass that imports everything in the generic directory?

I don't think it's about what can or can't be done as much as should they have to. Ultimately the ordering of stylesheets is important and so I want that to be thought about by the user. It's true that libraries that only define mixins and variables are order independent as are scoped stylesheets -- but I worry about providing a general capability that will be mis-used.

Define "scoped stylesheets"?

Stylesheets that nest most or all of their selectors. e.g. body.foo

Those aren't guaranteed to be order-independent. Another stylesheet elsewhere could define body.foo ..., or something else with higher specificity.

Then you really don't have a working framework because your files are not separated correctly.

There are plenty of ways for people to screw up their CSS. We can provide them this solution and explain when it should be used over importing individual files.

By not implementing this feature you are giving developers that want to do this implement scoped stylesheets these two choices:
1) Manually import each file independently (which can cause errors of it's own because it does not tell you when you missed a file)
2) Implement a build system to dynamically adds these files (which is a waste because there will be multiple people implementing the same thing)

It's certainly not the case that all order-dependence of scoped stylesheets is the result of poor separation of concerns. Consider:

body.foo .baz {
  color: blue; }

body.bar .baz {
  color: red; }

This stylesheet is well-separated, but still order-dependent.

In any case, the idea that we can expect everyone using this feature to understand the risks is wrong. The only way to ensure that everyone understands what order their stylesheets will be imported in is to have it be specified explicitly.

By and large scoped stylesheets will be order agnostic, but it can be the case that order matters even when concerns are correctly separated.

Silently ignoring imports that are not found is no longer an issue in sass3. Only css imports will be silently ignored.

I have one sass file that imports about 60 others. I change it when files are added or removed and I always think about the ordering when I do. It's never seemed like a burden to me, but rather, a necessary step.

If my imports are not found (I always specify .sass for imports) then my tests fail.

There's an addage: as simple as possible and no simpler.

My gut tells me that this makes things too simple and all the time savings are lost by one debugging session. I vote that we set this aside for the time being. If someone wants to make a sass plugin that provides this capability, I would be very interested in seeing how it works out for those users.

I think Richard's point was that there's no error when a partial is created but no import is added for it. I suppose this could be alleviated by looking for unused partials and printing warnings for them.

I'm going to go ahead and close this.

gah, this sucks... i have a folder called page_specific/ in my rails app's assets...
these should all be compiled into the big asset blob, and they are each wrapped completely in
body#page1 {}, body#page2 {}, etc...

there is zero chance of them being order dependent, and frankly this whole "you'll miss-use it! no!!!!!!" crap is insulting.

if a user of this feature discovers that order is important, they can just import the files in an explicit order, or refactor the styles to not be order-dependent... forcing everybody to manually work around this missing feature is paternalistic garbage >:(

surely we can think of a way to minimize this minor problem of ordering. deterministic ordering is a start. calling it @import-dir, and documentation of the potential ordering problem would also help. rails already provides require_tree, and things there seem to work fine. the one exception there is that files get compiled individually which drops my mixins and variables on the floor. i note that the mixins are the one part that were sited as explicitly order-independent, so why can this not work for sass when it works for everybody else?

@chriseppstein awesome! (and sorry for ranting like a maniac everybody)

Was this page helpful?
0 / 5 - 0 ratings