Статьи

Вызов

Сколько усилий нужно, чтобы отобразить результаты запроса в HTML? Точнее, сколько строк кода?

Недавно Джейсон проделал потрясающую работу по объединению тега Data to Table для WACT .

Вы можете увидеть некоторые примеры того, что он делает здесь

Это хорошо, что я настолько безрассуден, что могу поспорить, что ты не сможешь победить в этом испытании

Соревнование

Ради того, чтобы хвастаться правами или просто развлекаться; используя любой язык программирования, который вам нравится, и любые общедоступные (т.е. доступные для загрузки) библиотеки, которые вы хотите, попробуйте получить те же результаты, что и в следующих трех примерах, с меньшим количеством строк кода.

Я знаю, что количество строк кода не обязательно является лучшим показателем ценности кода, но это стало одной из главных проблем в перестрелке J2EE против .NET Petstore, поэтому я считаю, что мы можем последовать примеру.

Чтобы установить сцену, таблица должна отображаться в формате HTML, как;


<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
      'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
  <head>
    <meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' />
    <title>The Table Challenge</title>
    <link href="example.css" type="text/css" rel="stylesheet"/>
  </head>
  <body>
    <h1>The Table Challenge</h1>

    <!-- The table goes here -->
    <core:placeholder id="Table"/>

  </body>
</html>

Тот тег — это место, где должна появиться ваша таблица (не стесняйтесь ее удалять — это еще один тег WACT, облегчающий мою жизнь).

Файл example.css, упомянутый выше, выглядит так:

 
html, body {
    font-family: georgia, serif;
}

/**
  Table related
*/
.data {
    color: blue;
    background-color: silver;
    border: ridge silver;
}
.data tr {
    vertical-align: top;
}

/* Real browsers only... */
.data tr:hover {
    background-color: yellow;
}

.data th {
    color: black;
    background-color: white;
    font-weight: bold;    
}
.data td {
    font-size: 80%;
}
.even {
    background-color: Bisque;
}
.odd {
    background-color: Silver;
}
.deprecated {
    background-color: DimGrey;
}

/**
  Pager related
*/
.pager {
    font-size: 80%;
    color: red;
}
.pager a:link {
    color: black;
}
.pager a:visited {
    color: navy;
}
.pager a:hover {
    background-color: yellow;
}

Мы не будем считать строки кода в приведенном выше HTML или CSS.

Схему базы данных (плюс примеры данных) для таблицы «phpmodules», использованной в примерах, можно найти здесь .

Пример 1: Простая таблица

Начиная этот пример просто показывает все столбцы в таблице phpmdules;

PHP Script (6 строк);

 
<?php
require '/home/hfuecks/wact/framework/common.inc.php';
require WACT_ROOT . '/template/template.inc.php';
require WACT_ROOT . '/db/db.inc.php';
$Page =& new Template('/example1.html');
$Page->setChildDataSource('MyTable',DBC::NewRecordSet('SELECT * FROM phpmodules'));
$Page->display();
?>

Шаблон (example1.html: 2 строки);

 
<core:WRAP file="layout.html" placeholder="Table" />
<data:table id="MyTable" tableclass="data" />

Всего линий: 8

Вот как это выглядит:

Вот снимок выходного HTML (пробелы отформатированы для удобства чтения);

 
    <h1>The Table Challenge</h1>

    <!-- The table goes here -->
    
    <table  id="MyTable" class="data" >
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Description</th>
            <th>Url</th>
            <th>Configuration</th>
            <th>Deprecated</th>
        </tr>
        <tr>
            <td>1</td>
            <td>Apache-specific Functions</td>
            <td>These functions are only available when running PHP as an Apache 1.x module.</td>
            <td>http://www.php.net/manual/en/ref.apache.php</td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>2</td>
            <td>Array Functions</td>
            <td>These functions allow you to interact with and manipulate arrays in various ways.</td>
            <td>http://www.php.net/manual/en/ref.array.php</td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td>3</td>
            <td>Aspell functions</td>
            <td>The aspell() functions allows you to check the spelling on a word and offer suggestions.</td>
            <td>http://www.php.net/manual/en/ref.aspell.php</td>
            <td>--enable-mailparse</td>
            <td>Y</td>
        </tr>

