tags:

views:

150

answers:

6

Anyone know of any classes written for php that can clean up your code a bit?

Something like,

$htGen = new HTMLGenerator();
$htGen->newDOM('div', 'here is what goes in the div', 'optionalID', 'optionalClass');

Or does that just sound redundant?

I end up with some complex looking mish-mashes of html and php sometimes that I feel could be simplified a bit eg my latest cms bit;

foreach($details as $detail){

    $d = unserialize($detail);

    if($ad){
        print_r($d); // <-- VIEW DETAIL OBJECT IN WHOLE.
    }else{
    if($d->get_info('orphan')){
        echo '<li class="classRow orphan">' . "\n";
        echo '<div class="orphan" style="display:none">orphan</div>' . "\n";
    }else{
        echo '<li class="classRow">' . "\n";
        echo '<div class="orphan" style="display:none"></div>' . "\n";
    }

        echo '<div  class="classNumbers" id="' . $d->get_info('class ID') .  '" style="display:none"></div>' . "\n"; 
        echo '<div class="rowBG" style="overflow:hidden;width:100%">';   
            echo '<div class="startTime"></div>' . "\n";
            echo '<div class="details"><span class="classes">' . $d->get_info('class number') . '</span> - <input class="detailInput" type="text" value="' . $d->get_info('class description') . '"/><div class="editButton"><a class="editExpand">options(+)</a></div></div>' . "\n";
            echo '<div class="interval">';
            echo '<input class="intervalInput" type="text" value="' . $d->get_info('interval') . '" maxlength="5"/>';
            echo '</div>' . "\n"; 
            echo '<div class="numRiders"><input class="numRidersInput" type="text" value="' . $d->get_info('num riders') . '"/></div>' . "\n"; 
        echo '</div>'; 

        echo '<div class="classOptions">' . "\n";
            echo '<div class="selectRingMove">Move to Ring:<select id="ringSwap"><option>Select A Ring</option>' . get_ring_options() .  '</select></div>' . "\n";
            if($d->get_info('online sign up') != 'false'){
                echo '<div class="signUpContainer">Sign-Up<input type="checkbox" class="signUp" checked/></div>' . "\n";
            }else{
                echo '<div class="signUpContainer">Sign-Up<input type="checkbox" class="signUp"/></div>' . "\n";
            }
            if($d->get_info('water and drag')){
                echo '<div class="wdBoxContainer"><select id="wdDescrip"><option>WATER AND DRAG</option><option>COURSE CHANGE & WALK</option><option>OTHER</option></select><input type="checkbox" class="wdBox" checked/><input type="text" value="' . $d->get_info('water and drag') .  '" maxlength="2" class="wdInput"> min</div>' . "\n";
            }else{
                echo '<div class="wdBoxContainer"><select id="wdDescrip"><option>WATER AND DRAG</option><option>COURSE CHANGE & WALK</option><option>OTHER</option></select><input type="checkbox" class="wdBox"/><input type="text" value="20" maxlength="2" class="wdInput"> min</div>' . "\n";
            }
            if($d->get_info('ghost riders')){
                echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" checked class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput" value="' . $d->get_info('ghost riders') .  '"></div>' . "\n";
            }else{
                echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput"></div>' . "\n";
            }

        echo '</div>' . "\n";

    echo '</li>' . "\n";

    if($d->get_info('water and drag')){
        echo '<li class="waterAndDragRow" style="display:block;"><span class="wdStartTime">08:33am</span> - <span class="wdEndTime">08:34am</span> <input type="text" class="wdDescription" value="' . $d->get_info('water and drag description') . '"></li>';
    }
    }
}

Or, if you know of a cleaner way to write long blocks of intermingled php vars and html... (not a big fan of EOF>>>)

Thanks in advance.

+5  A: 

I guess it could be done with http://www.php.net/manual/en/class.domdocument.php. But that isn't really a good way to do it.

I agree that your code code sample isn't very clear, you could consider something like:

<ul>
<?php foreach ($items as $item): ?>
    <li>
        <?=$item['something']?>
        <?php if ($item['foo'] == 'bar'): ?>
        <ul>
            <li>bar</li>
        </ul>
        <?php else: ?>
        <ul>
            <li>foo</li>
        </ul>
        <?php endif; ?>
    </li>
<?php endforeach; ?>
<ul>

That's a lot better imho, I use it like that in my views.

Btw, you should validate your html output. For example, a div-element isn't allowed in a li-element.

edit: Obviously, the following code:

<?php if ($item['foo'] == 'bar'): ?>
<ul>
    <li>bar</li>
</ul>
<?php else: ?>
<ul>
    <li>foo</li>
</ul>
<?php endif; ?>

Could be replaced by:

<ul>
    <li><?=($item['foo'] == 'bar' ? 'bar' : 'foo')?></li>
</ul>
GuidoH
+1 I normally don't like to use short tags but this was what I was going to tell me him to do (with normal php tags)
AntonioCS
Short tags are okay, as long as it's enabled on your sever. Some say that they're deprecated and will be deleted in PHP6, that's definitely **NOT** true.
GuidoH
+2  A: 

I'll probably get downvoted for recommending short tags, but here's what I do. I put all the <? and ?> tags at column 1 so that the code reads like a mix of PHP and HTML. No echo statements is the goal.

    foreach ($details as $detail) {
        $d = unserialize($detail);

        if ($ad) {
            print_r($d); // <-- VIEW DETAIL OBJECT IN WHOLE.
        }
        else {
            if ($d->get_info('orphan')) {
?>              <li class="classRow orphan">
                  <div class="orphan" style="display:none">orphan</div>
<?          }
            else {
?>              <li class="classRow">
                  <div class="orphan" style="display:none"></div>
<?          }

?>          <div class="classNumbers" id="<?= $d->get_info('class ID') ?>"
                 style="display:none"></div> 
            <div class="rowBG" style="overflow:hidden;width:100%">
              <div class="startTime"></div>
              <div class="details">
                <span class="classes"><?= $d->get_info('class number') ?></span> -
                <input class="detailInput" type="text" value="<?= $d->get_info('class description') ?>"/>
                <div class="editButton">
                  <a class="editExpand">options(+)</a>
                </div>
              </div>
              <div class="interval">
                <input class="intervalInput" type="text" value="<?= $d->get_info('interval') ?>" maxlength="5"/>
              </div>
              <div class="numRiders">
                <input class="numRidersInput" type="text" value="<?= $d->get_info('num riders') ?>"/>
              </div>
            </div>

            <div class="classOptions">
              <div class="selectRingMove">
                Move to Ring:
                <select id="ringSwap">
                  <option>Select A Ring</option>
                  <?= get_ring_options() ?>
                </select>
              </div>

<?            if ($d->get_info('online sign up') != 'false') {
?>                <div class="signUpContainer">
                    Sign-Up
                    <input type="checkbox" class="signUp" checked/>
                  </div>
<?            }
              else {
?>                <div class="signUpContainer">
                    Sign-Up
                    <input type="checkbox" class="signUp"/>
                  </div>
<?            }

              if ($d->get_info('water and drag')) {
?>                <div class="wdBoxContainer">
                    <select id="wdDescrip">
                      <option>WATER AND DRAG</option>
                      <option>COURSE CHANGE &amp; WALK</option>
                      <option>OTHER</option>
                    </select>

                    <input type="checkbox" class="wdBox" checked/>
                    <input type="text" value="<?= $d->get_info('water and drag') ?>" maxlength="2" class="wdInput"> min
                  </div>
<?            }
              else {
?>                <div class="wdBoxContainer">
                    <select id="wdDescrip">
                      <option>WATER AND DRAG</option>
                      <option>COURSE CHANGE &amp; WALK</option>
                      <option>OTHER</option>
                    </select>

                    <input type="checkbox" class="wdBox"/>
                    <input type="text" value="20" maxlength="2" class="wdInput"> min
                  </div>
<?            }

              if ($d->get_info('ghost riders')) {
?>                <div class="ghostRidersContainer">
                    Ghost Riders
                    <input type="checkbox" checked class="ghostBox">
                    <input type="text" maxlength="2" class="ghostRiderInput" value="<?= $d->get_info('ghost riders') ?>">
                  </div>
<?            }
              else {
?>                <div class="ghostRidersContainer">
                    Ghost Riders
                    <input type="checkbox" class="ghostBox">
                    <input type="text" maxlength="2" class="ghostRiderInput">
                  </div>
<?            }
?>          </div>
            </li>

<?          if ($d->get_info('water and drag')) {
?>              <li class="waterAndDragRow" style="display:block;">
                  <span class="wdStartTime">08:33am</span> -
                  <span class="wdEndTime">08:34am</span>
                  <input type="text" class="wdDescription" value="<?= $d->get_info('water and drag description') ?>">
                </li>
<?          }
        }
    }
