bugo/smf-bricks

Collection of some building blocks for SMF

0.4 2025-02-01 04:12 UTC

This package is auto-updated.

Last update: 2025-03-01 04:33:39 UTC


README

SMF 2.1 PHP Coverage

По-русски

These helpers will be useful for simplifying the code of tables and forms when creating modifications to Simple Machines Forum.

Installing

In the root directory of your modification, run the command:

composer require bugo/smf-bricks

Then, include autoload.php in your code:

require_once __DIR__ . '/vendor/autoload.php';

Tables

The simple table builder TableBuilder::make() — you just need to provide the data, and you'll get a table styled like on the forum:

preview

Anyone who has ever set up a table structure in SMF 2.1 knows that you first create an array called $listOptions with the key settings. This array looks bigger the more columns you need to include in it:

<?php

global $context, $sourcedir;

$listOptions = [
    'id' => 'table_id',
    'title' => 'Table title',
    'items_per_page' => 10,
    'no_items_label' => 'There is no data yet',
    'base_href' => $context['canonical_url'],
    'default_sort_col' => 'id',
    'get_items' => [
        'function' => [$this, 'getData'],
    ],
    'get_count' => [
        'function' => [$this, 'getNumData'],
    ],
    'columns' => [
        'id' => [
            'data' => [
                'db' => 'id',
            ],
            'sort' => [
                'default' => 'id DESC',
                'reverse' => 'id',
            ],
        ],
    ],
    'form' => [
        'href' => $context['canonical_url'],
    ],
];

require_once $sourcedir . '/Subs-List.php';

createList($listOptions);

$context['sub_template'] = 'show_list';
$context['default_list'] = 'group_lists';

So how can you create such a structure using TableBuilder? Thanks to the fluent interface, it's very elegant and simple:

$builder = TableBuilder::make('table_id', 'Table title')
    ->withParams(
        perPage: 10,
        noItemsLabel: 'There is no data yet',
        action: $context['canonical_url'],
        defaultSortColumn: 'id'
    )
    ->setItems($this->getData(...)) // You can also use arrays: [$this, 'getData']
    ->setCount($this->getNumData(...)) // You can also use arrays: [$this, 'getNumData']
    ->addColumn(IdColumn::make());

We build with the builder, and with the presenter, we display what we've built:

$renderer = new TableRenderer();
$presenter = new TablePresenter($renderer);
$presenter->show($builder);

Instead of the universal method withParams, there are also more specific ones: paginate, setNoItemsLabel, setFormAction, and setDefaultSortColumn.

Columns are created using Column::make():

Column::make('column_name', 'Column Header')
    ->setClass('CSS class for the column')
    ->setStyle('CSS style for the column')
    ->setData('key in the array returned by the getData method', 'CSS class for the data cell')
    ->setSort('column_name', 'column_name DESC'),

There are also several child methods that inherit from Column: IdColumn, CheckboxColumn. You can easily create similar ones for your projects. For example, IdColumn is just a wrapper for a structure like:

Column::make('id', '#')
    ->setStyle('width: 5%')
    ->setData('id', '', 'text-align: center')
    ->setSort('id DESC', 'id');

When adding multiple columns, you can use the method addColumns([Column::make(), Column::make(), ...]), which accepts an array of Column instances.

You can also add buttons ABOVE or BELOW the table using the methods addRows([Row::make($button1), Row::make($button2)]) or addRow(Row::make($button)), where Row::make accepts text or HTML. The position of the buttons can be changed using the setPosition method, which takes one of the values from the RowPosition enumeration. By default, the buttons are displayed below the table.

Forms

What could be more interesting than building all sorts of forms, especially in SMF? Of course, creating and using a FormBuilder for such forms:

$builder = FormBuilder::make('form_id', 'Form title')
	->setBodyClass('windowbg')
    ->setAction(Utils::$context['post_url'] ?? '');

You can add form fields in a container (by specifying the block class as the second parameter):

$builder->addFields([
    TextField::make('title', 'Title')
        ->setStyle('width: 100%')
        ->required()
        ->setPlaceholder('Enter title'),
    TextareaField::make('description', 'Description')
        ->setPlaceholder('Some description')
        ->setStyle('width: 100%'),
    SelectField::make('status', 'Status')
        ->setValue('inactive')
        ->setOptions([
            'active' => 'Active',
            'inactive' => 'Inactive'
        ]),
], 'roundframe');

Or without it:

$builder->addFields([
    ColorField::make('color', 'Color')
        ->setValue('#ff00dd'),
    EmailField::make('email', 'Email')
        ->setValue('no-reply@no-reply.com'),
    NumberField::make('number', 'Number')
        ->setValue(0)
        ->setMin(0),
    PasswordField::make('password', 'Password')
        ->readonly()
        ->setValue('password'),
    RangeField::make('range', 'Range')
        ->setValue(1)
        ->setMin(0)
        ->setMax(3)
        ->setStep(1),
    UrlField::make('url', 'URL')
        ->disabled()
        ->setSize(40)
        ->setValue('https://github.com/dragomano/SMF-Bricks'),
]);

You can add your own buttons at the bottom of the form, specifying a class for the container as well as a class for all buttons inside the container:

$builder->addButtons([
    ResetButton::make(),
    Button::make('button_name', 'Click me'),
    SubmitButton::make(),
], 'floatright', 'button');

You can also add hidden fields:

$builder->addHiddenFields([
    Utils::$context['session_var'] => Utils::$context['session_id']
]);

Of course, there is a dedicated presenter for FormBuilderFormPresenter, designed to display the built forms in the browser:

$renderer = new FormRenderer();
$presenter = new FormPresenter($renderer);
$presenter->show($builder);

preview

More usage examples can be found in the tests, as well as in the Light Portal project.