Пример 2: небольшое форматирование

В первом примере отображается слишком много информации. Сначала я хочу скрыть «Id», «Url» и «Устаревшие». Я также хочу, чтобы название модуля PHP было ссылкой на страницу в руководстве по PHP. Между тем строки должны отображаться чередующимися цветами строк, чтобы их было легче читать. И если модуль устарел, я хочу, чтобы другой, более темный, цвет строки указывал на это.

PHP Script (19 строк);

 
<?php
require '/home/hfuecks/wact/framework/common.inc.php';
require WACT_ROOT . '/template/template.inc.php';
require WACT_ROOT . '/db/db.inc.php';
class RowColorFilter {
    function doFilter(&$tpl, &$row, $rowNum) {
        if ( $row->get('Deprecated') == 'Y' ) {
            return 'deprecated';
        }
        if ( ($rowNum % 2) == 0 ) {
            return 'even';
        }
        return 'odd';
    }
}
$Page =& new Template('/example2.html');
$Table = & $Page->getChild('MyTable');
$Table->registerDataSet(DBC::NewRecordSet('SELECT * FROM phpmodules'));
$Table->registerRowCssClassFilter(new RowColorFilter());
$Page->display();
?>

Шаблон (9 строк):

 
<core:WRAP file="layout.html" placeholder="Table" />
<data:table id="MyTable" tableclass="data">
    <data:column name="Name">
        <data:cell><a href="{$Url}" target="_blank">{$Name}</a></data:cell>
    </data:column>
    <data:column name="Id" hide="true" />
    <data:column name="Url" hide="true"/>
    <data:column name="Deprecated" hide="true" />
</data:table>

Всего строк: 28

Хорошо, он немного подкрался, в основном благодаря введенному мной классу RowColorFilter, но такова цена удовлетворения требований пользователей.

Вот как это выглядит:

И фрагмент сгенерированного HTML;

 
    <h1>The Table Challenge</h1>

    <!-- The table goes here -->
    
    <table  id="MyTable" class="data" >
        <tr>
            <th>Name</th>
            <th>Description</th>
            <th>Configuration</th>
        </tr>
        <tr class="odd">
            <td><a href="http://www.php.net/manual/en/ref.apache.php" target="_blank">Apache-specific Functions</a></td>
            <td>These functions are only available when running PHP as an Apache 1.x module.</td>
            <td></td>
        </tr>
        <tr class="even">
            <td><a href="http://www.php.net/manual/en/ref.array.php" target="_blank">Array Functions</a></td>
            <td>These functions allow you to interact with and manipulate arrays in various ways.</td>
            <td></td>
        </tr>
        <tr class="deprecated">
            <td><a href="http://www.php.net/manual/en/ref.aspell.php" target="_blank">Aspell functions</a></td>
            <td>The aspell() functions allows you to check the spelling on a word and offer suggestions.</td>
            <td>--enable-mailparse</td>
        </tr>

Пример 3: Постраничный набор результатов

Теперь мы добираемся до нокаута … прямо сейчас таблица отображает все строки одновременно; не очень хорошая идея для загрузки базы данных плюс упорная работа для пользователей. Он определенно нуждается в «пейджере», поэтому мы видим только около 10 строк на страницу.

