{"id":30151989,"url":"https://github.com/plone/mockup","last_synced_at":"2025-08-11T11:10:49.415Z","repository":{"id":5769361,"uuid":"6982635","full_name":"plone/mockup","owner":"plone","description":"A collection of client side patterns for faster and easier web development","archived":false,"fork":false,"pushed_at":"2025-07-25T09:24:21.000Z","size":175159,"stargazers_count":52,"open_issues_count":118,"forks_count":99,"subscribers_count":154,"default_branch":"master","last_synced_at":"2025-07-25T14:15:18.180Z","etag":null,"topics":["hacktoberfest","javascript","patternslib","ui-components"],"latest_commit_sha":null,"homepage":"http://plone.github.io/mockup/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/plone.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"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},"funding":{"github":"plone","custom":["https://plone.org/foundation/sponsorship"]}},"created_at":"2012-12-03T13:25:05.000Z","updated_at":"2025-07-25T09:23:18.000Z","dependencies_parsed_at":"2023-10-20T08:38:45.662Z","dependency_job_id":"f22c2ffd-f2da-4579-b192-77b2ef40ee10","html_url":"https://github.com/plone/mockup","commit_stats":{"total_commits":3887,"total_committers":135,"mean_commits":28.79259259259259,"dds":0.7782351427836378,"last_synced_commit":"d6a4d7a689761772f8c8a06826c5c1f6f757c75c"},"previous_names":[],"tags_count":176,"template":false,"template_full_name":null,"purl":"pkg:github/plone/mockup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plone%2Fmockup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plone%2Fmockup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plone%2Fmockup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plone%2Fmockup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/plone","download_url":"https://codeload.github.com/plone/mockup/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plone%2Fmockup/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269873158,"owners_count":24488993,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-11T02:00:10.019Z","response_time":75,"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":["hacktoberfest","javascript","patternslib","ui-components"],"created_at":"2025-08-11T11:08:48.984Z","updated_at":"2025-08-11T11:10:49.405Z","avatar_url":"https://github.com/plone.png","language":"JavaScript","funding_links":["https://github.com/sponsors/plone","https://plone.org/foundation/sponsorship"],"categories":[],"sub_categories":[],"readme":"# Plone Mockup\n\nMockup is the JavaScript stack of the Plone Classic UI.\n\n\n## Usage\n\nThere are several options to integrate Mockup.\n\n1.  It comes pre-installed with Plone 6 Classic UI.\n2.  You can install and compile a bundle. See [Development Section](#development) below.\n3.  You can download a `.zip` from [Mockup's releases page on GitHub](https://github.com/plone/mockup/releases).\n4.  You can use a precompiled bundle from a CDN, like:\n\n    ```html\n    \u003cscript src=\"https://unpkg.com/@plone/mockup@latest/dist/bundle.min.js\"\u003e\u003c/script\u003e\n    ```\n    or:\n    ```html\n    \u003cscript src=\"https://cdn.jsdelivr.net/npm/@plone/mockup@latest/dist/bundle.min.js\"\u003e\u003c/script\u003e\n    ```\n\n\n## Install\n\n-   Have a current version of Node.js installed.\n\n-   To install, run: `make install`.\n\n-   To run the demo server, do: `make serve`.\n\n    This starts up the webpack build process in watch mode.\n    Any JavaScript changes are immediately compiled.\n    For some changes - like for adding new packages via `yarn add` and then using it you might need to restart.\n    The command also spins up a development server for our `11ty` based documentation and demo pages.\n    If you don't need the docs running, you can run `yarn start:webpack` or `npm run start:webpack` instead, so that only the webpack devserver is running.\n\n-   Go to `http://localhost:8000`:\n    On this port our demo and documentation pages are served.\n\n\n## Mockup overview\n\nMockup is a JavaScript UI library which provides widgets, apps, and functionality for the Plone Classic UI frontend.\nIt is based on Patternslib, and provides its functionality through patterns.\nPatterns are initialized and activated when a triggering CSS selector is found in the DOM tree.\nFor example, the related items widget is initialized on a form input field with the CSS class `pat-relateditems`.\nThe configuration is done via data attributes.\nFor the related items pattern, it's an attribute called `data-pat-relateditems`.\nThe data structure of the configuration can be a JSON string or CSS declaration as key-value pairs, with the key and value separated by a colon (`:`), and the pairs separated by a semicolon (`;`).\nDefining a JSON structure is more flexible though.\n\nHere are two examples.\n\n`pat-relateditems` configuration as JSON structure:\n```html\n\u003cinput\n    type=\"text\"\n    class=\"pat-relateditems\"\n    data-pat-relateditems='{\n        \"selectableTypes\": [\"Document\"],\n        \"vocabularyUrl\": \"relateditems-test.json\"\n    }'\n/\u003e\n```\n\n`pat-relateditems` configuration as CSS declarations:\n```html\n\u003cinput\n    type=\"text\"\n    class=\"pat-relateditems\"\n    data-pat-relateditems=\"\n        selectableTypes: Document;\n        vocabularyUrl: relateditems-test.json;\n    \"\n/\u003e\n```\n\nBecause of historic reasons, the Mockup pattern attributes are written in \"camelCase\", for example `vocabularyUrl`.\nBut to resemble the CSS syntax, new patterns should instead separate each word with a dash, for example `vocabulary-url`.\n\n\n## Mockup Patterns\n\n- [pat-autotoc](src/pat/autotoc/README.md): Automatically create a table of contents.\n- [pat-contentbrowser](src/pat/contentbrowser/README.md): Show an offcanvas miller-column browser to select items.\n- [pat-cookietrigger](src/pat/cookietrigger/README.md): Show a DOM element if browser cookies are disabled.\n- [pat-datatables](src/pat/datatables/README.md): This pattern provides the functionality from https://datatables.net/\n- [pat-formautofocus](src/pat/formautofocus/README.md): Automatically set the focus on a form input field.\n- [pat-formunloadalert](src/pat/formunloadalert/README.md): Show a warning if the user leaves an unsaved form.\n- [pat-livesearch](src/pat/livesearch/README.md): Provide Plone's live search functionality.\n- [pat-manage-portlets](src/pat/manageportlets/README.md): Used by `plone.app.portlets` to manage portlets.\n- [pat-markspeciallinks](src/pat/markspeciallinks/README.md): Add a special class to links in certain conditions.\n- [pat-modal](src/pat/modal/README.md): Show content in a modal.\n- [pat-navigationmarker](src/pat/navigationmarker/README.md): Add classes to the main navigation.\n- [pat-passwordstrength](src/pat/passwordstrength/README.md): Check the strength of a password.\n- [pat-preventdoublesubmit](src/pat/preventdoublesubmit/README.md): Prevent multiple submissions of the same forn.\n- [pat-querystring](src/pat/querystring/README.md): Show the querystring selection app.\n- [pat-recurrence](src/pat/recurrence/README.md): Show the recurrence widget.\n- [pat-select2](src/pat/select2/README.md): Show a widget which enhances dropdown selections with automatic suggestions, search and tagging functionality.\n- [pat-sortable](src/pat/sortable/README.md): A pattern to make listings sortable.\n- [pat-structure](src/pat/structure/README.md): Plone's folder contents app.\n- [pat-structureupdater](src/pat/structure-updater/README.md): Update title and description based on the current folder contents location.\n- [pat-textareamimetypeselector](src/pat/textareamimetypeselector/README.md): Display the MIME type selection widget for textareas.\n- [pat-tinymce](src/pat/tinymce/README.md): Use the TinyMCE editor for HTML editing.\n- [pat-toggle](src/pat/toggle/README.md): A pattern to toggle classes on HTML elements.\n- [pat-toolbar](src/pat/toolbar/README.md): Render the Plone toolbar.\n- [pat-tree](src/pat/tree/README.md): Renders a navigable tree from a data structure.\n- [pat-upload](src/pat/upload/README.md): Upload files to Plone.\n\nDeprecated patterns:\n\n- [pat-relateditems](src/pat/relateditems/README.md) (_deprecated_): Show a widget to select related items. (use `pat-contentbrowser` instead)\n- [pat-backdrop](src/pat/backdrop/README.md) (_deprecated_): Renders a dark background.\n- [pat-contentloader](src/pat/contentloader/README.md) (_deprecated_): Load remote or local content into a target.\n- [pat-texteditor](src/pat/texteditor/README.md) (_deprecated_): Show a code editor.\n\n\n## Development\n\nYou can directly develop with the 11ty based documentation / demo server by running ``make serve``.\n\nIf you want to develop in Plone, you have two options:\n\n1) Run `make watch-plone`. You need buildout to have plone.staticresources checked out next to Mockup.\n   Mockup will compile it's bundle directly into the `++plone++static` directory of plone.staticresources and update it when you change something in Mockup.\n\n2) Run `npx yarn start:webpack`, go to the resource registry ( http://localhost:8080/Plone/@@resourceregistry-controlpanel ) and add the URL `http://localhost:8000/bundle.min.js` to the JavaScript input field of the plone bundle instead of the other URL `++plone++static/bundle-plone/bundle.min.js`.\n\nFor more commands inspect Makefile and the script part of the package.json.\n\n\n### Running tests\n\nRun `make check` to run all tests including `eslint` checks.\n\nTo run individual tests, run:\n\n-   `jest`: Run all tests\n-   `jest src/pat/PATH-TO-PATTERN`: Run a specific test suite\n-   `jest src/pat/PATH-TO-PATTERN -t \"Test name\"`: Run a specific test matching \"Test name\" from a specific test suite.\n-   `jest --watch`: Run the interactive test runner.\n\n### Debugging tests\n\nThe tests are based on jsdom - a library mocking DOM and HTML standards in JavaScript.\nNo real browsers are involved, which make the tests run really fast.\n\nStill, you can connect to the Chrome debugging interface via:\n\n```\nnode --inspect-brk node_modules/.bin/jest --runInBand ./src/pat/PATH-TO-PATTERN``\n```\n\nConnect in chrome via (You need to click \"continue\" or \"Resume script execution\" in the inspector once to proceed):\n\n```\nchrome://inspect\n```\n\nYou can pass Jest any parameter it accepts, like `-t TESTPATTERN`::\n\n```\nnode --inspect-brk node_modules/.bin/jest --runInBand ./src/pat/PATH-TO-PATTERN -t test.name\n```\n\nYou can put some `debugger;` statements to the code to break the execution and investigate.\n\n### Developing external Packages\n\nIf you want to work on ony external package like Patternslib or any external Mockup pattern you can do so by linking those packages into the node_modules folder via `yarn link`.\n\n1. Check out the external package you want to develop on.\n\n2. Make sure you have installed the dependencies in the development package (e.g. by running `yarn install`). (TODO: verify that!)\n\n3. Run `yarn link` in the external development package to register it with yarn.\n\n4. Run `yarn link \"PACKAGE-NAME\"` in mockup to create the node_modules symlink.\n\nAfter developing you might want to run `yarn unlink \"PACKAGE-NAME\"` to unlink the development package.\n\nFor more information see:\n\n-   https://classic.yarnpkg.com/en/docs/cli/link/\n-   https://classic.yarnpkg.com/en/docs/cli/unlink\n-   https://docs.npmjs.com/cli/v7/commands/npm-link\n\n**Please note:**: Make sure to unlink and reinstall development pacakges before building a production bundle.\nIn doubt, remove the node_modules directory and re-install.\n\n### Bundle build analyzation\n\nhttps://survivejs.com/webpack/optimizing/build-analysis/\nhttps://formidable.com/blog/2018/finding-webpack-duplicates-with-inspectpack-plugin/\n\nBuild the stats.json file:\n\n```\nnpx yarn build:stats\n```\n\nCheck dependency tree and why which package was included:\nhttps://www.npmjs.com/package/whybundled\n\n```\nnpx whybundled stats.json\n```\n\nVisualize dependency tree and analyze bundle size:\nhttps://www.npmjs.com/package/webpack-bundle-analyzer\n\n```\nnpx webpack-bundle-analyzer stats.json\n```\n\n\n### i18n message extraction\n\nTo update the translation file, the following needs to be done:\n\n1. Extract the messages from this package:\n\n```\nnpx yarn run i18n\n```\n\nOr just ``npm run i18n``...\n\n2. Copy the widgets.pot file to plone.app.locales\n\nAssuming you are doing this from a buildout.coredev environment in the mockup folder:\n```\ncp widgets.pot ../plone.app.locales/plone/app/locales/locales/\n```\n\n3. Run i18ndude to update the po files\n\n```\ncd ../plone.app.locales/plone/app/locales/locales\ni18ndude sync --pot widgets.pot */LC_MESSAGES/widgets.po\n```\n\n### i18n message handling in Plone\n\nTo test a translation, for example French:\n\n- Edit the po file ``src/plone.app.locales/plone/app/locales/locales/fr/LC_MESSAGES/widgets.po``.\n\n- Restart your instance to rebuild the mo file from the po file.\n\n- Purge your localStorage and refresh the page to trigger a new download of the translations.\n\nThe translations are handled by ``src/core/i18n.js``.\nThis translation helper that calls the ``@@plonejsi18n`` view defined in plone.app.content to generate a JSON of the translations from the mo file.\nThe ``@@plonejsi18n`` view is called one time for a given domain and language and the result is cached in localStorage for 24 hours.\nThe only way to test the new translations is to restart the instance to update the mo file from the po file, and then to purge the localStorage to trigger a new download of the translations.\n\n\n## Style guide\n\n-   Tab: 4 spaces for everything, except for HTML and XML files which must use 2 spaces, and the Makefile which must use tabs.\n    This rule is defined in the [.editorconfig file](./.editorconfig).\n\n### Commit style guide\n\nWe automatically generate the changelog from the commit messages following the [Conventional Commits specification](https://www.conventionalcommits.org/).\nChangelog generation is done by the [conventional changelog plugin](https://github.com/release-it/conventional-changelog/) for [release-it](https://github.com/release-it/release-it).\nThis is enforced via a pre-commit hook managed by [husky](https://github.com/typicode/husky).\n\n**And this is how you use it:**\n\nWe have 4 different types of changelog entries:\n\n-   Breaking Changes (type: `breaking`),\n-   Features (type: `feat`),\n-   Bug Fixes (type: `fix`),\n-   Maintenance (type: `maint`).\n\nWe can group commits in the changelog via a scope or grouping.\nLet's follow a convention and use these groupings, but the grouping is optional and any other group name can be used.\n\n-   \"Dependencies\" for upgrading package.json dependencies.\n-   \"Docs\" for documentation.\n-   \"Build\" for everything related to the release workflow, Webpack and building bundles.\n-   \"Cleanup\" for cleaning up or reformatting code.\n-   \"pat PATTERNNAME\" for changes to individual patterns in `src/pat`.\n-   \"core MODULENAME\" for changes to core modules in `src/core`.\n\nA commit message with a changelog grouping must be structured like so: `TYPE(GROUP): MESSAGE`.\nWithout grouping: `TYPE: MESSAGE`\n\nIf the commit message doesn't follow this convention, then it won't be included in the changelog.\nTo bypass the pre-commit hook, use the git `-n` switch.\nExample: `git commit yarn.lock -m \"yarn install.\" -n`.\n\nIf you are working on a component like the structure pattern (pat-structure), use `pat structure` as a group.\n\nExamples:\n\nAdd a feature to the structure pattern:\n\n```shell\ngit commit src/pat/structure -m \"feat(pat structure): Add feature to cook some coffee\"\n```\n\nCleanup task:\n\n```shell\ngit commit -am \"maint(Cleanup): Remove whitespace from documentation.\"\n```\n\nor without a grouping:\n\n```shell\ngit commit -am \"maint: Remove unnecessary file from root directory.\"\n```\n\n---\n\n**Note**\n\nPlease keep commits on the `yarn.lock` file or any other auto-generated code seperate.\n\nJust commit them seperately with `git commit yarn.lock -m \"yarn install\" -n`.\n\nKeeping them seperate reduces the effort when merging or rebasing branches where a merge conflict can easily happen.\nIn such cases you can just withdraw your changes on the `yarn.lock` file, or remove those commits and reinstall with `yarn install` at the end of a successful merge or rebase.\n\n---\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplone%2Fmockup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplone%2Fmockup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplone%2Fmockup/lists"}