3

I am creating a themeing system for a WordPress network that supports multiple layout themes that can support color schemes for a variety of universities. To do so, I periodically compile a LESS file (using lessphp) with school-specific variables and essentially use it as a library of helper classes in the themes.

Each school has 3 colors defined in LESS as: @primary, @secondary and @tertiary. The method is straightforward and functional but requites a lot of repetition in the code. For example:

//Modifier Classes
  .primary-lighter-text {
      color: lighten(@primary,20);
  }
  .sec-lighter-text {
      color: lighten(@secondary,20);
  }
  .tert-lighter-text {
      color: lighten(@tertiary,20);
  }
//Backgrounds
  .primary-bg {
      background-color: @primary;
  }

  .sec-bg {
      background-color: @secondary;
  }

  .tert-bg {
      background-color: @tertiary;  
  }

//Borders
  .primary-border{
      border-color: @primary;
  }
  .sec-border {
      border-color: @secondary;
  }
  .tert-border {
      border-color: @tertiary;      
  }

Nothing complicated from a LESS standpoint, but if I want to add a new helper class, I have to create 3. Is there a more succinct way to achieve this?

Andrew Cafourek
  • 431
  • 4
  • 11

1 Answers1

3

You can simplify it by making use of array loops. All you have to modify in case of a new addition would be to modify the array variables at the end.

.loop-column(@index) when (@index > 0) { /* Recursive Mixin with Guard condition. Mixin is processed only when the condition is satisfied */
  .loop-column(@index - 1); /* Call the mixin again with a decremented counter */
  @ctype:  extract(@type, @index); /* Extract the type value corresponding to the index from the array */
  @color:  extract(@colors, @index); /* Extract the color value corresponding to the index from the array */

  /* Form and Output the necessary classes and properties */
  .@{ctype}-lighter-text { /* Selector interpolation to dynamically form the selector */
    color: lighten(@color,20);
  }
  .@{ctype}-bg {
    background-color: @color;
  }
  .@{ctype}-border{
    border-color: @color;
  }  
}

.loop-column(length(@type));

@type: primary, sec, tert; /* The color types array */
@colors:#fff, #777, #000; /* The color value array for each type */
/* If required the colors can be kept as separate variables also. Refer 2nd demo. */

Demo | Demo 2

Update: (Based on comments from Andrew Cafourek and seven-phases-max)

Since LessPHP is outdated, the following line should be added and the length(@type) should be replaced with the actual count.

.loop-column(0) {};
.loop-column(4);
Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214
  • Just spent some time reading up on recursive loops . They documentation makes them look terrifying but with an example to walk through, they start to make a lot more sense. Only trouble I'm hitting is that @index won't decrement. When I try to compile via lessphp, I received the error ``` Error: .loop is undefined: failed at `.loop-column(length(@type)); ``` So, I removed the length function and just used ``` .loop-column(3); ``` which worked. Now I receive the same error but ``` Error: .loop is undefined: failed at `.loop-column((@index - 1)); ``` Any thoughts on why I'm hitting a snag? – Andrew Cafourek Jul 15 '14 at 19:00
  • Same file compiles perfectly using CodeKit - I'll dig into the lessphp docs a bit. – Andrew Cafourek Jul 15 '14 at 19:09
  • 1
    Ah ha! Simply adding ``` .loop-column(0) {} ``` before ``` .loop-column(3); ``` did the trick. Future visitors, see example in [lessphp docs](http://leafo.net/lessphp/docs/#selector_expressions). It still throws and error if I try and use ``` length(@type) ``` but I can live with that and it all works straight out of the demo from @harry if you are using CodeKit locally – Andrew Cafourek Jul 15 '14 at 19:20
  • 1
    That's just because `lessphp` is outdated. You can simplify loops further (e.g. see http://stackoverflow.com/q/23551080/2712740 with similar use-case, notice that the second example there does not use loops at all) but all this requires an up-to-date Less compiler. – seven-phases-max Jul 16 '14 at 04:08