Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically ordering HTML output from PHP

Tags:

php

I have a basic understanding of PHP, but I feel like what I am trying to do could by done in a much simpler way. I am using PHP to display HTML content for a Wordpress theme. I want users to be able to determine the order in which HTML "blocks" are displayed. Currently I am using an if/elseif setup. Here is an overly simplified example:

if ( $layout == 'layout_one' ) {
   echo '<div class="header">Header</div>';
   echo '<div class="content">Content</div>';
   echo '<div class="footer">Footer</div>';
} elseif ( $layout == 'layout_two' ) {
   echo '<div class="content">Content</div>';
   echo '<div class="header">Header</div>';
   echo '<div class="footer">Footer</div>';
} elseif ( $layout == 'layout_three' ) {
   echo '<div class="footer">footer</div>';
   echo '<div class="header">Header</div>';
   echo '<div class="content">Content</div>';
}

Now, this technique becomes an absolute bear due to the shear number of layout options (permutations). So in my mind you would write a separate function for each HTML content block, and then in some way have another function that presents them in the order specified by the user. Or maybe putting all the blocks into an array and then reordering the array based on the layout selection...

Anyway, I have hit a wall on how to actually do this. Any guidance would be greatly appreciated. Thanks

like image 386
ndiego Avatar asked Aug 23 '14 14:08

ndiego


1 Answers

This is not a trivial question; as the number of layout parts grows, it becomes more and more difficult to maintain. However I'm going to try to provide a "simple" solution for this.

Let's assume you have 3 parts, as in your example. However this should work for N parts. You set them in an array:

$parts = [
  0 => '<div class="header">Header</div>',
  1 => '<div class="content">Content</div>',
  2 => '<div class="footer">Footer</div>'
  ]

Then you want the combinations in a deterministic way. This is what I came up with, although I'm sure there's some algorithm to do all possible combinations (one example of an algorithm) so this step is automatic:

$layout_combinations = [
  0 => [0, 1, 2],
  1 => [0, 2, 1],
  2 => [1, 0, 2],
  3 => [1, 2, 0],
  4 => [2, 0, 1],
  5 => [2, 1, 0]
  ];

Do you really have $layout == 'layout_one'? We'll have to convert it:

$layout_number = [
  'layout_one'   => 0,
  'layout_two'   => 1,
  'layout_three' => 2,
  'layout_four'  => 3,
  'layout_five'  => 4,
  'layout_six'   => 5
  ];

To use it, after defining the parts above, simply do:

$layout = 'layout_four';

if (!array_key($layout, $layout_number))
  throw new Exception('Invalid layout');

$layout_number = $layout_number[$layout];

$layout_structure = $layout_combinations[$layout_number];

foreach ($layout_structure as $part_number) {
  echo $parts[$part_number];
  }

The main advantage is that it's very easily extensible. If you want to put another part, simply add it to the $parts array, add the corresponding new $layout_combinations and to the "english => number" conversion.

Note: a step could be prevented if $layout = 4 instead of $layout = 'layout_four'. This is highly preferable since it allow you to make it automatic, simply adding an element at the end of your $parts array.

like image 128
Francisco Presencia Avatar answered Oct 15 '22 19:10

Francisco Presencia