{"id":15903933,"url":"https://github.com/denisdefreyne/ddplugin","last_synced_at":"2026-04-07T05:31:57.276Z","repository":{"id":12350535,"uuid":"14995590","full_name":"denisdefreyne/ddplugin","owner":"denisdefreyne","description":"Plugin management library","archived":false,"fork":false,"pushed_at":"2022-11-27T10:40:22.000Z","size":64,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-27T00:40:13.740Z","etag":null,"topics":["plugin","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/denisdefreyne.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-12-06T22:56:34.000Z","updated_at":"2022-11-27T14:18:47.000Z","dependencies_parsed_at":"2023-01-13T16:54:50.917Z","dependency_job_id":null,"html_url":"https://github.com/denisdefreyne/ddplugin","commit_stats":null,"previous_names":["ddfreyne/ddplugin"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/denisdefreyne/ddplugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denisdefreyne%2Fddplugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denisdefreyne%2Fddplugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denisdefreyne%2Fddplugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denisdefreyne%2Fddplugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/denisdefreyne","download_url":"https://codeload.github.com/denisdefreyne/ddplugin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/denisdefreyne%2Fddplugin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31219232,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-31T04:08:55.938Z","status":"ssl_error","status_checked_at":"2026-03-31T04:08:47.883Z","response_time":111,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["plugin","ruby"],"created_at":"2024-10-06T12:04:50.343Z","updated_at":"2026-04-02T18:49:02.103Z","avatar_url":"https://github.com/denisdefreyne.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Gem version](http://img.shields.io/gem/v/ddplugin.svg)](http://rubygems.org/gems/ddplugin)\n[![Gem downloads](https://img.shields.io/gem/dt/ddplugin.svg)](http://rubygems.org/gems/ddplugin)\n![Build status](https://img.shields.io/github/workflow/status/denisdefreyne/ddplugin/ddplugin)\n\n# ddplugin\n\n_ddplugin_ is a library for managing plugins.\n\nDesigning a library so that third parties can easily extend it greatly improves its usefulness. _ddplugin_ helps solve this problem using _plugins_, which are classes of a certain type and with a given identifier (Ruby symbol).\n\nThis code was extracted from Nanoc, where it has been in production for years.\n\n## Use case\n\nMany projects can make use of plugins. Here are a few examples:\n\n- a **text processing library** with _filters_ such as `colorize-syntax`, `markdown` and `smartify-quotes`.\n\n- an **image processing library** with _filters_ such as `resize`, `desaturate` and `rotate`.\n\n- a **database driver abstraction** with _connectors_ such as `postgres`, `sqlite3` and `mysql`.\n\n- a **document management system** with _data sources_ such as `filesystem` and `database`.\n\nIn _ddplugin_, the filters, connectors and data sources would be _plugin types_, while the actual plugins, such as `markdown`, `rotate`, `postgres` and `database` would be _plugins_.\n\nA typical way to use plugins would be to store the plugin names in a configuration file, so that the actual plugin implementations can be discovered at runtime.\n\n## Requirements\n\n_ddplugin_ requires Ruby 2.3 or higher.\n\n## Versioning\n\n_ddplugin_ adheres to [Semantic Versioning 2.0.0](http://semver.org).\n\n## Installation\n\nIf your library where you want to use _ddplugin_ has a gemspec, add _ddplugin_ as a runtime dependency to the gemspec:\n\n```ruby\nspec.add_runtime_dependency 'ddplugin', '~\u003e 1.0'\n```\n\nIf you use Bundler instead, add it to the `Gemfile`:\n\n```ruby\ngem 'ddplugin', '~\u003e 1.0'\n```\n\n## Usage\n\nPlugin type are classes that extend `DDPlugin::Plugin`:\n\n```ruby\nclass Filter\n  extend DDPlugin::Plugin\nend\n\nclass DataSource\n  extend DDPlugin::Plugin\nend\n```\n\nTo define a plugin, create a class that inherits from the plugin type and sets the identifier, either as a symbol or a string:\n\n```ruby\nclass ERBFilter \u003c Filter\n  # Specify the identifier as a symbol…\n  identifier :erb\nend\n\nclass HamlFilter \u003c Filter\n  # … or as a string …\n  identifier 'haml'\nend\n\nclass FilesystemDataSource \u003c DataSource\n  # … or even provide multiple.\n  identifiers :filesystem, :file_system\nend\n\nclass PostgresDataSource \u003c DataSource\n  # … or mix and match (not sure why you would, though)\n  identifier :postgres, 'postgresql'\nend\n```\n\nTo find a plugin of a given type and with a given identifier, call `.named` on the plugin type, passing an identifier:\n\n```ruby\nFilter.named(:erb) # =\u003e ERBFilter\n\nFilter.named('haml') # =\u003e HamlFilter\n\nDataSource.named(:filesystem) # =\u003e FilesystemDataSource\n\nDataSource.named(:postgres) # =\u003e PostgresDataSource\n```\n\nIn a real-world situation, the plugin types could be described in the environment:\n\n```\n% cat .env\nDATA_SOURCE_TYPE=postgres\n```\n\n```ruby\nDataSource.named(ENV.fetch('DATA_SOURCE_TYPE')) # =\u003e PostgresDataSource\n```\n\n… or in a configuration file:\n\n```\n% cat config.yml\ndata_source: 'filesystem'\n```\n\n```ruby\nconfig = YAML.load_file('config.yml')\nDataSource.named(config.fetch('data_source')) # =\u003e FilesystemDataSource\n```\n\nTo get all plugins of a given type, call `.all` on the plugin type:\n\n```ruby\nFilter.all\n\nDataSource.all # =\u003e [FilesystemDataSource, PostgresDataSource]\n```\n\nTo get the identifier of a plugin, call `.identifier`, which returns a symbol:\n\n```ruby\nFilter.named(:erb).identifier\n\nFilter.named('haml').identifier\n\nPostgresDataSource.identifier # =\u003e :postgres\n```\n\n## Development\n\nPull requests and issues are greatly appreciated.\n\nWhen you submit a pull request, make sure that your change is covered by tests, and that the `README` and [YARD](http://yardoc.org/) source code documentation are still up-to-date.\n\nTo run the tests:\n\n```\n% bundle install\n% bundle exec rake\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenisdefreyne%2Fddplugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdenisdefreyne%2Fddplugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdenisdefreyne%2Fddplugin/lists"}