Скрипт PHP (20 строк):
(Нужно только изменить две строки кода…)

 
<?php
require '/home/hfuecks/wact/framework/common.inc.php';
require WACT_ROOT . '/template/template.inc.php';
require WACT_ROOT . '/db/db.inc.php';
class RowColorFilter {
    function doFilter(&$tpl, &$row, $rowNum) {
        if ( $row->get('Deprecated') == 'Y' ) {
            return 'deprecated';
        }
        if ( ($rowNum % 2) == 0 ) {
            return 'even';
        }
        return 'odd';
    }
}
$Page =& new Template('/example3.html');
$Pager = & $Page->getChild('ResultPager');
$Table = & $Page->getChild('MyTable');
$Table->registerDataSet(DBC::NewPagedRecordSet('SELECT * FROM phpmodules',$Pager));
$Table->registerRowCssClassFilter(new RowColorFilter());
$Page->display();
?>

Шаблон (22 строки):

 
<core:WRAP file="layout.html" placeholder="Table" />
<span class="pager">
    <page:navigator id="ResultPager" items="10">
        <page:first>First</page:first>
        <page:prev>Prev</page:prev>
        <page:list>
            <page:number>
            <page:elipses>...</page:elipses>
            <page:separator> </page:separator>
        </page:list>
        <page:next>Next</page:next>
        <page:last>Last</page:last>
    </page:navigator>
</span>
<data:table id="MyTable" tableclass="data">
    <data:column name="Name">
        <data:cell><a href="{$Url}" target="_blank">{$Name}</a></data:cell>
    </data:column>
    <data:column name="Id" hide="true" />
    <data:column name="Url" hide="true"/>
    <data:column name="Deprecated" hide="true" />
</data:table>

Строки кода в шаблоне прыгнули здесь, чтобы обеспечить полностью настраиваемый «пейджер».

Всего линий: 42

Теперь вы можете увидеть пейджер, расположенный прямо над столом:

Пейджер с результирующим набором «Google style» (содержит ссылки «Первый», «Предыдущий», «Следующий», «Последний» и ссылки на отдельные страницы).

Часть сгенерированного HTML;

 
    <h1>The Table Challenge</h1>

    <!-- The table goes here -->
    
    <span class="pager">
    
        First
        Prev
        1 <a  href="/wact/examples/apps/datatable/example3.php?page=2">2</a> 
        <a href="/wact/examples/apps/datatable/example3.php?page=3">3</a>
        <a href="/wact/examples/apps/datatable/example3.php?page=4">4</a> 
        <a href="/wact/examples/apps/datatable/example3.php?page=5">5</a>
        <a href="/wact/examples/apps/datatable/example3.php?page=6">6</a>

        <a  href="/wact/examples/apps/datatable/example3.php?page=2">Next</a>
        <a  href="/wact/examples/apps/datatable/example3.php?page=6">Last</a>
    
    </span>
    <table  id="MyTable" class="data" >
        <tr>
            <th>Name</th>
            <th>Description</th>
            <th>Configuration</th>
        </tr>
        <tr class="odd">
            <td><a href="http://www.php.net/manual/en/ref.apache.php" target="_blank">Apache-specific Functions</a></td>
            <td>These functions are only available when running PHP as an Apache 1.x module.</td>
            <td></td>
        </tr>
        <tr class="even">
            <td><a href="http://www.php.net/manual/en/ref.array.php" target="_blank">Array Functions</a></td>
            <td>These functions allow you to interact with and manipulate arrays in various ways.</td>
            <td></td>
        </tr>

Так что это проблема.

Пример 1: 8 строк

Пример 2: 28 строк

Пример 3: 42 строки

Будет интересно посмотреть, сможет ли кто-нибудь победить (или может быть обеспокоен).

И даже если вы можете разбить его на строки кода, все равно будет ли четкое разделение между логикой приложения и представлением? С помощью приведенных выше примеров вы можете просто передать CSS и шаблоны дизайнеру, и они смогут радикально изменить внешний вид, не касаясь PHP.

Вам также может быть трудно победить эти примеры по производительности …

Обратите внимание, что есть еще несколько вещей, которые вы еще не можете сделать с тегом таблицы данных, большинство редактируемых ячеек (поля ввода текста). WACT по-прежнему нуждается в фундаментальных изменениях, прежде чем это станет реальностью, но это не так уж и далеко.