{"id":13558096,"url":"https://github.com/thredded/thredded","last_synced_at":"2025-04-23T20:51:20.311Z","repository":{"id":38214954,"uuid":"9949492","full_name":"thredded/thredded","owner":"thredded","description":"The best Rails forums engine ever.","archived":false,"fork":false,"pushed_at":"2024-11-13T18:12:13.000Z","size":3662,"stargazers_count":1589,"open_issues_count":35,"forks_count":214,"subscribers_count":27,"default_branch":"main","last_synced_at":"2025-04-22T21:54:05.712Z","etag":null,"topics":["forums","message-board","rails","rails-engine","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/thredded.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"MIT-LICENSE","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":"2013-05-09T01:17:41.000Z","updated_at":"2025-04-17T14:50:04.000Z","dependencies_parsed_at":"2024-06-18T15:21:23.332Z","dependency_job_id":"1e5be12b-9c79-48ef-98ef-987bd8e9fa2e","html_url":"https://github.com/thredded/thredded","commit_stats":{"total_commits":1688,"total_committers":54,"mean_commits":31.25925925925926,"dds":"0.38684834123222744","last_synced_commit":"5ab22aecdb4db9b7ae426a3489b548ca1a716819"},"previous_names":[],"tags_count":82,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thredded%2Fthredded","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thredded%2Fthredded/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thredded%2Fthredded/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thredded%2Fthredded/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thredded","download_url":"https://codeload.github.com/thredded/thredded/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250331803,"owners_count":21413100,"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":["forums","message-board","rails","rails-engine","ruby"],"created_at":"2024-08-01T12:04:44.675Z","updated_at":"2025-04-23T20:51:20.289Z","avatar_url":"https://github.com/thredded.png","language":"Ruby","readme":"# Thredded\n[![Code Climate](https://codeclimate.com/github/thredded/thredded/badges/gpa.svg)](https://codeclimate.com/github/thredded/thredded)  [![Test Coverage](https://codeclimate.com/github/thredded/thredded/badges/coverage.svg)](https://codeclimate.com/github/thredded/thredded/coverage) [![Inline docs](http://inch-ci.org/github/thredded/thredded.svg?branch=main)](http://inch-ci.org/github/thredded/thredded) [![Gitter](https://badges.gitter.im/thredded/thredded.svg)](https://gitter.im/thredded/thredded?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n[![CI](https://github.com/thredded/thredded/actions/workflows/build.yml/badge.svg)](https://github.com/thredded/thredded/actions/workflows/build.yml)\n\n_Thredded_ is a Rails 7.0+ forum/messageboard engine. Its goal is to be as simple and feature rich as possible.\n\nSome of the features currently in Thredded:\n\n* Markdown (default) and / or BBCode post formatting, with [onebox] and `\u003cspoiler\u003e` / `[spoiler]` tag support.\n* (Un)read posts tracking.\n* Email notifications, topic subscriptions, @-mentions, per-messageboard notification settings.\n* Private group messaging.\n* Full-text search using the database.\n* Pinned and locked topics.\n* List of currently online users, for all forums and per-messageboard.\n* Flexible permissions system.\n* Basic moderation.\n* Lightweight default theme configurable via Sass.\n\n| ![Messageboards (Thredded v0.8.2)](https://cloud.githubusercontent.com/assets/216339/20338810/1fbc4240-abd1-11e6-9cba-4ae2e654c4d4.png) |  ![Topics (Thredded v0.8.2)](https://cloud.githubusercontent.com/assets/216339/20338809/1fbb7dc4-abd1-11e6-9bc3-207b94018931.png) |\n|:---:|:---:|\n| ![Topic on iPhone 6 (Thredded v0.8.2)](https://cloud.githubusercontent.com/assets/216339/20338433/0920debc-abcf-11e6-811c-8f29d10dfed7.png) | ![Messageboard Preferences on iPhone 6 (Thredded v0.8.2)](https://cloud.githubusercontent.com/assets/216339/20338432/090e9c5c-abcf-11e6-8e7e-e287d31f6a54.png) |\n\nThredded works with SQLite, MySQL (v5.6.4+), and PostgreSQL. Thredded has no infrastructure\ndependencies other than the database and, if configured in the parent application, the ActiveJob\nbackend dependency such as Redis. Currently only MRI Ruby 3.1+ is supported. We would love to\nsupport JRuby and Rubinius as well.\n\nIf you're looking for variations on a theme - see [Discourse]. However, it is a full rails\napplication and not an engine like Thredded.\n\n[Discourse]: http://www.discourse.org/\n[onebox]: https://github.com/discourse/onebox\n\nTable of Contents\n=================\n\n* [Installation](#installation)\n  * [Creating a new Rails app with Thredded](#creating-a-new-rails-app-with-thredded)\n  * [Adding Thredded to an existing Rails app](#adding-thredded-to-an-existing-rails-app)\n  * [Upgrading an existing install](#upgrading-an-existing-install)\n  * [Migrating from Forem](#migrating-from-forem)\n* [Rails compatibility](#rails-compatibility)\n* [Views and other assets](#views-and-other-assets)\n  * [Standalone layout](#standalone-layout)\n  * [Application layout](#application-layout)\n    * [Reference your paths so that Thredded can find them](#reference-your-paths-so-that-thredded-can-find-them)\n    * [Add Thredded styles](#add-thredded-styles)\n    * [Add Thredded JavaScripts (Sprockets)](#add-thredded-javascripts-sprockets)\n    * [Add Thredded JavaScripts (Webpack)](#add-thredded-javascripts-webpack)\n  * [User profile page](#user-profile-page)\n  * [Customizing views](#customizing-views)\n    * [View hooks](#view-hooks)\n  * [Theming](#theming)\n    * [Styles](#styles)\n* [Email and other notifications](#email-and-other-notifications)\n  * [Enabling auto-follow](#enabling-auto-follow)\n* [I18n](#i18n)\n* [Permissions](#permissions)\n  * [Permission methods](#permission-methods)\n    * [Reading messageboards](#reading-messageboards)\n    * [Posting to messageboards](#posting-to-messageboards)\n    * [Messaging other users (posting to private topics)](#messaging-other-users-posting-to-private-topics)\n    * [Moderating messageboards](#moderating-messageboards)\n    * [Admin permissions](#admin-permissions)\n  * [Default permissions](#default-permissions)\n  * [Handling \"Permission denied\" and \"Not found\" errors](#handling-permission-denied-and-not-found-errors)\n* [Moderation](#moderation)\n  * [Disabling moderation](#disabling-moderation)\n* [Plugins](#plugins)\n* [Development](#development)\n  * [Testing](#testing)\n  * [Ruby](#ruby)\n  * [JavaScript](#javascript)\n  * [Testing with all the databases and Rails versions locally.](#testing-with-all-the-databases-and-rails-versions-locally)\n  * [Developing and Testing with Docker Compose](#developing-and-testing-with-docker-compose)\n\n\n## Installation\n\n### Creating a new Rails app with Thredded\n\n\u003e [!CAUTION]\n\u003e Please add thredded_create_app is currently out of date and needs contributors to fix it - it won't work with the latest thredded. See https://github.com/thredded/thredded_create_app if you can contribute.\n\n\u003cdetails\u003e\n\u003csummary\u003e\nView the outdated instructions\n\u003c/summary\u003e\n\nThredded provides an app generator that will generate a Rails app with Thredded, Devise, SimpleForm, RSpec,\nPostgreSQL, and a basic theme and navigation that is configured to work out of the box.\n\n```sh\ngem install thredded_create_app\nthredded_create_app path/to/myapp\n```\n\nSee `thredded_create_app --help` and the [thredded_create_app repo] to learn about the various options.\n\nThen, see the rest of this Readme for more information about using and customizing Thredded.\n\n[thredded_create_app repo]: https://github.com/thredded/thredded_create_app\n\n\u003c/details\u003e\n\n### Adding Thredded to an existing Rails app\n\nAdd the gem to your Gemfile:\n\n```ruby\ngem 'thredded', '~\u003e 1.1'\n```\n\nAdd the Thredded [initializer] to your parent app by running the install generator.\n\n```console\nrails generate thredded:install\n```\n\nThredded needs to know the base application User model name and certain columns on it. Configure\nthese in the initializer installed with the command above.\n\nThen, copy the migrations over to your parent application and migrate:\n\n```console\nrake thredded:install:migrations db:migrate db:test:prepare\n```\n\nMount the thredded engine in your routes file:\n\n```ruby\nmount Thredded::Engine =\u003e '/forum'\n```\n\nYou also may want to add an index to the user name column in your users table.\nThredded uses it to find @-mentions and perform name prefix autocompletion on the private topic form.\nAdd the index in a migration like so:\n\n```ruby\nDbTextSearch::CaseInsensitive.add_index(\n    connection, Thredded.user_class.table_name, Thredded.user_name_column, unique: true)\n```\n\n### Upgrading an existing install\n\n1) To upgrade the initializer:\n\n```console\nrails g thredded:install\n```\n\nBut then compare this with the previous version to decide what to keep.\n\n2) To upgrade the database (in this example from v0.11 to v0.12):\n\n```console\n# Note that for guaranteed best results you will want to run this with the thredded gem at v0.12\ncp \"$(bundle show thredded)\"/db/upgrade_migrations/20170420163138_upgrade_thredded_v0_11_to_v0_12.rb db/migrate\nrake db:migrate\n```\n\n### Migrating from Forem\n\nAre you currently using [Forem]? Thredded provides [a migration][forem-to-thredded] to copy all of your existing data from Forem over\nto Thredded.\n\n[forem-to-thredded]: https://github.com/thredded/thredded/wiki/Migrate-from-Forem\n[Forem]: https://github.com/rubysherpas/forem\n\n## Rails compatibility\n\n| Rails      | Latest Thredded   |\n|------------|-------------------|\n| Rails 7.0+ | Thredded 1.2+     |\n| Rails 6.1  | Thredded 1.1      |\n| Rails 6.0  | Thredded 1.1      |\n| Rails 5.2  | Thredded 1.0.1    |\n| Rails 4.2  | Thredded 0.16.16  |\n\n\n## Views and other assets\n\n### Standalone layout\n\nBy default, thredded renders in its own (standalone) layout.\n\nWhen using the standalone thredded layout, the log in / sign out links will be rendered in the navigation.\nFor these links (and only for these links), Thredded makes the assumption that you are using devise as your auth\nlibrary. If you are using something different you need to override the partial at\n`app/views/thredded/shared/nav/_standalone.html.erb` and use the appropriate log in / sign out path URL helpers.\n\nYou can override the partial by copying it into your app:\n\n```bash\nmkdir -p app/views/thredded/shared/nav \u0026\u0026 cp \"$(bundle show thredded)/$_/_standalone.html.erb\" \"$_\"\n```\n\n### Application layout\n\nYou can also use Thredded with your application (or other) layout by setting `Thredded.layout` in the initializer.\n\nIn this case, you will need to reference your paths/routes carefully and pull in thredded assets (styles and javascript):\n\n#### Reference your paths so that Thredded can find them\n\nIn your layout you will probably have links to other paths in your app (e.g. navigation links).\nFor any url helpers (like `users_path` or `projects_path` or whatever) will need to have `main_app.`\nprefixed to them so that they can be found from thredded (`main_app.users_path` will work from both thredded and your app).\n\n#### Add Thredded styles\n\nIn this case, you will also need to include Thredded styles and JavaScript into the application styles and JavaScript.\n\nAdd thredded styles to your `application.scss`:\n\n```scss\n@import \"thredded\";\n```\n\nThredded wraps the views in a container element that has a `max-width` and paddings by default.\nIf your app layout already has a container element that handles these, you can remove the `max-width` and paddings\nfrom the Thredded one by adding this Sass snippet after `@import \"thredded\";`:\n\n```scss\n.thredded--main-container {\n  // The padding and max-width are handled by the app's container.\n  max-width: none;\n  padding: 0;\n  @include thredded-media-tablet-and-up {\n    padding: 0;\n  }\n}\n```\n\nSee [below](#styles) for customizing the styles via Sass variables.\n\n#### Add Thredded JavaScripts (Sprockets)\n\nInclude thredded JavaScripts in your `application.js`:\n\n```js\n//= require thredded\n```\n\nThredded is fully compatible with deferred and async script loading.\n\n#### Add Thredded JavaScripts (Webpack)\n\nYou can also include Thredded JavaScript into your webpack pack.\n\nFirst, run `bundle exec rails webpacker:install:erb`.\n\nThen, add an `app/javascript/thredded_imports.js.erb` file with the following contents:\n\n```erb\n\u003c%= Thredded::WebpackAssets.javascripts %\u003e\n```\n\nFinally, add the following to your `app/javascript/packs/application.js`:\n\n```js\nrequire('thredded_imports.js');\n```\n\nNote that you must use `require` (not `import`) because Thredded JavaScript must be run after UJS/Turbolink `start()`\nhas been called. This is because Webpack places `import` calls before the code in the same file (unlike `require`,\nwhich are placed in the same order as in the source).\n\n##### Alternative JavaScript dependencies\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eRails UJS version\u003c/b\u003e\u003c/summary\u003e\n\nBy default, thredded loads `rails-ujs`.\n\nIf you'd like it to use `jquery_ujs` instead, run this command from your app directory:\n\n```bash\nmkdir -p app/assets/javascripts/thredded/dependencies/\nprintf '//= require jquery3\\n//= require jquery_ujs\\n' \u003e app/assets/javascripts/thredded/dependencies/ujs.js\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eTimeago version\u003c/b\u003e\u003c/summary\u003e\n\nBy default, thredded loads `timeago.js`.\n\nIf you'd like to use `jquery.timeago` or `rails-timeago` instead, run this command from your app directory:\n\n```bash\nmkdir -p app/assets/javascripts/thredded/dependencies/\necho '//= require jquery.timeago' \u003e app/assets/javascripts/thredded/dependencies/timeago.js\n```\n\nYou will also need to adjust the `//= require` statements for timeago locales if your site is translated into multiple\nlanguages. For `jquery.timeago`, these need to be require after `thredded/dependencies` but before `thredded/thredded`.\nE.g. for Brazilian Portuguese with jquery.timeago:\n\n ```js\n //= require thredded/dependencies\n //= require locales/jquery.timeago.pt-br\n //= require thredded/thredded\n ```\n\u003c/details\u003e\n\n#### Thredded page title and ID\n\nThredded views also provide two `content_tag`s available to yield - `:thredded_page_title` and `:thredded_page_id`.\nThe views within Thredded pass those up through to your layout if you would like to use them.\n\n### User profile page\n\nThredded does not provide a user's profile page, but it provides a partial for rendering the user's recent posts\nin your app's user profile page. Here is how you can render it in your app:\n\n```erb\n\u003c%= Thredded::ApplicationController.render partial: 'thredded/users/posts', locals: {\n      posts: Thredded.posts_page_view(scope: user.thredded_posts.order_newest_first.limit(5),\n                                      current_user: current_user) } %\u003e\n```\n\nThe `user` above is the user whose posts are rendered, and `current_user` is the user viewing the posts or `nil`.\nThe policy scopes that limit the posts to the ones `current_user` can see are applied automatically.\n\nThe code above uses the `ApplicationController.render` method introduced in Rails 5. If you're using Rails 4,\nyou will need to add the [`backport_new_renderer`](https://github.com/brainopia/backport_new_renderer) gem to use it.\n\n### Customizing views\n\nYou can also override any views and assets by placing them in the same path in your application as they are in the gem.\nThis uses the [standard Rails mechanism](http://guides.rubyonrails.org/engines.html#overriding-views) for overriding\nengine views. For example, to copy the post view for customization:\n\n```bash\n# Copy the post view into the application to customize it:\nmkdir -p app/views/thredded/posts \u0026\u0026 cp \"$(bundle show thredded)/$_/_post.html.erb\" \"$_\"\n```\n\n**NB:** Overriding the views like this means that on every update of the thredded gem you have to check that your\ncustomizations are still compatible with the new version of thredded. This is difficult and error-prone.\nWhenever possible, use the styles and i18n to customize Thredded to your needs.\n\n#### View hooks\n\nThredded provides view hooks to customize the UI before/after/replacing individual components.\n\nView hooks allow you to render anything in the thredded view context.\nFor example, to render a partial after the post content textarea, add the snippet below to\nthe `config/initializers/thredded.rb` initializer:\n\n```ruby\nRails.application.config.to_prepare do\n  Thredded.view_hooks.post_form.content_text_area.config.before do |form:, **args|\n    # This is render in the Thredded view context, so all Thredded helpers and URLs are accessible here directly.\n    render 'my/partial', form: form\n  end\nend\n```\n\nYou can use the post content textarea hook to add things like wysiwyg/wymean editors, buttons, help links, help copy,\nfurther customization for the textarea, etc.\n\nTo see the complete list of view hooks and their arguments, run:\n\n```bash\ngrep view_hooks -R --include '*.html.erb' \"$(bundle show thredded)\"\n```\n\n### Theming\n\nThe engine comes by default with a light and effective implementation of the\nviews, styles, and javascript. Once you mount the engine you will be presented\nwith a \"themed\" version of thredded.\n\n#### Styles\n\nThredded comes with a light Sass theme controlled by a handful of variables that can be found here:\nhttps://github.com/thredded/thredded/blob/main/app/assets/stylesheets/thredded/base/_variables.scss.\n\nTo override the styles, override the variables *before* importing Thredded styles, e.g.:\n\n```scss\n// application.scss\n$thredded-brand: #9c27b0;\n@import \"thredded\";\n```\n\nIf you are writing a Thredded plugin, import the [`thredded/base`][thredded-scss-base] Sass package instead.\nThe `base` package only defines variables, mixins, and %-placeholders, so it can be imported safely without producing\nany duplicate CSS.\n\n[thredded-scss-dependencies]: https://github.com/thredded/thredded/blob/main/app/assets/stylesheets/thredded/_dependencies.scss\n[thredded-scss-base]: https://github.com/thredded/thredded/blob/main/app/assets/stylesheets/thredded/_base.scss\n\n### Email and other notifications\n\nThredded sends several notification emails to the users. You can override in the same way as the views.\nSee [this page](https://github.com/thredded/thredded/wiki/Styling-email-content) on how to style the emails.\n\nIf you use [Rails Email Preview], you can include Thredded emails into the list of previews by adding\n`Thredded::BaseMailerPreview.preview_classes` to the [Rails Email Preview] `preview_classes` config option.\n\n[Rails Email Preview]: https://github.com/glebm/rails_email_preview\n\nYou can also turn off the email notifier totally, or add other notifiers (e.g. Pushover, possibly Slack) by adjusting\nthe `Thredded.notifiers` configuration in your initializer. See the default initializer for examples.\n\nYou must configure the address the email appears to be from (`Thredded.email_from`). This address is also used as the \"To\" address for both email notifcations, as all the recipients are on bcc.\n\n### Enabling auto-follow\n\nIn some cases, you'll want all users to auto-follow new messageboard topics by default. This might be useful\nfor a team messageboard or a company announcements board, for example. To enable user auto-follow of new topics,\nrun the following migration(s):\n\n```ruby\nchange_column_default :thredded_user_preferences, :auto_follow_topics, true\n```\n\n## I18n\n\nThredded is mostly internationalized. It is currently available in English, Brazilian Portuguese, Chinese (Simplified),\nGerman, Polish, Italian, Russian, French, and Spanish.\nWe welcome PRs adding support for new languages.\n\nHere are the steps to ensure the best support for your language if it isn't English:\n\n1. Add `rails-i18n` and `kaminari-i18n` to your Gemfile.\n\n2. Require the translations for timeago.js in your JavaScript. E.g. if you want to add German and Brazilian Portuguese:\n\n   Sprockets:\n\n   ```js\n   //= require thredded/dependencies/timeago\n   //= require timeago/locales/de\n   //= require timeago/locales/pt_BR\n   //= require thredded\n   ```\n\n   Webpack:\n\n   ```erb\n   \u003c% timeago_root = File.join(Gem.loaded_specs['timeago_js'].full_gem_path, 'assets', 'javascripts') %\u003e\n   import \"\u003c%= File.join(timeago_root, 'timeago.js') %\u003e\";\n   \u003c%= %w[de pt_BR].map { |locale| %(import \"#{File.join(timeago_root, \"timeago/locales/#{locale}.js\")}\";) } * \"\\n\" %\u003e\n   \u003c%= Thredded::WebpackAssets.javascripts %\u003e\n   ```\n\n   Note that it is important that timeago and its locales are required *before* Thredded.\n\n3. To generate URL slugs for messageboards, categories, and topics with support for more language than English,\n   you can use a gem like [babosa](https://github.com/norman/babosa).\n   Add babosa to your Gemfile and uncomment the `Thredded.slugifier` proc for babosa in the initializer.\n\n## Permissions\n\nThredded comes with a flexible permissions system that can be configured per messageboard/user.\nIt calls a handful of methods on the application `User` model to determine permissions for logged in users, and calls\nthe same methods on `Thredded:NullUser` to determine permissions for non-logged in users.\n\n### Permission methods\n\nThe methods used by Thredded for determining the permissions are described below.\n\n* To customize permissions for logged in users, override any of the methods below on your `User` model.\n* To customize permissions for non-logged in users, override these methods on `Thredded::NullUser`.\n\n#### Reading messageboards\n\n1. A list of messageboards that a given user can read:\n\n  ```ruby\n  # @return [ActiveRecord::Relation] messageboards that the user can read\n  thredded_can_read_messageboards\n  ```\n2. A list of users that can read a given list of messageboards:\n\n  ```ruby\n  # @param messageboards [Array\u003cThredded::Messageboard\u003e]\n  # @return [ActiveRecord::Relation] users that can read the given messageboards\n  self.thredded_messageboards_readers(messageboards)\n  ```\n\n#### Posting to messageboards\n\nA list of messageboards that a given user can post in.\n\n  ```ruby\n  # @return [ActiveRecord::Relation\u003cThredded::Messageboard\u003e] messageboards that the user can post in\n  thredded_can_write_messageboards\n  ```\n\n#### Messaging other users (posting to private topics)\n\nA list of users a given user can message:\n\n```ruby\n# @return [ActiveRecord::Relation] the users this user can include in a private topic\nthredded_can_message_users\n```\n\n#### Moderating messageboards\n\nA list of messageboards that a given user can moderate:\n\n  ```ruby\n  # @return [ActiveRecord::Relation\u003cThredded::Messageboard\u003e] messageboards that the user can moderate\n  thredded_can_moderate_messageboards\n  ```\n\n#### Admin permissions\n\nIncludes all of the above for all messageboards:\n\n```ruby\n# @return [boolean] Whether this user has full admin rights on Thredded\nthredded_admin?\n```\n\n### Default permissions\n\nBelow is an overview of the default permissions, with links to the implementations:\n\n\u003ctable\u003e\n\u003cthead\u003e\n  \u003ctr\u003e\n    \u003cth align=\"center\"\u003e\u003c/th\u003e\n    \u003cth align=\"center\"\u003eRead\u003c/th\u003e\n    \u003cth align=\"center\"\u003ePost\u003c/th\u003e\n    \u003cth align=\"center\"\u003eMessage\u003c/th\u003e\n    \u003cth align=\"center\"\u003eModerate\u003c/th\u003e\n    \u003cth align=\"center\"\u003eAdministrate\u003c/th\u003e\n  \u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n  \u003cth align=\"center\"\u003eLogged in\u003c/th\u003e\n  \u003ctd align=\"center\" rowspan=\"2\"\u003e\u003ca href=\"https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/read/all.rb\"\u003e\n    ✅ All\n  \u003c/a\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/write/all.rb\"\u003e\n    ✅ All\n  \u003c/a\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb\"\u003e\n    Readers of the messageboards\u003cbr\u003ethe user can post in\n  \u003c/a\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/moderate/if_moderator_column_true.rb\"\u003e\n    \u003ccode\u003emoderator_column\u003c/code\u003e\n  \u003c/a\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/admin/if_admin_column_true.rb\"\u003e\n    \u003ccode\u003eadmin_column\u003c/code\u003e\n  \u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n  \u003cth align=\"center\"\u003eNot logged in\u003c/th\u003e\n  \u003c!-- rowspan --\u003e\n  \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/write/none.rb\"\u003e\n    ❌ No\n  \u003c/a\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb\"\u003e\n    ❌ No\n  \u003c/a\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/moderate/none.rb\"\u003e\n    ❌ No\n  \u003c/a\u003e\u003c/td\u003e\n  \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/admin/none.rb\"\u003e\n    ❌ No\n  \u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n### Handling \"Permission denied\" and \"Not found\" errors\n\nThredded defines a number of Exception classes for not found / permission denied errors.\nThe complete list can be found [here](https://github.com/thredded/thredded/blob/main/app/controllers/thredded/application_controller.rb#L18-L40).\n\nCurrently, the default behaviour is to render an error message with an appropriate response code within the Thredded\nlayout. You may want to override the handling for `Thredded::Errors::LoginRequired` to render a login form instead.\nFor an example of how to do this, see the initializer.\n\n## Moderation\n\nThredded comes with two options for the moderation system:\n\n1. Reactive moderation, where posts from first-time users are published immediately but enter the moderation queue\n   (default).\n2. Pre-emptive moderation, where posts from first-time users are not published until they have been approved.\n\nThis is controlled by the `Thredded.content_visible_while_pending_moderation` setting.\n\nUsers, topics, and posts can be in one of three moderation states: `pending_moderation`, `approved`, and `blocked`.\nBy default, new users are `pending_moderation`, and new posts and topics inherit their default moderation_state from\nthe user's.\n\nWhen you approve a new user's post, all of their later posts will be approved automatically.\n\nAdditionally, users always see their own posts regardless of the moderation state. For blocked users, this means\nthey might not realize they have been blocked right away.\n\nBlocked users cannot send private messages.\n\n### Disabling moderation\n\nTo disable moderation, e.g. if you run internal forums that do not need moderation, run the following migration:\n\n```ruby\nchange_column_default :thredded_user_details, :moderation_state, 1 # approved\n```\n\n### Requiring authentication to access Thredded\n\nTo require users to be authenticated to access any part of Thredded, add the following to your initializer:\n\n```ruby\n# config/initializers/thredded.rb\nRails.application.config.to_prepare do\n  Thredded::ApplicationController.module_eval do\n    # Require authentication to access the forums:\n    before_action :thredded_require_login!\n\n    # You may also want to render a login form after the\n    # \"Please sign in first\" message:\n    rescue_from Thredded::Errors::LoginRequired do |exception|\n      # Place the code for rendering the login form here, for example:\n      flash.now[:notice] = exception.message\n      controller = Users::SessionsController.new\n      controller.request = request\n      controller.request.env['devise.mapping'] = Devise.mappings[:user]\n      controller.response = response\n      controller.response_options = { status: :forbidden }\n      controller.process(:new)\n    end\n  end\nend\n```\n\n## Plugins\n\nThe following official plugins are available for Thredded:\n\n* [BBCode](https://github.com/thredded/thredded-bbcode) formatting for posts, e.g. `[b]for bold[/b]`. Can be used alongside Markdown.\n* [Code Syntax Highlighting in Markdown](https://github.com/thredded/thredded-markdown_coderay) using Coderay.\n* [TeX math via KaTeX in Markdown](https://github.com/thredded/thredded-markdown_katex), fast, accessible, JS-free math rendering.\n\nThredded is built for extensibility, and writing plugins for it is easy. If you plan on extending Thredded functionality\nin a way others may benefit from, please consider making it a plugin.\n\n## Development\n\nTo be more clear - this is the for when you are working on *this* gem.\nNot for when you are implementing it into your Rails app.\n\nFirst, to get started, migrate and seed the database (SQLite by default):\n\n```bash\nbundle\n# Create, migrate, and seed the development database with fake forum users, topics, and posts:\nbin/rails db:create db:migrate db:seed\n```\n\nInstall NPM dependencies for the dummy app:\n\n```bash\ncd spec/dummy \u0026\u0026 yarn \u0026\u0026 cd -\n```\n\nThen, start the dummy app server:\n\n```bash\nbin/rails s\n```\n\nBy default, the dummy app server uses Webpack for JavaScript.\nTo use Sprockets instead, run:\n\n```bash\nTHREDDED_TESTAPP_SPROCKETS=1 bin/rails s\n```\n\nalternatively you can use guard (which comes with activereload to make development more pleasant) with:\n\n    export THREDDED_USE_GUARD=1\n    bundle\n    bundle exec guard\n\n\n### Testing\n\nIn order to run the tests locally, you will need to be running webpack-dev-server (or do a manual compilation):\n\n    cd spec/dummy \u0026\u0026 yarn \u0026\u0026 cd -\n    BUNDLE_GEMFILE=\"${PWD}/Gemfile\" spec/dummy/bin/webpack-dev-server\n\nThen to run the tests, just run `rspec`. The test suite will re-create the test database on every run, so there is no need to\nrun tasks that maintain the test database.\n\nBy default, SQLite is used in development and test. On Travis, the tests will run using SQLite, PostgreSQL, MySQL,\nand all the supported Rails versions.\n\nThe test suite requires Chromium v59+ and its WebDriver installed:\n\nOn Ubuntu, run:\n\n```bash\nsudo apt-get install chromium-chromedriver\n```\n\nOn Mac, run:\n\n```bash\nbrew install --cask chromium\nbrew install --cask chromedriver\n```\n\nTo get better page saves (`page.save_and_open_page`) from local capybara specs ensure you are running the server locally\nand set `export CAPYBARA_ASSET_HOST=http://localhost:3000` (or whatever host/port your server is on) before running your\ntest suite.\n\n### Ruby\n\nThredded Ruby code formatting is ensured by [Rubocop](https://github.com/bbatsov/rubocop). Run `rubocop -a` to ensure a\nconsistent code style across the codebase.\n\nThredded is documented with [YARD](http://yardoc.org/) and you can use the\n[inch gem](https://github.com/rrrene/inch) or the [Inch CI](http://inch-ci.org/github/thredded/thredded) to find code\nthat lacks documentation.\n\n### JavaScript\n\nCurrently, Thredded JavaScript is written in the subset of ES6 that does not\nrequire Babel polyfills. We're waiting for the ES6/7 support on Rails to improve\nbefore updating this to full Babel.\n\nAll Thredded JavaScript is compatible with the following Turbolinks options:\n\n* No Turbolinks.\n* Turbolinks 5.\n* Turbolinks Classic.\n* Turbolinks Classic + jquery-turbolinks.\n\nThredded JavaScript is also compatible with being loaded from script elements with\n`[async]` and/or `[defer]` attributes.\n\nTo achieve the above, all the Thredded code must register onload via\n`Thredded.onPageLoad`, e.g.:\n\n```js\nwindow.Thredded.onPageLoad(() =\u003e {\n  // Initialize widgets\n  autosize('textarea');\n});\n```\n\nAdditionally, all the thredded views must be wrapped in a `\u003c%= thredded_page do %\u003e` block.\n\nOn Turbolinks 5 onPageLoad will run on the same DOM when the page is restored\nfrom history (because Turbolinks 5 caches a *clone* of the body node, so\nthe events are lost).\n\nThis means that all DOM modifications on `window.Thredded.onPageLoad` must be\nidempotent, or they must be reverted on the `turbolinks:before-cache` event,\ne.g.:\n\n```js\ndocument.addEventListener('turbolinks:before-cache', () =\u003e {\n  // Destroy widgets\n  autosize.destroy('textarea');\n});\n```\n\n### Testing with all the databases and Rails versions locally.\n\nYou can also test the gem with all the supported databases and Rails versions locally.\n\nFirst install PostgreSQL and MySQL, and run:\n\n```bash\nscript/create-db-users\n```\n\nThen, to test with all the databases and the default Rails version (as defined in `Gemfile`), run:\n\n```bash\nrake test_all_dbs\n```\n\nTo test with a specific database and all the Rails versions, run:\n\n```bash\n# Test with SQLite3:\nrake test_all_gemfiles\n# Test with MySQL:\nDB=mysql2 rake test_all_gemfiles\n# Test with PostgreSQL:\nDB=postgresql rake test_all_gemfiles\n```\n\nTo test all combinations of supported databases and Rails versions, run:\n\n```bash\nrake test_all\n```\n\n### Developing and Testing with [Docker Compose](http://docs.docker.com/compose/)\n\nTo quickly try out _Thredded_ with the included dummy app, clone the source and\nstart the included docker-compose.yml file with:\n\n```console\ndocker-compose build\ndocker-compose up\n```\n\nThe above will build and run everything, daemonized, resulting in a running\ninstance on port 9292. Running `docker-compose logs` will let you know when\neverything is up and running. Editing the source on your host machine will\nbe reflected in the running docker'ized application.\n\nNote that when using [boot2docker](https://github.com/boot2docker/boot2docker)\non a Mac make sure you visit the boot2docker host ip at\n`http://$(boot2docker ip):9292`.\n\nAfter booting up the containers you can run the test suite with the following:\n\n```console\ndocker-compose run web bundle exec rake\n```\n\nThe docker container uses PostgreSQL.\n\n[initializer]: https://github.com/thredded/thredded/blob/main/lib/generators/thredded/install/templates/initializer.rb\n","funding_links":[],"categories":["Ruby","Social Networking","Software","ruby","Apps","Happy Exploring 🤘"],"sub_categories":["Communication - Social Networks and Forums","SocialMedia"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthredded%2Fthredded","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthredded%2Fthredded","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthredded%2Fthredded/lists"}