Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing variables to PHP before compile #48

Open
nesevis opened this issue Nov 19, 2013 · 23 comments
Open

Passing variables to PHP before compile #48

nesevis opened this issue Nov 19, 2013 · 23 comments

Comments

@nesevis
Copy link

nesevis commented Nov 19, 2013

Hi there. I am really enjoying using wp-less. However, there is a niggle:

I am trying to make individually styled pages through use of custom categories, meta fields, what have you.

The way I've done this in the past is to basically generate in-line CSS with PHP, based on what the $vars of the page are set to.

I have been trying to pass vars to wp-less for quite some time now, from header.php to functions.php, but have had no luck. Using my_less_vars(), add_var(), the $less->addVariable() method, etc have yielded no luck.

Manually changing the variables.less file to change colour values results in immediate change. But I want to do it as the page renders.

I am using the twitter bootstrap less framework, and enqueuing only bootstrap.less, which as you probably know @imports a whole bunch of .less files, one of which contains the relevant values: variables.less

Am I getting this ass backwards, or is something wrong? I am on a fresh install of WP 3.7.1 on Dreamhost. WP-less is the only plug-in installed.

@thom4parisot
Copy link
Owner

Let me know of this bit of documentation helps you achieving what you want :-)

@nesevis
Copy link
Author

nesevis commented Nov 19, 2013

@hi Thomas,

Thank you for getting back to me this quickly.

I realised I was playing with Bootstrap 2.3.2, and thought that might've caused my problems with PHP passing of variables, so I uploaded all the files from the js and less directories of the newest version of bootstrap to my theme directory (I had previously only embedded the generated bootstrap stylesheet, as this is a superfresh install).

After upgrading to 3.0.2 I got this error message:

Fatal error: Uncaught exception 'Exception' with message 'Failed to assign arg @list: /home/directory/domain/wp-content/themes/edit-communication/less/bootstrap.less on line 50' in /home/directory/domain/wp-content/plugins/wp-less/lib/vendor/lessphp/lessc.inc.php:3521 Stack trace: #0 /home/directory/domain/wp-content/plugins/wp-less/lib/vendor/lessphp/lessc.inc.php(2063): lessc_parser->throwError('Failed to assig...', 16848) #1 /home/directory/domain/wp-content/plugins/wp-less/lib/vendor/lessphp/lessc.inc.php(650): lessc->throwError('Failed to assig...') #2 /home/directory/domain/wp-content/plugins/wp-less/lib/vendor/lessphp/lessc.inc.php(503): lessc->zipSetArgs(Array, Array, Array) #3 /home/directory/domain/wp-content/plugins/wp-less/lib/vendor/lessphp/lessc.inc.php(586): lessc->patternMatch(Object(stdClass), Array, Array) #4 /home/directory/domain/wp-content/plugins/wp-less/lib/vendor/lessphp/lessc.inc.php(605): lessc->patternMatchAll(Array, Array, Array, Array) #5 /home/chriskol/edit2 in /home/directory/domain/wp-content/plugins/wp-less/lib/vendor/lessphp/lessc.inc.php on line 3521

Which seemed to be an issue with lessphp, so I got the newest version of that too, and updated the version sitting in the lib/vendor/ folder. That didn't help (it was probably the newest version anyway).

TL;DR: Not only can I not pass variables to the pre-compiled LESS file(s) with PHP, I can't even get it to render.

Questions:

—Assuming the $less-addVariable() option works, where should I be able to put it to effect change to the stylesheet before it has been compiled? From header.php? If only from functions.php— is it even possible to pass values to it as the page is rendering?
—Is the fact that I am only enqueuing bootstrap.less (consisting only of @import calls) a potential problem in "accessing" the pre-compiled @variables?

Thank you again,
On Tuesday, 19 November 2013 at 22:49, Thomas Parisot wrote:

