{"id":29711734,"url":"https://github.com/rougin/fortem","last_synced_at":"2026-05-31T03:01:46.994Z","repository":{"id":303043680,"uuid":"1014208030","full_name":"rougin/fortem","owner":"rougin","description":"Simple form templates in PHP.","archived":false,"fork":false,"pushed_at":"2026-05-30T16:28:44.000Z","size":84,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-30T18:12:45.966Z","etag":null,"topics":["html-form","php-form","php-ui-kit"],"latest_commit_sha":null,"homepage":"https://roug.in/fortem/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rougin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-05T09:01:46.000Z","updated_at":"2026-05-30T16:28:48.000Z","dependencies_parsed_at":"2025-07-05T10:45:10.921Z","dependency_job_id":"509e3e5b-266b-4287-b240-17bf8838db68","html_url":"https://github.com/rougin/fortem","commit_stats":null,"previous_names":["rougin/fortem"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/rougin/fortem","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rougin%2Ffortem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rougin%2Ffortem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rougin%2Ffortem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rougin%2Ffortem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rougin","download_url":"https://codeload.github.com/rougin/fortem/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rougin%2Ffortem/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33717419,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html-form","php-form","php-ui-kit"],"created_at":"2025-07-23T23:12:34.515Z","updated_at":"2026-05-31T03:01:46.988Z","avatar_url":"https://github.com/rougin.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fortem\n\n[![Latest Version on Packagist][ico-version]][link-packagist]\n[![Software License][ico-license]][link-license]\n[![Build Status][ico-build]][link-build]\n[![Coverage Status][ico-coverage]][link-coverage]\n[![Total Downloads][ico-downloads]][link-downloads]\n\nA collection of form templates for PHP with full support for [alpinejs](https://alpinejs.dev/) properties.\n\n``` php\n\u003cdiv\u003e\n  \u003c?= $form-\u003elabel('Name')-\u003easRequired() ?\u003e\n  \u003c?= $form-\u003einput('name')-\u003easModel() ?\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n  \u003c?= $form-\u003elabel('Description')-\u003easRequired() ?\u003e\n  \u003c?= $form-\u003einput('detail')-\u003easModel() ?\u003e\n\u003c/div\u003e\n\u003cdiv\u003e\n  \u003c?= $form-\u003ebutton('Update')-\u003eonClick('update(id)') ?\u003e\n\u003c/div\u003e\n```\n\n## Installation\n\nInstall the package using [Composer](https://getcomposer.org/):\n\n``` bash\n$ composer require rougin/fortem\n```\n\n## Basic usage\n\n\u003e [!NOTE]\n\u003e All elements below use [Bootstrap](https://getbootstrap.com/) classes by default. Use the `noStyling` method to opt out, or see [Restyling elements](#restyling-elements) to apply a custom CSS framework.\n\nThe `FormHelper` class provides an interface for creating labels, inputs, buttons, select dropdowns, and error messages:\n\n``` php\n// index.php\n\nuse Rougin\\Fortem\\Helpers\\FormHelper;\n\n$form = new FormHelper;\n\necho $form-\u003elabel('Name');\n```\n\n``` html\n\u003clabel class=\"form-label\"\u003eName\u003c/label\u003e\n```\n\n\u003e [!NOTE]\n\u003e See the next sections for the documentation of the abovementioned elements.\n\nThe `LinkHelper` class helps in generating and checking URLs to the template:\n\n``` php\nuse Rougin\\Fortem\\Helpers\\LinkHelper;\n\n$server = array();\n$server['HTTP_HOST'] = 'localhost';\n$server['REQUEST_URI'] = '/';\n\n$link = new LinkHelper($server);\n\necho $link; // http://localhost/\n```\n\nUse the `isActive` method to check if a given link is the current URL:\n\n``` php\n$current = $link-\u003eisActive('/'); // true\n```\n\nIf `HTTP_HOST` is not available, the `setBase` method can be used:\n\n``` php\nuse Rougin\\Fortem\\Helpers\\LinkHelper;\n\n$data = /** instaceof $_SERVER */;\n\n$link = new LinkHelper($data);\n\n$link-\u003esetBase('roug.in')\n\necho $link; // http://roug.in/\n```\n\n## Labels\n\nTo create a `\u003clabel\u003e` element, the `label` method is used:\n\n``` php\necho $form-\u003elabel('Name');\n```\n\n``` html\n\u003clabel class=\"form-label\"\u003eName\u003c/label\u003e\n```\n\nAdditional CSS classes can be appended using `withClass`:\n\n``` php\necho $form-\u003elabel('Name')-\u003ewithClass('text-uppercase');\n```\n\n``` html\n\u003clabel class=\"form-label text-uppercase\"\u003eName\u003c/label\u003e\n```\n\nTo remove the default styling, use the `noStyling` method:\n\n``` php\necho $form-\u003elabel('Name')-\u003enoStyling();\n```\n\n``` html\n\u003clabel\u003eName\u003c/label\u003e\n```\n\nA label can also be marked as required, which adds a red asterisk:\n\n``` php\necho $form-\u003elabel('Name')-\u003easRequired();\n```\n\n``` html\n\u003clabel class=\"form-label\"\u003eName \u003cspan class=\"text-danger\"\u003e*\u003c/span\u003e\u003c/label\u003e\n```\n\n## Inputs\n\nTo create an `\u003cinput\u003e` element, the `input` method is used. By default, it creates a `text` input:\n\n``` php\necho $form-\u003einput('name');\n```\n\n``` html\n\u003cinput type=\"text\" name=\"name\" class=\"form-control\"\u003e\n```\n\nAdditional CSS classes can be appended using `withClass`:\n\n``` php\necho $form-\u003einput('name')-\u003ewithClass('is-invalid');\n```\n\n``` html\n\u003cinput type=\"text\" name=\"name\" class=\"form-control is-invalid\"\u003e\n```\n\nThe input type can be changed using the `withType` method or the convenient `asEmail` and `asNumber` methods:\n\n``` php\necho $form-\u003einput('email')-\u003easEmail();\n```\n\n``` html\n\u003cinput type=\"email\" name=\"email\" class=\"form-control\"\u003e\n```\n\n``` php\necho $form-\u003einput('age')-\u003easNumber();\n```\n\n``` html\n\u003cinput type=\"number\" name=\"age\" class=\"form-control\"\u003e\n```\n\n## Buttons\n\nTo create a `\u003cbutton\u003e` element, the `button` method is used:\n\n``` php\necho $form-\u003ebutton('Submit');\n```\n\n``` html\n\u003cbutton type=\"button\" class=\"btn\"\u003eSubmit\u003c/button\u003e\n```\n\nAdditional CSS classes can be appended using `withClass`:\n\n``` php\necho $form-\u003ebutton('Submit')-\u003ewithClass('btn-primary');\n```\n\n``` html\n\u003cbutton type=\"button\" class=\"btn btn-primary\"\u003eSubmit\u003c/button\u003e\n```\n\nThe button type can be changed using the `withType` method:\n\n``` php\necho $form-\u003ebutton('Submit')-\u003ewithType('submit');\n```\n\n``` html\n\u003cbutton type=\"submit\" class=\"btn\"\u003eSubmit\u003c/button\u003e\n```\n\n## Select dropdowns\n\nTo create a `\u003cselect\u003e` element, the `select` method is used:\n\n``` php\n$items = array('Male', 'Female');\n\necho $form-\u003eselect('gender', $items);\n```\n\n``` html\n\u003cselect name=\"gender\" class=\"form-select\"\u003e\n  \u003coption value=\"\"\u003ePlease select\u003c/option\u003e\n  \u003coption value=\"0\"\u003eMale\u003c/option\u003e\n  \u003coption value=\"1\"\u003eFemale\u003c/option\u003e\n\u003c/select\u003e\n```\n\nAn associative array with `id` and `name` keys can also be provided:\n\n``` php\n$items = [ array('id' =\u003e 'm', 'name' =\u003e 'Male') ];\n$items[] = array('id' =\u003e 'f', 'name' =\u003e 'Female');\n\necho $form-\u003eselect('gender', $items);\n```\n\n``` html\n\u003cselect name=\"gender\"\u003e\n  \u003coption value=\"\"\u003ePlease select\u003c/option\u003e\n  \u003coption value=\"m\"\u003eMale\u003c/option\u003e\n  \u003coption value=\"f\"\u003eFemale\u003c/option\u003e\n\u003c/select\u003e\n```\n\n## Error messages\n\nThe `error` method is used to create a placeholder for validation error messages:\n\n``` php\necho $form-\u003eerror('error.name');\n```\n\n``` html\n\u003ctemplate x-if=\"error.name\"\u003e\n  \u003cp class=\"text-danger small mb-0\" x-text=\"error.name[0]\"\u003e\u003c/p\u003e\n\u003c/template\u003e\n```\n\n\u003e [!NOTE]\n\u003e This is only works when integrated in `alpinejs`.\n\n## Using `alpinejs`\n\n`Fortem` provides methods for seamless integration with [alpinejs](https://alpinejs.dev/).\n\nFor `Input` and `Select` classes, the `asModel` method adds an `x-model` attribute to the element, binding its value to its variable:\n\n``` php\necho $form-\u003einput('name')-\u003easModel();\n```\n\n``` html\n\u003cinput type=\"text\" name=\"name\" x-model=\"name\"\u003e\n```\n\n``` php\necho $form-\u003eselect('gender', $items)-\u003easModel();\n```\n\n``` html\n\u003cselect name=\"gender\" x-model=\"gender\"\u003e...\u003c/select\u003e\n```\n\nIn all elements, the `disablesOn` method adds the `:disabled` attribute, allowing an element to be disabled based on its condition:\n\n``` php\necho $form-\u003einput('name')-\u003edisablesOn('loading');\n```\n\n``` html\n\u003cinput type=\"text\" name=\"name\" :disabled=\"loading\"\u003e\n```\n\nFor the `Button` class, the `onClick` method adds the `@click` attribute to a button, executing its function on click:\n\n``` php\necho $form-\u003ebutton('Submit')-\u003eonClick('submitForm');\n```\n\n``` html\n\u003cbutton type=\"button\" @click=\"submitForm\"\u003eSubmit\u003c/button\u003e\n```\n\n## Scripts\n\nThe `script` method helps create a JavaScript object from PHP which is useful for initializing data for `alpinejs`:\n\n``` php\necho $form-\u003escript('data')\n  -\u003ewith('name', 'John Doe')\n  -\u003ewith('age', 30)\n  -\u003ewithLoading()\n  -\u003ewithError();\n```\n\n``` html\n\u003cscript\u003e\n  let data = {\"name\":\"John Doe\",\"age\":30,\"loading\":false,\"error\":{}};\n\u003c/script\u003e\n```\n\n## Restyling elements\n\nThe default styling uses Bootstrap 5 classes. To use a different CSS framework, implement the `StyleInterface` and pass it to the form helper:\n\n``` php\nnamespace Rougin\\Test\\Styles;\n\nuse Rougin\\Fortem\\StyleInterface;\n\nclass TailwindStyle implements StyleInterface\n{\n    public function button()\n    {\n        return 'rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500';\n    }\n\n    public function error()\n    {\n        return 'mt-1 text-sm text-red-600';\n    }\n\n    public function input()\n    {\n        return 'block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 sm:text-sm';\n    }\n\n    public function label()\n    {\n        return 'block text-sm font-medium leading-6 text-gray-900';\n    }\n\n    public function required()\n    {\n        return 'text-red-500';\n    }\n\n    public function select()\n    {\n        return 'block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 sm:text-sm';\n    }\n}\n```\n\n``` php\nuse Rougin\\Fortem\\Helpers\\FormHelper;\nuse Rougin\\Test\\Styles\\TailwindStyle;\n\n$form = new FormHelper;\n\n// Apply the custom style to all elements ---\n$form-\u003euseStyling(new TailwindStyle);\n// ------------------------------------------\n\n// All elements now use the custom style ---\n$form-\u003elabel('Name')-\u003easRequired();\n$form-\u003einput('name');\n$form-\u003ebutton('Submit')-\u003ewithClass('btn-primary');\n$form-\u003eselect('gender', array('Male', 'Female'));\n$form-\u003eerror('error.name');\n// -----------------------------------------\n\n// Opt out the default styling per element ---\n$form-\u003einput('name')-\u003enoStyling();\n// -------------------------------------------\n```\n\n## Changelog\n\nPlease see [CHANGELOG][link-changelog] for recent changes and latest updates.\n\n## Contributing\n\nSee [CONTRIBUTING][link-contributing] on how to contribute to the project.\n\n## License\n\nThe MIT License (MIT). Please see [LICENSE][link-license] for more information.\n\n[ico-build]: https://img.shields.io/github/actions/workflow/status/rougin/fortem/build.yml?style=flat-square\n[ico-coverage]: https://img.shields.io/codecov/c/github/rougin/fortem?style=flat-square\n[ico-downloads]: https://img.shields.io/packagist/dt/rougin/fortem.svg?style=flat-square\n[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square\n[ico-version]: https://img.shields.io/packagist/v/rougin/fortem.svg?style=flat-square\n\n[link-build]: https://github.com/rougin/fortem/actions\n[link-changelog]: https://github.com/rougin/fortem/blob/master/CHANGELOG.md\n[link-contributing]: https://github.com/rougin/fortem/blob/master/CONTRIBUTING.md\n[link-coverage]: https://app.codecov.io/gh/rougin/fortem\n[link-downloads]: https://packagist.org/packages/rougin/fortem\n[link-license]: https://github.com/rougin/fortem/blob/master/LICENSE.md\n[link-packagist]: https://packagist.org/packages/rougin/fortem\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frougin%2Ffortem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frougin%2Ffortem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frougin%2Ffortem/lists"}