Allow passing variables in from command-line #731

Closed
twoolie opened this Issue Mar 23, 2012 · 13 comments

Comments

Projects
None yet
8 participants
@twoolie

twoolie commented Mar 23, 2012

Would it be possible to pass in arbitary vars from commandline?

lessc {infile} --variable="@static_url: \"{static_url}\"" > {outfile}
or
lessc {infile} --static_url=/static/ > {outfile}

@aziz

This comment has been minimized.

Show comment
Hide comment

aziz commented Mar 31, 2012

👍

@lukeapage

This comment has been minimized.

Show comment
Hide comment
@lukeapage

lukeapage Jul 23, 2012

Member

just write them to a file and include it?

Member

lukeapage commented Jul 23, 2012

just write them to a file and include it?

@twoolie

This comment has been minimized.

Show comment
Hide comment
@twoolie

twoolie Jul 24, 2012

Toolchain integration would be much easier if lessc {infile} --static_url="/static/" > {outfile} were available

@agatronic How do you easily write out a file from a makefile? (No echo hax)

twoolie commented Jul 24, 2012

Toolchain integration would be much easier if lessc {infile} --static_url="/static/" > {outfile} were available

@agatronic How do you easily write out a file from a makefile? (No echo hax)

@amcgregor

This comment has been minimized.

Show comment
Hide comment
@amcgregor

amcgregor Oct 4, 2012

+1

Extra special bonus points if the command-line provided variable can explicitly override one defined in your source .less files. Use case for me is:

@basePath: '../static';  # in the .less source
lessc <src> --override basePath=http://cdn.example.com/ > <out>

Edited to add: the reason for overriding like this, if not clear from the above, is that I can have a default value for use by the in-browser development mode, and override the value with the full base path to a CDN during compilation when deploying.

+1

Extra special bonus points if the command-line provided variable can explicitly override one defined in your source .less files. Use case for me is:

@basePath: '../static';  # in the .less source
lessc <src> --override basePath=http://cdn.example.com/ > <out>

Edited to add: the reason for overriding like this, if not clear from the above, is that I can have a default value for use by the in-browser development mode, and override the value with the full base path to a CDN during compilation when deploying.

@amcgregor

This comment has been minimized.

Show comment
Hide comment
@amcgregor

amcgregor Oct 9, 2012

@twoolie Echo hacks are still better than awk/sed hacks.

@twoolie Echo hacks are still better than awk/sed hacks.

@jonschlinkert

This comment has been minimized.

Show comment
Hide comment
@jonschlinkert

jonschlinkert Apr 5, 2013

Contributor

I was just going to create this as a feature request, this is a great idea. Huge thumbs-up from me.

An example use case would be to use this to define variables in external JSON files, say representing themes, swatches, and so on, and then use build configuration to mix and match. The power of this feature is that it makes LESS more interesting to 3rd-party build systems that use Less.js.

If you want real-world examples of something similar, look at Shopify themes. They use liquid for templating, and they use LESS for styles. And when you create a theme you put all of your theme variables into JSON. What's cool is that you can put some variables in JSON and some directly in the styles. Once you start doing it that way you begin to see patterns of why you would always put certain variables in JSON and others in LESS.

{
  "basePath": "../base/path"
}

However, I don't like the override concept. I think variables defined this way would be considered "global variables" and would be overridden by anything defined inside the LESS files themselves. It needs to be black and white like that or it's too complicated.

Contributor

jonschlinkert commented Apr 5, 2013

I was just going to create this as a feature request, this is a great idea. Huge thumbs-up from me.

An example use case would be to use this to define variables in external JSON files, say representing themes, swatches, and so on, and then use build configuration to mix and match. The power of this feature is that it makes LESS more interesting to 3rd-party build systems that use Less.js.

