PHPackages                             uestla/twigrid - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. uestla/twigrid

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

uestla/twigrid
==============

Experimental DataGrid for Nette Framework

12.1.1(5mo ago)1712.3k9[2 issues](https://github.com/uestla/twigrid/issues)[4 PRs](https://github.com/uestla/twigrid/pulls)1MITPHPPHP &gt;= 7.1.0CI passing

Since Apr 15Pushed 5mo ago4 watchersCompare

[ Source](https://github.com/uestla/twigrid)[ Packagist](https://packagist.org/packages/uestla/twigrid)[ Docs](https://github.com/uestla/TwiGrid)[ RSS](/packages/uestla-twigrid/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (7)Dependencies (12)Versions (71)Used By (1)

TwiGrid
=======

[](#twigrid)

... is a DataGrid for Nette Framework.

[![Buy me a Coffee](https://camo.githubusercontent.com/648ad6f048733f167bf65e11a4fd759eef14da88db61ad078bbd5ddea5d57133/68747470733a2f2f7777772e70617970616c6f626a656374732e636f6d2f656e5f55532f692f62746e2f62746e5f646f6e6174655f4c472e676966)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5UZMKSVARNKJL)

**Demo**:
**Demo sources**:

It's based on another (and great) datagrid written by @hrach - . My datagrid is hugely inspired by this component and its programming ideas and therefore I would like to give this man a maximum credit and respect :-)

Quickstart
==========

[](#quickstart)

Let's see how many steps do we have to make to create our first datagrid.

1. ### Create new project

    [](#create-new-project)

    ```
    composer create-project nette/web-project twigrid-quickstart
    ```
2. ### Install TwiGrid &amp; client-side assets

    [](#install-twigrid--client-side-assets)

    ```
    cd twigrid-quickstart
    composer require uestla/twigrid
    yarn add twigrid-datagrid --modules-folder www/assets/vendor
    ```

    > If you're not using yarn, you can install assets manually by looking into `package.json` and see required dependencies there.

    We'll then update `app/Presentation/@layout.latte` to load downloaded assets - just replace `{asset? 'main.js'}` with:

    ```

    {asset 'vendor/bootstrap/dist/css/bootstrap.min.css'}
    {asset 'vendor/twigrid-datagrid/assets/twigrid.datagrid.css'}

    {asset 'vendor/jquery/dist/jquery.min.js'}
    {asset 'vendor/bootstrap/dist/js/bootstrap.min.js'}
    {asset 'vendor/nette-forms/src/assets/netteForms.min.js'}
    {asset 'vendor/nette.ajax.js/nette.ajax.js'}
    {asset 'vendor/twigrid-datagrid/assets/twigrid.datagrid.js'}

    {asset 'script.js'}
    ```

    Then we'll create `www/assets/script.js` with Nette Forms and nette.ajax initialization:

    ```
    Nette.initOnLoad();

    $(function () {
    	$.nette.init();
    });
    ```
3. ### Database

    [](#database)

    Download [the SQLite3 file](https://github.com/uestla/twigrid-demo/raw/455d55d2e2a34bae9aaa64658bf8a4b6ddfca4a0/app/users.s3db) from the demo application and place it in `app/Model/users.s3db`.

    And we'll configure this database to be used by the application:

    ```
    # config/common.neon
    database:
    	dsn: 'sqlite:%appDir%/Model/users.s3db'
    ```
4. ### Create datagrid

    [](#create-datagrid)

    Now it's finally time to create our first datagrid - let's create an `app/Grids/UsersGrid.php` file. We'll need database connection for data loading, so we inject it properly via constructor.

    ```
    // app/Grids/UsersGrid.php

    /** @implements TwiGrid\DataGrid */
    final class UsersGrid extends TwiGrid\DataGrid
    {
    	public function __construct(
    		private readonly Nette\Database\Explorer $database,
    	) {
    		parent::__construct();
    	}

    	protected function build(): void
    	{
    		// TODO
    	}
    }
    ```

    We'll define the datagrid body inside the `build()` method. Although the table `user` has many columns, we'll have just some of them in our grid just to make it easy.

    ```
    // app/Grids/UsersGrid.php

    /** @implements TwiGrid\DataGrid */
    final class UsersGrid extends TwiGrid\DataGrid
    {
    	// ...

    	protected function build(): void
    	{
    		$this->addColumn('firstname', 'Firstname');
    		$this->addColumn('surname', 'Surname');
    		$this->addColumn('streetaddress', 'Street address');
    		$this->addColumn('city', 'City');
    		$this->addColumn('country_code', 'Country');
    	}
    }
    ```

    TwiGrid also needs to know what column(s) it should consider as a primary key:

    ```
    $this->setPrimaryKey('id');
    ```

    And finally we'll tell TwiGrid how to load our users:

    ```
    $this->setDataLoader(fn() => $this->database->table('user'));
    ```
5. ### Factory

    [](#factory)

    To properly inject our grid into presenters, we'll need to create a factory interface:

    ```
    // app/Grids/UsersGridFactory.php

    interface UsersGridFactory
    {
    	public function create(): UsersGrid;
    }
    ```

    This interface will now be used for automatic factory generation and autowired thanks to [SearchExtension](https://doc.nette.org/en/dependency-injection/configuration#toc-search), which is handy.
6. ### Presenter

    [](#presenter)

    Having all of this done, we can now simply inject our grid factory into `HomePresenter`.

    ```
    // app/Presentation/Home/HomePresenter.php

    final class HomePresenter extends Nette\Application\UI\Presenter
    {
    	public function __construct(
    		private readonly \UsersGridFactory $usersGridFactory,
    	) {
    		parent::__construct();
    	}
    }
    ```

    Now we'll add the control factory itself:

    ```
    // app/Presentation/Home/HomePresenter.php

    protected function createComponentUsersGrid(): \UsersGrid
    {
    	return $this->usersGridFactory->create();
    }
    ```
7. ### Render the grid

    [](#render-the-grid)

    We're nearly done! Just open `app/Presentation/Home/default.latte` and replace the whole content with

    ```
    {block content}

    		UsersGrid example

    		{control usersGrid}

    {/block}
    ```
8. ### Custom template

    [](#custom-template)

    Maybe showing the country code isn't that sexy - we'd like to have the whole country name in "Country" column. To achieve that, we'll create custom grid template:

    ```
    {* app/Grids/UsersGrid.latte *}

    {extends $defaultTemplate}

    {define body-cell-country_code}
    	{$record->country->title}
    {/define}
    ```

    And tell TwiGrid to use this template:

    ```
    // app/Grids/UsersGrid.php::build()

    $this->setTemplateFile(__DIR__ . '/UsersGrid.latte');
    ```

    That's all, folks!

    Now when you'll open the page, you might see something like this:

    [![Result screenshot](https://camo.githubusercontent.com/317a40d1bb79bf705de89790f6b2ff10b60d96146f8c362364ec293648ae2d9b/68747470733a2f2f692e696d6775722e636f6d2f37793844306f772e706e67)](https://camo.githubusercontent.com/317a40d1bb79bf705de89790f6b2ff10b60d96146f8c362364ec293648ae2d9b/68747470733a2f2f692e696d6775722e636f6d2f37793844306f772e706e67)

More
----

[](#more)

To see more examples, please visit the [demo page](https://kesspess.cz/twigrid/). Enjoy!

###  Health Score

51

—

FairBetter than 96% of packages

Maintenance67

Regular maintenance activity

Popularity33

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity73

Established project with proven stability

 Bus Factor1

Top contributor holds 99% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~67 days

Recently: every ~314 days

Total

69

Last Release

172d ago

Major Versions

7.0.2 → 8.0.02016-07-05

8.0.2 → 9.0.02016-07-07

9.0.1 → 10.0.02016-07-08

10.0.2 → 11.0.02017-03-03

11.2.8 → 12.0.02019-10-11

PHP version history (3 changes)0.9.1PHP &gt;= 5.3.0

7.0.0PHP &gt;= 5.6.0

11.2.4PHP &gt;= 7.1.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/4d3a756def83a4d23274f1b7c7854f6eda71834901be89fc668f85f170f97653?d=identicon)[uestla](/maintainers/uestla)

---

Top Contributors

[![uestla](https://avatars.githubusercontent.com/u/373888?v=4)](https://github.com/uestla "uestla (378 commits)")[![MartinMystikJonas](https://avatars.githubusercontent.com/u/2094752?v=4)](https://github.com/MartinMystikJonas "MartinMystikJonas (2 commits)")[![Vlczech](https://avatars.githubusercontent.com/u/10884140?v=4)](https://github.com/Vlczech "Vlczech (2 commits)")

---

Tags

datagridfilteringgroup-actionsinline-editingnettepaginationphprow-actionssortingtwitter-bootstrapnettedatagridaddon

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/uestla-twigrid/health.svg)

```
[![Health](https://phpackages.com/badges/uestla-twigrid/health.svg)](https://phpackages.com/packages/uestla-twigrid)
```

###  Alternatives

[nette/code-checker

✅ Nette CodeChecker: A simple tool to check source code against a set of Nette coding standards.

881.7M6](/packages/nette-code-checker)[tomaj/nette-api

Nette api

36261.8k4](/packages/tomaj-nette-api)[ipub/gravatar

Gravatar creator for Nette Framework

122.0k1](/packages/ipub-gravatar)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
