1unitedpower: Projektvorstellung: Teein/Html eine Virtual DOM basierte Templating Engine für PHP 7.1

Beitrag lesen

problematische Seite

@@Felix Riesterer

Wie macht man das Folgende?

+-----------------------+
|     November 2017     | <caption>
+--+--+--+--+--+--+--+--+
|KW|Mo|Di|Mi|Do|Fr|Sa|So| <th>...
+--+--+--+--+--+--+--+--+
|45|30|31| 1| 2| 3| 4| 5|
|46| 6| 7| 8| 9|10|11|12| <th><td><td>...

Und das noch mit thead
|KW|Mo|Di|Mi|Do|Fr|Sa|So|

Und mit vordefinierten Spalten?

Ich früchtige euch mal beide in einer Antwort ab. Bevor ich den dynamischen Teil modelliere, will ich hier noch kurz eine 1-zu-1-Überstzung von Gunnars Codepen-Beispiel in Teein/Html vorführen.

table(class_('month'))(
    caption()(text('October 2017')),
    colgroup()(
        col(class_('week"')),
        col(class_('mo"')),
        col(class_('tu"')),
        col(class_('we"')),
        col(class_('th"')),
        col(class_('fr"')),
        col(class_('sa"')),
        col(class_('su"'))
    ),
    thead()(
        tr()(
            th()(text('week')),
            th()(text('Monday')),
            th()(text('Tuesday')),
            th()(text('Wednesday')),
            th()(text('Thursday')),
            th()(text('Friday')),
            th()(text('Saturday')),
            th()(text('Sunday'))
        )
    ),
    tbody()(
        tr()(
            th()(text('39')),
            td(class_('prev'))(text('25')),
            td(class_('prev'))(text('26')),
            td(class_('prev'))(text('27')),
            td(class_('prev'))(text('28')),
            td(class_('prev'))(text('29')),
            td(class_('prev'))(text('30')),
            td()(text('1'))
        ),
        tr()(
            th()(text('40')),
            td()(text('2'))),
            td(class_('holiday'))(text('3')),
            td()(text('4')),
            td()(text('5')),
            td()(text('6')),
            td()(text('7')),
            td()(text('8'))
        ),
        tr()(
            th()(text('41')),
            td()(text('9')),
            td()(text('10')),
            td()(text('11')),
            td()(text('12')),
            td()(text('13')),
            td()(text('14')),
            td()(text('15'))
        ),
        tr()(
            th()(text('42')),
            td()(text('16')),
            td()(text('17')),
            td()(text('18')),
            td()(text('19')),
            td()(text('20')),
            td()(text('21')),
            td()(text('22'))
        ),
        tr()(
            th()(text('43')),
            td()(text('23')),
            td()(text('24')),
            td()(text('25')),
            td()(text('26')),
            td()(text('27')),
            td()(text('28')),
            td()(text('29'))
        ),
        tr()(
            th()(text('41')),
            td()(text('30')),
            td()(text('31')),
            td(class_('next'))(text('1')),
            td(class_('next'))(text('2')),
            td(class_('next'))(text('3')),
            td(class_('next'))(text('4')),
            td(class_('next'))(text('5'))
        )
    )
)

Angenommen wir haben jetzt ein Model, aus dem die Daten für die Monatsansicht stammen, sagen wir sowas hier:

interface MonthSheet
{
    public function getMonthName() : string
    public function getYear() : int;

    /**
     * @return Week[]
     */
    public function getWeeks() : array
}

interface Week
{
    public function getNumber() : int;

    /**
     * @return Day[]
     */
    public function getDays() : array;
}

interface Day
{
    public function getDate() : int;
    public function isHoliday() : bool;
    public function isPrev() : bool;
    public function isNext() : bool;
}

Dann könnte man das folgende Template dafür bauen:

function viewMonthSheet(MonthSheet $sheet) : Element
{
    return table(class_('month'))(
        caption()(text("{$sheet->getMonthName()} {$sheet->getYear()}")),
        colgroup()(
            col(class_('week"')),
            col(class_('mo"')),
            col(class_('tu"')),
            col(class_('we"')),
            col(class_('th"')),
            col(class_('fr"')),
            col(class_('sa"')),
            col(class_('su"'))
        ),
        thead()(
            tr()(
                th()(text('week')),
                th()(text('Monday')),
                th()(text('Tuesday')),
                th()(text('Wednesday')),
                th()(text('Thursday')),
                th()(text('Friday')),
                th()(text('Saturday')),
                th()(text('Sunday'))
            )
        ),
        tbody()(...array_map('viewWeek', $sheet->getWeeks()))
    );
}

function viewWeek(Week $week) : Element
{
    return tr()(
        th()(text("{$week->getNumber()}")),
        ...array_map('viewDay', $week->getDays())
    );
}

function viewDay(Day $day) : Element
{
    $isPrev = $day->isPrev() ? 'prev' : '';
    $isNext = $day->isNext() ? 'next' : '';
    $isHolidy = $day->isHolidy() ? 'holiday' : '';
    return td(class_("{$isPrev} {$isNext} {$isHoliday}"))(text("{$day->getDate()}"));
}