Let me know of this bit of documentation (https://github.com/oncletom/wp-less/wiki/Advanced-Usage#registering-a-less-variable) helps you achieving what you want :-)


Reply to this email directly or view it on GitHub (#48 (comment)).

@thom4parisot
Copy link
Owner

Well this is documented in the previous link. You might register the variables too late.

As you are encountering many troubles, due to bootstrap version etc., I can't really tell if the problem is lying in defining variables or something else. If you define variables which are overridden by bootstrap, them comment them out in Bootstrap variables.less file so as you can have a full hand on them, dynamically from PHP.

@thom4parisot
Copy link
Owner

Otherwise try out with a simpler codebase, and then switch back to bootstrap to find out what the problem you encounter really is.

@nesevis
Copy link
Author

nesevis commented Nov 19, 2013

Thank you again, Thomas.

I'm back on bootstrap 2.3.2.

I manually unset two variables in variables.less (@black and @white). The rendering failed at first, as they weren't declared, but once I did a $less->addVariable and added them (with reversed values, white being black, etc) from header.php, it rendered with the correct—inverted—settings.

However, if e.g @black is already declared, then it cannot be changed from PHP. lessphp's function unsetVariable() isn't included in wp-less, so I have no way of checking if unsetting and then setting works. $less->setVariables(), the plural function, does not work if values have already been set either.

Interesting chicken egg situation going on here.
On Tuesday, 19 November 2013 at 23:24, Thomas Parisot wrote:

Otherwise try out with a simpler codebase, and then switch back to bootstrap to find out what the problem you encounter really is.


Reply to this email directly or view it on GitHub (#48 (comment)).

@thom4parisot
Copy link
Owner

Can you paste the code used to declare the variables? Because it could sound like a bug and I wonder why no one complained about it.

@nesevis
Copy link
Author

nesevis commented Nov 19, 2013

This is the code(s) I used. the addVariable() lines are commented out so I could check setVariables(). Both work when the variables are unset, but not at all when they are declared in variables.less.

$less = WPLessPlugin::getInstance();
// $less->addVariable('white','#000');
// $less->addVariable('black','#fff');
$less->setVariables(array(
'white' => '#000',
'black' => '#fff'
));

Hope it helps.

On Tuesday, 19 November 2013 at 23:40, Thomas Parisot wrote:

Can you paste the code used to declare the variables? Because it could sound like a bug and I wonder why no one complained about it.


Reply to this email directly or view it on GitHub (#48 (comment)).

@nesevis
Copy link
Author

nesevis commented Nov 19, 2013

I changed over to a .less stylesheet that consists of these simple lines:

@white: #fff;
@bodyBackground: @white;
@baseFontFamily: Arial, sans-serif;
@baseFontSize: 12px;
@baseLineHeight: 20px;
@textcolor: #333;

body {
margin: 0;
font-family: @baseFontFamily;
font-size: @baseFontSize;
line-height: @baseLineHeight;
color: @textcolor;
background-color: @bodyBackground;
}

…and the issue is still the same. Pre-declared variables cannot be written to, but unset ones are fine (this goes for both addVariable() and setVariables()).

WP 3.7.1, newest WP-less, newest lessphp, on Dreamhost.

I can't for the life of me understand what I'm doing wrong—if anything.

On Tuesday, 19 November 2013 at 23:42, Chris Kolbu wrote:

This is the code(s) I used. the addVariable() lines are commented out so I could check setVariables(). Both work when the variables are unset, but not at all when they are declared in variables.less.

$less = WPLessPlugin::getInstance();
// $less->addVariable('white','#000');
// $less->addVariable('black','#fff');
$less->setVariables(array(
'white' => '#000',
'black' => '#fff'
));

Hope it helps.


Chris Kolbu
+47 40552655 (Norway)
+61 (0) 481 366 664 (Australia)

On Tuesday, 19 November 2013 at 23:40, Thomas Parisot wrote:

Can you paste the code used to declare the variables? Because it could sound like a bug and I wonder why no one complained about it.


Reply to this email directly or view it on GitHub (#48 (comment)).

@thom4parisot
Copy link
Owner

They can be written. The thing is by writting @white: #fff;, you overwrite it in your less file:

  1. PHP is defining the less variable @white
  2. Your stylesheet is defining again the less variable @white

So that's perfectly normal. That's how your variables in PHP works: if you redefine them later, they are overridden.

In the last example if you remove @white: #fff; and use addVariable('white', '#000') the background will switch to black (hence leading to a very bad variable naming).

@nesevis
Copy link
Author

nesevis commented Nov 19, 2013

I chose to make white black to be able to see instantly if it actually took effect. I'll make it clearer for you:

  1. @white in variables.less is #fff
  2. @white as declared by me in header.php above wp_head() is #000
    Result: @white is rendered as #fff
  3. @white in variables.less is commented out (and will halt less->css compilation unless declared via php)
  4. @white as declared by me is #000
    Result: @white is rendered as #000—black.

My issue is that I cannot seem to overwrite an already declared variable, in this case @white.

On Wednesday, 20 November 2013 at 01:55, Thomas Parisot wrote:

They can be written. The thing is by writting @white: #fff;, you overwrite it in your less file.
So that's perfectly normal. That's how your variables in PHP works: if you redefine them later, they are overridden.
In the last example if you remove @white: #fff; and use addVariable('white', '#000') the background will switch to black (hence leading to a very bad variable naming).


Reply to this email directly or view it on GitHub (#48 (comment)).

@thom4parisot
Copy link
Owner

That's the expected behaviour. It is the same as:

// equivalent of `addVariable`/`setVariables`
@white: #000;

@import 'variables.less'

with

//variables.less
@white: #fff;   //this redefines @white which has been previously defined
@backgroundColor: @white;

Last declaration wins.

@nesevis
Copy link
Author

nesevis commented Nov 19, 2013

So what you're saying is that there is no way I can keep the declared values in variables.less as "defaults"—so if I want to have the option to style each of them individually, I'll need an enormous list of every single unset @variable to go through every single time, so not as to halt compilation of the css file?

Seems inelegant. Is there any way to change the order of that?

Now the order seems to be:

  1. Variables declared through PHP
  2. Variables declared through .less files
  3. Compilation

Can it be changed to

  1. Variables declared through .less files
  2. Variables declared through PHP
  3. Compilation

?

On Wednesday, 20 November 2013 at 02:05, Thomas Parisot wrote:

That's the expected behaviour. It is the same as:
// equivalent of addVariable/setVariables @white: #000; @import 'variables.less'
and
//variables.less @white: #fff;
Last declaration wins.


Reply to this email directly or view it on GitHub (#48 (comment)).

@thom4parisot
Copy link
Owner

Yep you got it. What I suggest you is to comment out only the variables you'd like to have an hand on, defining the default values in PHP and redefining then in PHP.

$less = WPLessPlugin::getInstance();

$less->setVariables(array(
  // ... default values
));

// later on according to the context
if (is_category()) {
  $less->addVariable('@backgroundColor', category_get_meta('background-color'));
}

Something like that (beware of not killing perfs by doing unnecessary database query).

@bassjobsen
Copy link

What @nesevis mentioned is related to leafo/lessphp#302

What I suggest you is to comment out only the variables

Does not seems a solution for me. I try to integrate your plugin with my theme which use Twitter's Bootstrap (see: bassjobsen/jbst#82). In this case i want to keep the original variables.less and overwrite some variables.

It doesn't matter at the moment cause PHPLESS doesn't support TB v 3.0.2 at all.

@thom4parisot
Copy link
Owner

Well, the goal of this plugin is to deal with LESS, not be an upgrade of it.

What I usually do, is to deal with import folders: my include directory first, then bootstrap folder.
So when I do a @import 'variables.less', it reads my variables, where this is relevant to strip out/comment variables you want to override.

So far I don't see any other alternative at the moment.

@bassjobsen
Copy link

You method can be some kind of compromise maybe by defining a custom variables.less. In this case Bootstrap's variables.less can be removed.
Also consider https://github.com/ldbglobe/lessphp/compare/patch-1

@qzminski
Copy link

qzminski commented Apr 2, 2014

It should be possible to override the variables. Those in the LESS file should be replaced by ones provided via PHP. Otherwise we cannot extend the default values (see Bootstrap case above) and we are forced to use some strange walkarounds.

+1 both hands for overriding the variables

@thom4parisot
Copy link
Owner

This issue is really related on how LESS handles the variable merging etc.

Any action from the plugin would simply be a quick and dirty patch modifying LESS logic (which other people rely on).

One of the latest addition of this plugin has been to be able to define the location of LESS.
This would address this issue IMO. Don't you think?

@qzminski
Copy link

qzminski commented Apr 4, 2014

Thanks for the reply. Well, where it has been said that the variables set from PHP have to be added to the beginning of the LESS file and not at the end (once all others are parsed)? I think it's a wrapper logic and not the LESS itself. Maybe it would be good to provide option to choose whether the default ones should be overridden or not?

@thom4parisot
Copy link
Owner

The plugin takes data, gives them to LESS and put the output in suitable WP directories.
That is the job of the plugin. And to do that as seamlessly as possible.

LESS does the munging, processing of the data and handles the variables, applies the functions and output that as CSS.

Overriding a variable is the business of LESS, as you want the parsing and CSS transpilation to be done differently. The plugin would expose a mechanism to do so, but *LESS is the candidate which would perform* that.

Now thinking about it, I especially say that because @bassjobsen's patch inspires me that thought.
If you had another way in mind to achieve that, at least share the algorithm you have in mind with simple words and bullet points so as we can figure out where to add this feature.

@qzminski
Copy link

qzminski commented Apr 6, 2014

Not having much time to think I ended up by removing the default variables from LESS and setting them directly from PHP. Just like suggested in the comment somewhere above.

@oncletom I am not sure how to implement that. Hopefully one day somebody will figure that out ;-)

@kenmorechalfant
Copy link

This has really been bothering me. I'd really prefer having defaults setup like I would normally.

It would be really cool if, instead of automatically importing variables added through PHP, we could choose a variable group like "colors" and then @import "@{colors}" specifically where we want it.

Then we could have a defaults at the top of the file and then import the PHP-set variables below that, so they can override if necessary. Just an idea.

@thom4parisot
Copy link
Owner

I agree but all this is related to how the less parser is working and scopes the variables.

If you think you can make it through this extension, please contribute/ask/discuss about how to ship it.
I would be super happy to help that to succeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants