Jump to content

How to - alternating chessboard


Peter Knight
 Share

Recommended Posts

Hi guys

Is there a way to call a Repeater content and specify that

Repeater item 1 should use mini template "odd"

repeater item 2 should use mini template "even".

I think that's half my battle. Basically, I have a weird little grid of cubes as follows

post-1166-0-23137900-1463577268_thumb.pn

I have it all working as basic CSS and HTML but I now need to make it client edit friendly.

I have some complexity in that:

1. Each text panel has a unique color (ideally specified by CSS)

2. On each row, the photo and text are on different sides

I was wondering if a repeater would work. I can certainly use that to allow client to add raw text and image. I then realised that allowing the client to add content isn't the challenge as much as outputting it correctly on the front end.

I'm having trouble understanding how I can tell the page to

  1. Make Row 1 use this blue background. Put the image on the right.
  2. Make Row 2 use this pink background. Put the image on the left.
  3. Make Row 3 use this other blue background. Put the image on the right.

I could always resort to plain non-repeater fields but I'd then have 6 fields etc :(

Link to comment
Share on other sites

These days I would handle this issue with CSS:

div:nth-of-type(even) {  }
div:nth-of-type(odd) { }

But since it took me a while to understand this modulus operator stuff I'll give you an example:

<?php

$i = 1;
foreach($page->repeater_field as $repeater) {
    $i++; // 2, 3, 4, 5, etc
    echo '<div class="' . ($i % 2 == 0 ? "odd-item" : "even-item") . '">'; // % is the modulus operator
    echo '</div>';
}
  • Like 5
Link to comment
Share on other sites

For such situations the profield matrix repeater module is a good option. It saved me a lot of headaches I would have faced if I have gone the ckeditor route.

  • Like 3
Link to comment
Share on other sites

For such situations the profield matrix repeater module is a good option. It saved me a lot of headaches I would have faced if I have gone the ckeditor route.

Ckeditor is certainly not suited for this. I can imagine that Profield Matrix can make things more intuitive for the Editor in the admin, however, I think it can be implemented with a simple repeater too, and it will be usable. It might depend on the amount of gray matter the client is equipped with :D

Also, we should not forget that simple repeaters might stop working around 50 items (Pages) depending on the available memory.

  • Like 3
Link to comment
Share on other sites

Would be also possible with PageTableExtended to render the setup in the backend use Drag&Drop and two settingsfields for the entries (colorselect and image left/right)...i use PTE as a contentblockbuilder on many cases this would be no problem.

  • Like 1
Link to comment
Share on other sites

Guys - thanks for the info and suggestions.

I'm currently playing with some modulus thingys :)

<?php

$i
= 1;
foreach($page->repeater_field as $repeater) {
$i++; // 2, 3, 4, 5, etc
echo '<div class="' . ($i % 2 == 0 ? "odd-item" : "even-item") . '">'; // % is the modulus operator
echo '</div>';
}

I can see how that applies and odd or even item class to a div.

I'd still need an "else" statement though to alternate the left and right photos but I think I can get there. 

Cheers

Link to comment
Share on other sites

Hello Peter,

Isn't something like this just what you need to add?:

div.odd-item img {float: right;}
div.even-item img {float: left;}

And adjusting the margins and/or paddings.

For a different background color on each row, are you going to use something like :nth-child(1), :nth-child(2)... [ https://developer.mozilla.org/en/docs/Web/CSS/:nth-child ] or :nth-of-type(1), :nth-of-type(2)... [ https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-of-type ]?

  • Like 1
Link to comment
Share on other sites

That the css way. You can also use php to achieve this:

$i = 1;

foreach($page->repeater_field as $repeater) {
    $i++; // 2, 3, 4, 5, etc
    $odd = $i % 2 == 0;

    if ($odd) {
        echo "<div class='item-$i item-odd'>"; // Use .item-1, .item-2, etc to style
        /* OR */ echo "<div class='item-$i item-odd' style='background:{$repeater->color_field}'>"; // Or use a the color field by soma to select color in repeater
        echo $repeater->text; // Left
        echo $repeater->image; // Right
        echo "</div>";
    } else {
        echo "<div class='item-$i item-even'>";
        echo $repeater->image; // Left
        echo $repeater->text; // Right
        echo "</div>";
    }    
}

This could be written less verbose, but I think it gets the point accross.

  • Like 5
Link to comment
Share on other sites

Hello Peter,

Isn't something like this just what you need to add?:

div.odd-item img {float: right;}
div.even-item img {float: left;}

hey Chris

That would work. I'm using a responsive framework in there so need to adhere a little to it's setup.

Link to comment
Share on other sites

That the css way. You can also use php to achieve this:

$i = 1;

foreach($page->repeater_field as $repeater) {
    $i++; // 2, 3, 4, 5, etc
    $odd = $i % 2 == 0;

    if ($odd) {
        echo "<div class='item-$i item-odd'>"; // Use .item-1, .item-2, etc to style
        /* OR */ echo "<div class='item-$i item-odd' style='background:{$repeater->color_field}'>"; // Or use a the color field by soma to select color in repeater
        echo $repeater->text; // Left
        echo $repeater->image; // Right
        echo "</div>";
    } else {
        echo "<div class='item-$i item-even'>";
        echo $repeater->image; // Left
        echo $repeater->text; // Right
        echo "</div>";
    }    
}

This could be written less verbose, but I think it gets the point accross.

Arjen - that's very cool. Thanks :)

I've adapted it slightly to my requirements but it's going to come in very useful.

I notice that the numbering is a little off for me.

My three rows start at 2 instead of 1. Not a big deal - I'm fiddling with the setup now.

Link to comment
Share on other sites

Sure. $i starts at 2 in the foreach statement.

I guess you can do something like

$row -= $i

if ($odd) {
echo "<div class='item-$row item-odd'>"; // Use .item-1, .item-2, etc to style
/* OR */ echo "<div class='item-$row item-odd' style='background:{$repeater->color_field}'>"; // Or use a the color field by soma to select color in repeater
...
} else {
echo "<div class='item-$row item-even'>";
...

I haven't eaten yet today, so I could be wrong...

Perhaps you have already done something similar to this...

Link to comment
Share on other sites

These days I would handle this issue with CSS:

div:nth-of-type(even) {  }
div:nth-of-type(odd) { }

Just wanted to throw a quick +1 to this approach. CSS classes like .even and .odd are very much a thing of the past and generally speaking one should steer away from those. Also: I'm having hard time imagining a front-end framework that doesn't support some variation of source ordering (pull/push classes) :)

  • Like 1
Link to comment
Share on other sites

My only issue with those otherwise great pseudo-classes is that they increase the selectors specificity. They just cannot be overwritten anymore by any styles added via a class. Otherwise I would also use :not() far more often.

Link to comment
Share on other sites

Not entirely sure we're on the same page here, so just to clarify: what exactly do you mean by not being able to overwrite these? Just in case I prepared a little demo here: https://weekly.pw/odd.html. Seems to me that overwriting :nth-child() with a class works just fine, but then again, I'm probably missing your point here  :)

  • Like 1
Link to comment
Share on other sites

So the gist of this issue is what Martijn said above: pseudo-classes and classes have the same specificity.

Actually I was under the assumption that this would be the case, though I'm not sure if I've ever actually checked. It's just that this makes a lot of sense considering that pseudo-classes are essentially a way to support stuff like .odd, .even, .first, .last and .list-item-number-3653 without actually cluttering your markup with a whole bunch of style-related stuff.

This doesn't, though, mean that you can't override these; just that you'll have to be specific with your selectors. Just like in any other language, CSS also requires you to be exact with what you mean. I also don't see this as a very good reason to ditch the pseudo-class stuff, especially if the alternative is to write new code to generate an army of classes for identifying parity, position, order, etc.

In my humble opinion it's an awful practice to use markup (even classes) to generate what should – and could – be purely a question of style, even more so when code is required to generate that markup. At the same time I do also tend to steer away from some variations of ::before / ::after + content(), for the same exact reason: CSS should define style, not content, unless that content is strictly for the looks and doesn't provide any real value  :)

Link to comment
Share on other sites

In my humble opinion it's an awful practice to use markup (even classes) to generate what should – and could – be purely a question of style, even more so when code is required to generate that markup. At the same time I do also tend to steer away from some variations of :after + content(), for the same exact reason: CSS should define style, not content, unless that content is strictly for the looks and doesn't provide any actual value :)

In basics my opinion is very simple, when removing stylesheets & scripts, the leftover should be good structured and meaning full Markup. Not markup that is designed to make it look better.  What you see a lot in the so called frameworks is a grid system based on rows and columns. In most use cases those row divs are purely there for visualising, and they div(ide) content where the content should not be divided. 

Classes are meaningless for Markup, what I mean by this is that a <p> stays <p> even when the <p> has a class.  So my opinion: classes are perfectly valid for visuals without altering the meaning. Pseudo elements can really help to make your markup as meaningful as possible. With pseudo you can left out that break, clear a float, etc etc, without using markup. Some people point out that html should be re-useable, so classes can be a 'pain in the ass', but my opinion is different for this as I haven't had a single project where I re-used big blocks of HTML.

  • Like 2
Link to comment
Share on other sites

For the most part I agree: classes don't have actual semantic meaning, so technically speaking they're fine, and I believe we're pretty much on the same page regarding pseudo elements too. It's just that I've recently started to emphasise pseudo-elements over classes whenever it makes sense. There are many cases where it doesn't make sense, but for something as simple as alternating background colors for predefined elements it fits the bill perfectly.

I've also grown tired of trying to guess which classes I should add to my markup in order to make it easy enough to style, and I strongly dislike having to change any aspect of the markup (including generated classes) if I later on decide that I need to do something purely style-related – such as make odd items have a different background color. Pseudo elements are awesome for separation of concerns, and they can reduce the clutter quite a bit.

While classes rarely add a considerable amount of extra weight to the document, unless we're talking about a serious case of classitis combined with extremely large scale use, that's another (however minor) argument against them: why add something that isn't required in the first place :)

  • Like 4
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...