If you want real-world examples of something similar, look at Shopify themes. They use liquid for templating, and they use LESS for styles. And when you create a theme you put all of your theme variables into JSON. What's cool is that you can put some variables in JSON and some directly in the styles. Once you start doing it that way you begin to see patterns of why you would always put certain variables in JSON and others in LESS.

{
  "basePath": "../base/path"
}

However, I don't like the override concept. I think variables defined this way would be considered "global variables" and would be overridden by anything defined inside the LESS files themselves. It needs to be black and white like that or it's too complicated.

@CHH

This comment has been minimized.

Show comment
Hide comment

CHH commented Apr 12, 2013

👍

@lukeapage

This comment has been minimized.

Show comment
Hide comment
@lukeapage

lukeapage Apr 15, 2013

Member

@jonschlinkert re: override concept. what you say would also match the browser variable injection. will target 1.4.1

Member

lukeapage commented Apr 15, 2013

@jonschlinkert re: override concept. what you say would also match the browser variable injection. will target 1.4.1

@jonschlinkert

This comment has been minimized.

Show comment
Hide comment
@jonschlinkert

jonschlinkert Apr 15, 2013

Contributor

👍 this will be a huge feature! can't wait

Contributor

jonschlinkert commented Apr 15, 2013

👍 this will be a huge feature! can't wait

@brigand

This comment has been minimized.

Show comment
Hide comment
@brigand

brigand Jun 17, 2013

Related to #1374.

brigand commented Jun 17, 2013

Related to #1374.

@chipx86

This comment has been minimized.

Show comment
Hide comment
@chipx86

chipx86 Nov 14, 2013

Contributor

We had a need for this in our product (Review Board) as well. Specifically, we needed to be able to define global variables that a .less file could use as a path for imports, both during compilation time with lessc, and during development using less.js. Along with this, we needed the equivalent of less.modifyVars in lessc, so that we could override a variable defined within the .less file.

I started playing around with this and developed a change. I know the guidelines say to discuss the design before working on any code, but I took our requirements as an opportunity to learn the codebase and test out designs on our product's side, so I have some code I'll be submitted for your review/feedback anyway. Let me know if there are better ways of doing what I'm doing, or if you'd prefer a different design.

I'll go over what I've put together.

lessc

I've added two new arguments to lessc: --global-var and --modify-var. Both take variables in the form of VARNAME=VALUE. In the case of --global-var, the variable is basically inserted at the top of the buffer being compiled to CSS, and --modify-var inserts at the end. (I know that toCSS's second parameter takes variables, but it seemed to require tree nodes, and it seemed like far more effort to figure that out from command line arguments than to just modify the buffer in-memory.)

--modify-var is basically analogous to less.modifyVars.

For example, using global variables with a .less file that depends on @static-url but doesn't define it itself:

$ lessc --global-var="static-url='/static/'" site.less site.css

Or, if the .less file defined a default for testing that you'd want to override:

$ lessc --modify-var="static-url='http://cdn.example.com/'" site.less site.css

Multiple variables of either type can be specified by passing additional --global-var and --modify-var arguments.

less.js

I also added a new option to less.js's less dictionary: less.globalVars. This is equivalent to --global-var (though with the same dictionary syntax for entries that less.modifyVars uses).

Here's an example with a Django template:

<script>
    less = {
        globalVars: {
            'static-url': '{{settings.STATIC_URL}}'
        }
    }
</script>

Use cases

There are some good use cases listed in this bug report, and in some other related reports. Ours is similar to the other base path use-cases. Essentially, we've standardized on less for all static media for extensions built for Review Board, and needed a way to provide some configuration-related variables to all bundled and extension-provided .less files, for the base path and for other bits of build-time configuration.

