{"id":15433021,"url":"https://github.com/simonw/datasette-plugin","last_synced_at":"2025-04-19T17:52:31.654Z","repository":{"id":46321462,"uuid":"273547529","full_name":"simonw/datasette-plugin","owner":"simonw","description":"Cookiecutter template for creating Datasette plugins","archived":false,"fork":false,"pushed_at":"2025-04-10T22:42:53.000Z","size":105,"stargazers_count":20,"open_issues_count":4,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-10T23:30:00.654Z","etag":null,"topics":["cookiecutter-template","datasette"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simonw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2020-06-19T17:10:15.000Z","updated_at":"2025-04-10T22:42:57.000Z","dependencies_parsed_at":"2024-10-20T20:19:21.689Z","dependency_job_id":null,"html_url":"https://github.com/simonw/datasette-plugin","commit_stats":{"total_commits":94,"total_committers":2,"mean_commits":47.0,"dds":"0.010638297872340385","last_synced_commit":"db7c0549cd5656bdec00ba1e15c0ef7d6cc78f16"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonw%2Fdatasette-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonw%2Fdatasette-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonw%2Fdatasette-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonw%2Fdatasette-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simonw","download_url":"https://codeload.github.com/simonw/datasette-plugin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249753093,"owners_count":21320664,"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","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":["cookiecutter-template","datasette"],"created_at":"2024-10-01T18:30:34.646Z","updated_at":"2025-04-19T17:52:31.626Z","avatar_url":"https://github.com/simonw.png","language":"Python","readme":"# datasette-plugin cookiecutter template\n\nA cookiecutter template for creating new Datasette plugins. See [Writing Plugins](https://docs.datasette.io/en/stable/writing_plugins.html) in the Datasette documentation for more details.\n\nUse this template on your own machine with cookiecutter, or create a brand new repository based on this template entirely through the GitHub web interface using [datasette-plugin-template-repository](https://github.com/simonw/datasette-plugin-template-repository).\n\n## Installation\n\nYou'll need to have [cookiecutter](https://cookiecutter.readthedocs.io/) installed. I recommend pipx for this:\n```bash\npipx install cookiecutter\n```\nRegular `pip` will work OK too.\n\n## Usage\n\nRun `cookiecutter gh:simonw/datasette-plugin` and then answer the prompts. Here's an example run:\n```\n$ cookiecutter gh:simonw/datasette-plugin\nplugin_name []: plugin template demo\ndescription []: Demonstrating https://github.com/simonw/datasette-plugin\nhyphenated [plugin-template-demo]:\nunderscored [plugin_template_demo]:\ngithub_username []: simonw\nauthor_name []: Simon Willison\ninclude_static_directory []: y\ninclude_templates_directory []: y\n```\nI strongly recommend accepting the suggested value for \"hyphenated\" and \"underscored\" by hitting enter on those prompts.\n\nThe `include_static_directory` and `include_templates_directory` prompts will cause `../static` and `../templates` folders to be created and added to `setup.py` as `package_data`. Use these if your plugin needs to include templates or static assets (CSS and JavaScript). Leave these prompts blank if you do not want these directories to be created.\n\nThis will create a directory called `datasette-plugin-template-demo` - the plugin name you enter is converted to lowercase and uses hyphens instead of spaces.\n\nSee https://github.com/simonw/datasette-plugin-template-demo for the output of this example.\n\n## Developing your plugin\n\nHaving created the new plugin structure from the template, here's how to start working on the plugin.\n\nIf your plugin is called `datasette-my-new-plugin`, you can start working on it like so:\n```bash\ncd datasette-my-new-plugin\n# Create and activate a virtual environment:\npython -m venv venv\nsource venv/bin/activate\n# Install dependencies so you can edit the plugin:\npip install -e '.[test]'\n# With zsh you have to run this again for some reason:\nsource venv/bin/activate\n# Confirm your plugin is visible to Datasette:\ndatasette plugins\n```\nYou should see the following:\n```json\n[\n    {\n        \"name\": \"datasette-my-new-plugin\",\n        \"static\": false,\n        \"templates\": false,\n        \"version\": \"0.1\",\n        \"hooks\": []\n    }\n]\n```\nYou can run the default test for your plugin like so:\n```bash\npython -m pytest\n```\nThis will execute the test in `tests/test_my_new_plugin.py`, which confirms that the plugin has been installed.\n\nNow you can open the `datasette_my_new_plugin/__init__.py` file and start adding your [plugin hooks](https://docs.datasette.io/en/stable/plugin_hooks.html).\n\n## Creating a Git repository for your plugin\n\nYou can initialize a Git repository for your plugin like this:\n```bash\ncd datasette-my-new-plugin\ngit init\ngit add .\ngit commit -m \"Initial structure from template\"\n# Rename the 'master' branch to 'main':\ngit branch -m master main\n```\n## Publishing your plugin to GitHub\n\nUse https://github.com/new to create a new GitHub repository sharing the same name as your plugin, which should be something like `datasette-my-new-plugin`.\n\nPush your `main` branch to GitHub like this:\n```bash\ngit remote add origin git@github.com:YOURNAME/datasette-my-new-plugin.git\ngit push -u origin main\n```\nThe template will have created a GitHub Action which runs your plugin's test suite against every commit.\n\n## Publishing your plugin as a package to PyPI\n\nThe template also includes an Action for publishing packages to [PyPI](https://pypi.org/).\n\nFor this to work, you need to create an environment in your GitHub repository called `release`. You then need to configure PyPI with a new \"pending publisher\" with the following settings:\n\n- PyPI Project Name: `datasette-name-of-your-plugin`\n- Owner: Your GitHub username or organization\n- Repository name: The name of your repository\n- Workflow name: `publish.yml`\n- Environment name: `release`\n\nSee [Publish releases to PyPI from GitHub Actions without a password or token](https://til.simonwillison.net/pypi/pypi-releases-from-github) for details.\n\nWith that configured, create a GitHub release with a name that corresponds to the version number listed in your `pyproject.toml` file and the action will build and publish a PyPI package for you.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonw%2Fdatasette-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimonw%2Fdatasette-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonw%2Fdatasette-plugin/lists"}