Load variables into LESS CSS preprocessor from JSON file
Asked Answered
A

5

27

Is it possible to load variables into LESS CSS preprocessor from a JSON file like you can do with Stylus?

With contents of file myvars.json

{
    "color1": "#112345",
    "color2": "#667890"
}

In Stylus I do...

json('myvars.json')
body{ background-color: color1; }

Is it possible to do this in LESS?

I want to keep the file as JSON, so I can easily re-use it in javascript.

Adulterant answered 8/10, 2013 at 15:41 Comment(0)
M
20

In less.js you can make use of javascript interpolation (using the back-ticks). And call a function that loads the json object with the variables from the file ... from which you can extract the variable by its key - something in this direction perhaps:

@json_file: myvars.json;

@json: ~`json = function($key) { var request = new XMLHttpRequest(); request.open("GET", "@{json_file}", false); request.send(null); var my_json = JSON.parse(request.responseText); return my_json[$key]; }`;

body {
  background-color: ~`json('color1')`;
}

this might not look super elegant, but it works. A more elegant option would probably be to define your custom user function in the global LESS object before calling the script, but I never really bothered playing with that, as I was always using LESS client-side just in development.

Another thing that you can do - is loading the json file in javascript (after calling the LESS script in the browser) and using the less.modifyVars() function to recompile LESS with the json variables. You can do something along this lines in your html (here I use plain JS but it's even simpler if you use jQuery.getJSON):

<link rel="stylesheet/less" href="style.less" type="text/css">
<script type="text/javascript">less = { env: "development" };</script>
<script src="http://rawgithub.com/less/less.js/master/dist/less-1.4.1.min.js" ></script>
<script type="text/javascript">
    var request = new XMLHttpRequest();
    request.open("GET", "myvars.json", false);
    request.send(null);
    var my_json = JSON.parse(request.responseText);
    less.modifyVars(my_json);
</script>

and something like this in your LESS style file:

@color1: darkblue; //default value - will get overwritten by .modifyVars()

body {
  background-color: @color1;
}

Another note: all variable names in LESS have to begin with an at sign (@). However, the json variables do not need to, because less.modifyVars() automatically prepends the variables with an @ if missing.

Hope this gives you some ideas. There might be better ways to do it ... but this two approaches worked for me.

Materialist answered 9/10, 2013 at 2:29 Comment(0)
B
3

If you not use LESS in browser but compile the CSS, I just publish a gulp plugin to do this job.

It can look like this :

css/myvars.json

{
    "color1": "#112345",
    "color2": "#667890"
}

less/styles.less

@json-import "myvars.json";

body {
  background-color: @color1;
}

gulpfile.js

var gulp = require('gulp');
var less = require('gulp-less');
var lessJsonImport = require('gulp-less-json-import');

gulp.task('less', function(){ 
  gulp.src(['./less/**/*.less', '!./less/**/_*.less'])
      .pipe(lessJsonImport())
      .pipe(less())
      .pipe(gulp.dest('./css'));
});
Bally answered 6/7, 2016 at 13:35 Comment(0)
A
0

When using LESS in browser, there is also 'globalVars' option that can be used to set variables before loading the LESS files: http://lesscss.org/usage/#using-less-in-the-browser-options

Alevin answered 10/8, 2015 at 13:20 Comment(0)
B
0

You can use globalVars less option to provide object loaded from json file.

For example with less-loader plugin webpack.config.js will be like:

function lessGlobalVars() {
    return require('flat')(require('./path/to/config.json'),
        {
            delimiter: '_'
        });
}

module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'less-loader',
            options: {
              globalVars: lessGlobalVars()
            }
          }
        ]
      }
    ]
  }
};

config.json:

{
  "dimensions": {
    "width": 100,
    "height": 50
  }
}

globalVars accepts only flat structures so we need flat package that will flatten object loaded with require('./path/to/config.json') to:

{
  dimensions_width: 100,
  dimensions_height: 50
}

Passing this object to globalVars option will make global variable @dimensions_width and @dimensions_height available for all your less stylesheets:

.some-class {
  width: @dimensions_width;
  height: @dimensions_height;
}
Bogbean answered 28/6, 2019 at 12:20 Comment(0)
S
0

A relatively new approach is described here:

myPluginFile.js:

const axios = require('axios').default

module.exports = {
  install: function (less, pluginManager, functions) {
    functions.add("blue", function () {

      const headers = {
        'Access-Control-Allow-Origin': '*',
        'Content-Type': 'application/json',
        timestamp: +new Date(),
      }  
      
      try {
        const method = 'get'
        const url = 'https://myAPI.com/myFile.json'
        const options = { headers: { ...headers } }
        const { data } = await axios[method](url, {}, options)
        return data
      } catch (error) {
        console.info('Error', { msg: error.message })
      }
    });
  },
};

myStyleFile.less:

@plugin "myPluginFile";

/* Style the body */
body {
  color: blue();
}
Stephaniastephanie answered 12/3, 2021 at 2:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.