The variables we prepare are largely for the @import statements that may be in a file. The imports will be used to pull in common definitions and macros we ship (which may exist in different locations depending on whether it's using the runtime or being packaged). We'd use --global-var and less.globalVars for this.

When packaging, depending on the configuration of the server, certain variables may be overridden, and for this we'd use --modify-var and less.modifyVars.

Contributor

chipx86 commented Nov 14, 2013

We had a need for this in our product (Review Board) as well. Specifically, we needed to be able to define global variables that a .less file could use as a path for imports, both during compilation time with lessc, and during development using less.js. Along with this, we needed the equivalent of less.modifyVars in lessc, so that we could override a variable defined within the .less file.

I started playing around with this and developed a change. I know the guidelines say to discuss the design before working on any code, but I took our requirements as an opportunity to learn the codebase and test out designs on our product's side, so I have some code I'll be submitted for your review/feedback anyway. Let me know if there are better ways of doing what I'm doing, or if you'd prefer a different design.

I'll go over what I've put together.

lessc

I've added two new arguments to lessc: --global-var and --modify-var. Both take variables in the form of VARNAME=VALUE. In the case of --global-var, the variable is basically inserted at the top of the buffer being compiled to CSS, and --modify-var inserts at the end. (I know that toCSS's second parameter takes variables, but it seemed to require tree nodes, and it seemed like far more effort to figure that out from command line arguments than to just modify the buffer in-memory.)

--modify-var is basically analogous to less.modifyVars.

For example, using global variables with a .less file that depends on @static-url but doesn't define it itself:

$ lessc --global-var="static-url='/static/'" site.less site.css

Or, if the .less file defined a default for testing that you'd want to override:

$ lessc --modify-var="static-url='http://cdn.example.com/'" site.less site.css

Multiple variables of either type can be specified by passing additional --global-var and --modify-var arguments.

less.js

I also added a new option to less.js's less dictionary: less.globalVars. This is equivalent to --global-var (though with the same dictionary syntax for entries that less.modifyVars uses).

Here's an example with a Django template:

<script>
    less = {
        globalVars: {
            'static-url': '{{settings.STATIC_URL}}'
        }
    }
</script>

Use cases

There are some good use cases listed in this bug report, and in some other related reports. Ours is similar to the other base path use-cases. Essentially, we've standardized on less for all static media for extensions built for Review Board, and needed a way to provide some configuration-related variables to all bundled and extension-provided .less files, for the base path and for other bits of build-time configuration.

The variables we prepare are largely for the @import statements that may be in a file. The imports will be used to pull in common definitions and macros we ship (which may exist in different locations depending on whether it's using the runtime or being packaged). We'd use --global-var and less.globalVars for this.

When packaging, depending on the configuration of the server, certain variables may be overridden, and for this we'd use --modify-var and less.modifyVars.

@chipx86

This comment has been minimized.

Show comment
Hide comment
@chipx86

chipx86 Nov 16, 2013

Contributor

Thanks, Luke!

Contributor

chipx86 commented Nov 16, 2013

Thanks, Luke!

@CHH

This comment has been minimized.

Show comment
Hide comment
@CHH

CHH Nov 16, 2013

Thanks Luke!

Christoph Hochstrasser

http://twitter.com/hochchristophhttp://christophh.net
https://github.com/CHH

On Sat, Nov 16, 2013, at 12:40 AM, chipx86 wrote:

Thanks, Luke!

Reply to this email directly or [1]view it on GitHub.
[EFp1U5tejaLdqk9LbHMKEL7Q-W6JOsz4iEP2Y9uIwNW5-QMzGmE_sVezFZzQaE4a.gif]

References

  1. #731 (comment)

CHH commented Nov 16, 2013

Thanks Luke!

Christoph Hochstrasser

http://twitter.com/hochchristophhttp://christophh.net
https://github.com/CHH

On Sat, Nov 16, 2013, at 12:40 AM, chipx86 wrote:

Thanks, Luke!

Reply to this email directly or [1]view it on GitHub.
[EFp1U5tejaLdqk9LbHMKEL7Q-W6JOsz4iEP2Y9uIwNW5-QMzGmE_sVezFZzQaE4a.gif]

References

  1. #731 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment