{"id":13491507,"url":"https://github.com/elixir-waffle/waffle","last_synced_at":"2025-10-21T19:02:28.941Z","repository":{"id":35094452,"uuid":"204286023","full_name":"elixir-waffle/waffle","owner":"elixir-waffle","description":"Flexible file upload and attachment library for Elixir","archived":false,"fork":false,"pushed_at":"2024-12-09T14:06:55.000Z","size":448,"stargazers_count":767,"open_issues_count":28,"forks_count":77,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-10T17:06:40.437Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","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/elixir-waffle.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2019-08-25T11:39:00.000Z","updated_at":"2025-03-08T01:03:51.000Z","dependencies_parsed_at":"2023-01-15T13:43:04.833Z","dependency_job_id":"cac28602-b99a-43da-a466-ec47bbe5d07c","html_url":"https://github.com/elixir-waffle/waffle","commit_stats":{"total_commits":288,"total_committers":81,"mean_commits":"3.5555555555555554","dds":0.7986111111111112,"last_synced_commit":"2e3234974a76f71e3ea1e3fb4cc531693fd94cea"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-waffle%2Fwaffle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-waffle%2Fwaffle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-waffle%2Fwaffle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-waffle%2Fwaffle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elixir-waffle","download_url":"https://codeload.github.com/elixir-waffle/waffle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245996759,"owners_count":20707311,"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":[],"created_at":"2024-07-31T19:00:57.672Z","updated_at":"2025-10-21T19:02:23.894Z","avatar_url":"https://github.com/elixir-waffle.png","language":"Elixir","funding_links":[],"categories":["Elixir","Files and Directories"],"sub_categories":[],"readme":"[hex-img]: http://img.shields.io/hexpm/v/waffle.svg\n\n[hexdocs-img]: http://img.shields.io/badge/hexdocs-documentation-brightgreen.svg\n\n[evrone-img]: https://img.shields.io/badge/Sponsored_by-Evrone-brightgreen.svg\n\n# Waffle [![Sponsored by Evrone][evrone-img]](https://evrone.com?utm_source=waffle)\n\n[![Hex.pm Version][hex-img]](https://hex.pm/packages/waffle)\n[![waffle documentation][hexdocs-img]](https://hexdocs.pm/waffle)\n\n![Waffle is a flexible file upload library for Elixir](https://elixir-waffle.github.io/waffle/assets/logo.svg)\n\nWaffle is a flexible file upload library for Elixir with straightforward integrations for Amazon S3 and ImageMagick.\n\n[Documentation](https://hexdocs.pm/waffle)\n\n## Installation\n\nAdd the latest stable release to your `mix.exs` file, along with the\nrequired dependencies for `ExAws` if appropriate:\n\n```elixir\ndefp deps do\n  [\n    {:waffle, \"~\u003e 1.1\"},\n\n    # If using S3:\n    {:ex_aws, \"~\u003e 2.1.2\"},\n    {:ex_aws_s3, \"~\u003e 2.0\"},\n    {:hackney, \"~\u003e 1.9\"},\n    {:sweet_xml, \"~\u003e 0.6\"}\n  ]\nend\n```\n\nThen run `mix deps.get` in your shell to fetch the dependencies.\n\n## Usage\n\nAfter installing Waffle, another two things should be done:\n\n1. setup a storage provider\n2. define a definition module\n\n### Setup a storage provider\n\nWaffle has two built-in storage providers:\n\n* `Waffle.Storage.Local`\n* `Waffle.Storage.S3`\n\n[Other available storage providers](#other-storage-providers)\nare supported by the community.\n\nAn example for setting up `Waffle.Storage.Local`:\n\n```elixir\nconfig :waffle,\n  storage: Waffle.Storage.Local,\n  asset_host: \"http://static.example.com\" # or {:system, \"ASSET_HOST\"}\n```\n\nAn example for setting up `Waffle.Storage.S3`:\n\n```elixir\nconfig :waffle,\n  storage: Waffle.Storage.S3,\n  bucket: \"custom_bucket\",                # or {:system, \"AWS_S3_BUCKET\"}\n  asset_host: \"http://static.example.com\" # or {:system, \"ASSET_HOST\"}\n\nconfig :ex_aws,\n  json_codec: Jason\n  # any configurations provided by https://github.com/ex-aws/ex_aws\n```\n\n### Define a definition module\n\nWaffle requires a **definition module** which contains the relevant\nfunctions to store and retrieve files:\n\n* Optional transformations of the uploaded file\n* Where to put your files (the storage directory)\n* How to name your files\n* How to secure your files (private? Or publicly accessible?)\n* Default placeholders\n\nThis module can be created manually or generated by `mix waffle.g`\nautomatically.\n\nAs an example, we will generate a definition module for handling\navatars:\n\n    mix waffle.g avatar\n\nThis should generate a file at `lib/[APP_NAME]_web/uploaders/avatar.ex`.\nCheck this file for descriptions of configurable options.\n\n## Examples\n\n* [An example for Local storage driver](documentation/examples/local.md)\n* [An example for S3 storage driver](documentation/examples/s3.md)\n\n## Usage with Ecto\n\nWaffle comes with a companion package for use with Ecto. If you\nintend to use Waffle with Ecto, it is highly recommended you also\nadd the\n[`waffle_ecto`](https://github.com/elixir-waffle/waffle_ecto)\ndependency.  Benefits include:\n\n  * Changeset integration\n  * Versioned urls for cache busting (`.../thumb.png?v=63601457477`)\n\n## Other Storage Providers\n\n  * **Rackspace** - [arc_rackspace](https://github.com/lokalebasen/arc_rackspace)\n\n  * **Manta** - [arc_manta](https://github.com/onyxrev/arc_manta)\n\n  * **OVH** - [arc_ovh](https://github.com/stephenmoloney/arc_ovh)\n\n  * **Google Cloud Storage** - [waffle_gcs](https://github.com/elixir-waffle/waffle_gcs)\n\n  * **Microsoft Azure Storage** - [arc_azure](https://github.com/phil-a/arc_azure)\n\n  * **Aliyun OSS Storage** - [waffle_aliyun_oss](https://github.com/ug0/waffle_aliyun_oss)\n  \n## Testing\n\nThe basic test suite can be run with without supplying any S3 information:\n\n```\nmix test\n```\n\nIn order to test S3 capability, you must have access to an S3/equivalent bucket. For\nS3 buckets, the bucket must be configured to allow ACLs and it must allow public\naccess.\n\nThe following environment variables will be used by the test suite:\n\n* WAFFLE_TEST_BUCKET\n* WAFFLE_TEST_BUCKET2\n* WAFFLE_TEST_S3_KEY\n* WAFFLE_TEST_S3_SECRET\n* WAFFLE_TEST_REGION\n\nAfter setting these variables, you can run the full test suite with `mix test --include s3:true`.\n\n## Attribution\n\nGreat thanks to Sean Stavropoulos (@stavro) for the original awesome work on the library.\n\nThis project is forked from [Arc](https://github.com/stavro/arc) from the version `v0.11.0`.\n\n## License\n\nCopyright 2019 Boris Kuznetsov \u003cme@achempion.com\u003e\n\nCopyright 2015 Sean Stavropoulos\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felixir-waffle%2Fwaffle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felixir-waffle%2Fwaffle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felixir-waffle%2Fwaffle/lists"}