John Kugelman
Nothing bad in short tags. It's just a configuration option.
Col. Shrapnel
+1 for short tags. May the PHP devs who've ever thought about deprecating or eliminating them reconsider their foolishness.
Weston C
Short tags aren't portable. Something to be aware of before you choose to do this.
banzaimonkey
@banzaimonkey it IS portable. Just turn it on. It's not as hard as it seems.
Col. Shrapnel
@Col.: Yes, it can be turned on, but remember not everyone has control over their servers.
Marcel Korpel
@Marcel and so what? Not everyone have PHP installed on their server. Or, say, a mod_rewrite. Is it a reason not to use it at all? The most portable web application is pure HTML one. Any other technology shouldn't be used because of that "not portable" fear. There are hundreds of configuration options in PHP. Why so much concern in that one?
Col. Shrapnel
Marcel Korpel
A: 

why not create your own clases?? or at least some functions... and i saw that you use alot of IF, you may clean it using vairables like when you have

if($d->get_info('ghost riders')){
            echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" checked class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput" value="' . $d->get_info('ghost riders') .  '"></div>' . "\n";
        }else{
            echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput"></div>' . "\n";
        }

you could write:

$check = ($d->get_info('ghost riders'))?"checked":"";
echo '<div class="ghostRidersContainer">Ghost Riders<input type="checkbox" '.$check.' class="ghostBox"><input type="text" maxlength="2" class="ghostRiderInput" value="' . $d->get_info('ghost riders') .  '"></div>' . "\n";

it will look cleaner :) I've created a Form class that helps me when i have to create forms and the code is more legible

pleasedontbelong
as a matter of fact, ternary operator looks ugly. as well as echoed HTML. But the point itself is right
Col. Shrapnel
+1  A: 

The main idea of generating HTML is to keep HTML as is.
Just divide your script into 2 parts: prepare data part and display data part. A latter one should contain mostly HTML with some PHP control structures. Of course, there should be as less PHP code as possible. Move all unnecessary PHP code into first part.

Well to sum up all of the above:
there should be nothing to unserialize in the $details array. Have your data prepared already

<? foreach ($details as $d): ?>              
<li class="classRow orphan">
  <div class="orphan" style="display:none"><? if ($d->get_info('orphan')): ?>orphan<? endif ?></div>
   <div class="classNumbers" id="<?= $d->get_info('class ID') ?>" style="display:none"></div> 
    <div class="rowBG" style="overflow:hidden;width:100%">
     <div class="startTime"></div>
      <div class="details">
       <span class="classes"><?= $d->get_info('class number') ?></span> -
        <input class="detailInput" type="text" value="<?= $d->get_info('class description') ?>"/>
         <div class="editButton">
          <a class="editExpand">options(+)</a>
         </div>
        </div>
        <div class="interval">
         <input class="intervalInput" type="text" value="<?= $d->get_info('interval') ?>" maxlength="5"/>
        </div>
        <div class="numRiders">
         <input class="numRidersInput" type="text" value="<?= $d->get_info('num riders') ?>"/>
        </div>
       </div>
       <div class="classOptions">
       <div class="selectRingMove">Move to Ring:
        <select id="ringSwap">
         <option>Select A Ring</option>
