{"id":13879952,"url":"https://github.com/contentful/contentful_rails","last_synced_at":"2025-09-29T12:30:38.909Z","repository":{"id":24342015,"uuid":"27739776","full_name":"contentful/contentful_rails","owner":"contentful","description":"A ruby gem to help you quickly integrate Contentful into your Rails site","archived":true,"fork":false,"pushed_at":"2023-10-26T13:43:00.000Z","size":116,"stargazers_count":52,"open_issues_count":17,"forks_count":35,"subscribers_count":18,"default_branch":"master","last_synced_at":"2024-09-22T15:32:28.535Z","etag":null,"topics":[],"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/contentful.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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":"2014-12-08T23:11:02.000Z","updated_at":"2024-05-08T10:49:00.000Z","dependencies_parsed_at":"2024-06-22T13:16:03.391Z","dependency_job_id":null,"html_url":"https://github.com/contentful/contentful_rails","commit_stats":null,"previous_names":["errorstudio/contentful_rails"],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/contentful%2Fcontentful_rails","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/contentful%2Fcontentful_rails/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/contentful%2Fcontentful_rails/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/contentful%2Fcontentful_rails/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/contentful","download_url":"https://codeload.github.com/contentful/contentful_rails/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219874544,"owners_count":16554590,"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-08-06T08:02:40.316Z","updated_at":"2025-09-29T12:30:33.623Z","avatar_url":"https://github.com/contentful.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# Contentful Rails\n\nA collection of useful things to help make it easier to integrate Contentful into your Rails app.\nIt includes view helpers, a Webhook handler, caching, and a Rails Engine to hook it all together.\n\nThis is a work in progress. It relies on the contentful_model gem (http://github.com/contentful/contentful_model)\n\n## What is Contentful?\n\n[Contentful](https://www.contentful.com) provides a content infrastructure for digital teams to power content in websites, apps, and devices. Unlike a CMS, Contentful was built to integrate with the modern software stack. It offers a central hub for structured content, powerful management and delivery APIs, and a customizable web app that enable developers and content creators to ship digital products faster.\n\n# Configuration\nContentfulRails accepts a block for configuration. Best done in a Rails initializer.\n\n```ruby\nContentfulRails.configure do |config|\n  config.authenticate_webhooks = true # false here would allow the webhooks to process without basic auth\n  config.webhooks_username = \"a basic auth username\"\n  config.webhooks_password = \"a basic auth password\"\n  config.access_token = \"your access token\"\n  config.preview_access_token = \"your preview access token\"\n  config.management_token = \"your management access token\"\n  config.space = \"your space ID\"\n  config.environment = \"your environment ID\"\n  config.contentful_options = \"hash of options\"\nend\n```\n\nNote that you _don't_ have to separately configure ContentfulModel - adding the access tokens / space ID / options here will\npass to ContentfulModel in an initializer in the Rails engine.\n\nThe default is to authenticate the webhooks; probably a smart move to host on an HTTPS endpoint too.\n\n### Entry Mapping\n\nBy default, ContentfulRails will try to define your `entry_mapping` configuration for you.  It does this by iterating through\n the descendents of the base class `ContentfulModel::Base` during initialization.  In order to ensure these classes are\n loaded by this time, it will call `eager_load!` for the entire application.  If this is not desired, you can set the\n `eager_load_entry_mapping` config to false set your entry mapping manually by setting the entry_mapping config\n  as [described here](https://github.com/contentful/contentful.rb#custom-resource-classes).\n\n\n```ruby\nContentfulRails.configure do |config|\n  ...\n  config.eager_load_entry_mapping = false\n  config.contentful_options = {\n    entry_mapping: {\n      'article' =\u003e Article,\n      ...\n    }\n  }\nend\n```\n\n**Note:** If you do not define the entry mapping in your configuration, the webhook cache expiration will likely not work as expected\n\n# Allowing 'Russian Doll' style caching on Entries\nThe issue with 'Russian Doll' caching in Rails is that it requires a hit on the database to check the `updated_at` timestamp of an object.\n\nThis is obviously expensive when the object is called over an API. So this gem wraps caches `updated_at` locally, and checks that first on subsequent calls.\n\n```ruby\nFoo.updated_at #returns a timestamp from cache, or from the API if no cache exists\n```\n\n# Webhooks Endpoint\nIf there's a new version of an entry we need to expire the timestamp from the cache.\n\nThis gem includes a controller endpoint for Contentful to POST back to.\n\nTo make use of this in your app:\n\n## routes.rb\nMount the ContentfulRails engine at your preferred url:\n\n```ruby\nmount ContentfulRails::Engine =\u003e '/contentful' #feel free to choose a different endpoint name\n```\n\nThis will give you 2 routes:\n\n`/contentful/webhooks` - the URL for contentful to post back to.\n`/contentful/webhooks/debug` - a development-only URL to check you have mounted the engine properly :-)\n\n## What the webhook handler does\nAt the moment all this does is delete the timestamp cache entry, which means that a subsequent call to `updated_at` calls the API.\n\n# View Helpers\nContentful has a [really nice url-based image manipulation API](https://www.contentful.com/blog/2014/08/14/do-more-with-images-on-contentful-platform/).\n\nTo take advantage of this, there's a custom Redcarpet renderer which allows you to pass the image parameters you want into the call to a `parse_markdown()` method.\n\nIn your application_controller.rb:\n\n```ruby\nhelper ContentfulRails::MarkdownHelper\n```\n\nThis allows you to call `parse_markdown(@your_markdown)` and get HTML. *Note* that out of the box, the `parse_markdown()` is really permissive and allows you to put HTML in the Contentful markdown fields. This might not be what you want.\n\n## Manipulating images\nTo manipulate images which are referenced in your markdown, you can pass the following into the `parse_markdown()` call.\n\n```ruby\nparse_markdown(@your_markdown, image_options: { width: 1024, height: 1024 })\n```\n\nThe `image_options` parameter takes the following options (some are mutually exclusive. Read the [instructions here](https://www.contentful.com/blog/2014/08/14/do-more-with-images-on-contentful-platform/)):\n\n* `:width`\n* `:height`\n* `:fit`\n* `:focus`\n* `:corner_radius`\n* `:quality`\n\n## Subclassing the MarkdownRenderer class\nSometimes you might want to apply some specific class, markup or similar to an html entity when it's being processed. [With RedCarpet that's dead easy](https://github.com/vmg/redcarpet#and-you-can-even-cook-your-own).\n\nJust subclass the `ContentfulRails::MarkdownRenderer` class, and call any methods you need.\n\n```ruby\nclass MyRenderer \u003c ContentfulRails::MarkdownRenderer\n  # If you want to pass options into your renderer, you need to overload initialize()\n  def initialize(opts)\n    @options = opts\n    super\n  end\n\n  # If you want to do something special with links:\n  def link(link,title,content)\n    # Add a class name to all links, for example\n    class_name = \"my-link-class-name\"\n    content_tag(:a, content, href: link, title: title, class: class_name)\n  end\nend\n```\n\nYou can overload any methods exposed in RedCarpet.\n\n# Preview API\nContenfulRails can be set up to use the [Contenful Preview API](https://www.contentful.com/developers/docs/references/content-preview-api/), and has the option of protecting that content behind basic authentication.\nTo enable the preview api, add the below settings to your configuration.\n\n```\nContentfulRails.configure do |config|\n  config.enable_preview_domain = true # use the preview domain\n  config.preview_access_token = \"your preview access token\"\n  config.preview_username = \"a basic auth username\"\n  config.preview_password = \"a basic auth password\"\nend\n```\n\nIf you site is already protected with another form of authentication, then leave `preview_username` and `preview_password` unset.\nThis will skip the authentication step when displaying preview content.\n\n# To Do\nSome things would be nice to do:\n\n* Tests :-)\n* Make caching the timestamp optional in the configuration\n* Implement a method on ContentfulModel to simulate a parent-child relationship, so we can invalidate caches for parent items\n\n\n# Licence\nLicence is MIT. Please see MIT-LICENCE in this repo.\n\n# Contributing\nPlease feel free to contribute!\n\n* Fork this repo\n* Make your changes\n* Commit\n* Create a PR\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontentful%2Fcontentful_rails","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcontentful%2Fcontentful_rails","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontentful%2Fcontentful_rails/lists"}