<?= foreach (get_ring_options() as $value => $option): ?>
     <option value="<?=$value?>"><?=$option?></option>
<? endforeach ?>
         </select>
       </div>
       <div class="signUpContainer">Sign-Up
        <input type="checkbox" class="signUp" <? if (!$d->get_info('online sign up'): ?>checked<? endif ?>/>
       </div>

and so on.

The main rule should be DRY: Do not Repeat Yourself. Do not repeat blocks of code if there is only one word difference.
But enclose that word into condition

Note that get_ring_options() was replaced with proper code.
Do not make functions that return HTML, but an array instead.

Col. Shrapnel
btw.. $details is an array of serialized objects... hence the unserialze(). Obviously you couldn't have known that ;)
Jascha
@Jascha it is obvious from the code. but it should not be serialized. Why to serialize at all? Make it array of objects. I've added some explanations to the answer
Col. Shrapnel
@Col.Shrapnel, I'm serializing it because it's data going in and out of a database.
Jascha
@Jascha serializing data that is going in and out of a database is **especially prohibited**. Anyway, you have to prepare your data first. Data preparation - first part. Data output - second part. DO NOT MIX
Col. Shrapnel
@Col.Shrapnel, Also, this is all part of a method named pring_list() buried in a class ScheduleUtils. My end product is <html><body><?php print_list(); ?></body></html> (simplified example).
Jascha
@Col.Shrapnel. Could you elaborate on the prohibition? I found it the simplest solution as I had an array of objects that I didn't want to break down into table columns. My process was to serialize my object, insert it in an array, json_encode that array and then real_escape my json_encoded array. It let me store large chunks of data in one column, rather than creating a whole table to store all of my objects vars. Does that sound completely wrong?
Jascha
@Jascha yes, that's right words: sound completely wrong. Database IS designed to have many columns and make relations and calculations between them. The way you are using a database, you don't need a database at all.
Col. Shrapnel
+1  A: 

Instead of a class, consider a library of functions to generate HTML. I didn't use a class to make the code that you end up writing concise but expressive. With a class you must create an instance and use that variable, or make the methods static and write static references.

With this technique creating HTML for an image that is a link looks like this:

a('/example/url', img('image_url', $altText));

This is based on a script I once created. First the generic functions to generate HTML elements and attributes:

function tag($tag, $text, $attributes = array()) {
    return "<$tag" . attributesToArray($attributes) . ">$text</$tag>";
}

function minimizedTag($tag, $attributes = array()) {
    return "<$tag" . attributesToArray($attributes) . " />";
}

function attributesToArray($attributes = array()){
    $a = '';
    foreach ($attributes as $attribute => $value) {
        $a .= " $attribute='$value'";
    }
    return $a;
}

Then add functions named according to the HTML elements they create, like a() and img() to create a link and image:

function a($link, $text, $attributes = array()) {
    $a = array('href' => $link);
    foreach ($attributes as $attribute => $value) {
        $a[$attribute] = $value;
    }
    return tag('a', $text, $a);
}

function img($url, $alt = null) {
    $a = array('src' => $url);
    if (!is_null($alt)){
        if (is_array($alt)){
            $a = array_merge($a, $alt);
        } else {
            $a['alt'] = $alt;
        }
    }
    return minimizedTag('img', $a);
}

Choose the parameters to pass common attributes wisely to make the library easier to use.

Kwebble
That reminds me of the late Doug Clifton, from whom I learned the basics of PHP. He also wrote something like that: http://loadaveragezero.com/vnav/labs/PHP/markup.php
Marcel Korpel
A: 

i'm making a class that create tags in xml and transform to html after. i'm still at the beginning.

sorry for my bad english

Mix Wipeout