Full Code of plataformatec/show_for for AI

main 0c847172d160 cached
40 files
62.1 KB
17.7k tokens
86 symbols
1 requests
Download .txt
Repository: plataformatec/show_for
Branch: main
Commit: 0c847172d160
Files: 40
Total size: 62.1 KB

Directory structure:
gitextract_7x2s2uzu/

├── .github/
│   ├── code-scanning.yml
│   └── workflows/
│       └── test.yml
├── .gitignore
├── CHANGELOG.md
├── Gemfile
├── MIT-LICENSE
├── README.md
├── Rakefile
├── gemfiles/
│   ├── Gemfile-rails-7-0
│   ├── Gemfile-rails-7-1
│   ├── Gemfile-rails-7-2
│   ├── Gemfile-rails-8-0
│   └── Gemfile-rails-main
├── lib/
│   ├── generators/
│   │   └── show_for/
│   │       ├── USAGE
│   │       ├── install_generator.rb
│   │       └── templates/
│   │           ├── en.yml
│   │           ├── show.html.erb
│   │           ├── show.html.haml
│   │           ├── show.html.slim
│   │           └── show_for.rb
│   ├── show_for/
│   │   ├── association.rb
│   │   ├── attribute.rb
│   │   ├── builder.rb
│   │   ├── content.rb
│   │   ├── helper.rb
│   │   ├── label.rb
│   │   └── version.rb
│   └── show_for.rb
├── show_for.gemspec
└── test/
    ├── association_test.rb
    ├── attribute_test.rb
    ├── builder_test.rb
    ├── content_test.rb
    ├── generators/
    │   └── show_for_generator_test.rb
    ├── helper_test.rb
    ├── label_test.rb
    ├── support/
    │   ├── misc_helpers.rb
    │   └── models.rb
    ├── test_helper.rb
    └── value_test.rb

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/code-scanning.yml
================================================
paths-ignore:
  - test/**


================================================
FILE: .github/workflows/test.yml
================================================
name: Test

permissions:
  contents: read
on:
  push:
    branches:
      - main
  pull_request:
  workflow_dispatch:
jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        gemfile:
          - Gemfile
          - gemfiles/Gemfile-rails-main
          - gemfiles/Gemfile-rails-8-0
          - gemfiles/Gemfile-rails-7-2
          - gemfiles/Gemfile-rails-7-1
          - gemfiles/Gemfile-rails-7-0
        ruby:
          - '4.0'
          - '3.4'
          - '3.3'
          - '3.2'
          - '3.1'
          - '3.0'
          - '2.7'
        exclude:
          - gemfile: Gemfile
            ruby: '3.1'
          - gemfile: Gemfile
            ruby: '3.0'
          - gemfile: Gemfile
            ruby: '2.7'
          - gemfile: gemfiles/Gemfile-rails-main
            ruby: '3.2'
          - gemfile: gemfiles/Gemfile-rails-main
            ruby: '3.1'
          - gemfile: gemfiles/Gemfile-rails-main
            ruby: '3.0'
          - gemfile: gemfiles/Gemfile-rails-main
            ruby: '2.7'
          - gemfile: gemfiles/Gemfile-rails-8-0
            ruby: '3.1'
          - gemfile: gemfiles/Gemfile-rails-8-0
            ruby: '3.0'
          - gemfile: gemfiles/Gemfile-rails-8-0
            ruby: '2.7'
          - gemfile: gemfiles/Gemfile-rails-7-2
            ruby: '3.0'
          - gemfile: gemfiles/Gemfile-rails-7-2
            ruby: '2.7'
    runs-on: ubuntu-latest
    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
      BUNDLE_GEMFILE: ${{ matrix.gemfile }}
    steps:
      - uses: actions/checkout@v4
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby }}
          bundler-cache: true # runs bundle install and caches installed gems automatically
      - run: bundle exec rake


================================================
FILE: .gitignore
================================================
.bundle/
pkg/
gemfiles/*.lock


================================================
FILE: CHANGELOG.md
================================================
## Unreleased

* Ruby 4.0 support (no changes required)

## 0.9.0

* Add support for Ruby 3.3/3.4 and Rails 7.2/8.0/8.1. (no changes required)
* Drop support for Rails < 7 and Ruby < 2.7.

## 0.8.1

* Add support for Rails 7.0/7.1 and Ruby 3.1/3.2 (no changes required)
* Remove test files from the gem package.

## 0.8.0

* Respect `nil` value when provided, by skipping model attribute value.
* Add support for Ruby 3.0, drop support for Ruby < 2.5.
* Add support for Rails 6.1, drop support for Rails < 5.2.
* Move CI to GitHub Actions.

## 0.7.0

* Add support for Rails 6.0.
* Drop support for Rails < 5.0 and Ruby < 2.4.

## 0.6.1

* Add support for Rails 5.2.
*  Fix issue causing blank class not being applied to field wrapper when the result of a Proc is empty.

## 0.6.0

* Relaxed dependencies to support Rails 5.1.

## 0.5.0

* Relaxed dependencies to support Rails 5.
* Removed support for Rails `3.2` and `4.0` and Ruby `1.9.3` and `2.0.0`.

### enhancements
  * Do not generate label/content/wrapper/collection classes when config is set to `nil`.

## 0.4.0

### enhancements
  * Change default `wrapper_tag` to generate a `div` instead of `p`. The `p` tag generates
    invalid HTML with collections: `p > ul`, and failed tests on Rails 4.2. If you depend
    on the `p` tag being generated, change your Show For config to set `wrapper_tag` to `:p`.
  * Remove deprecated `:method` in favor of `:using`.
  * Improve support to Rails 4.x associations with more duck typing instead of Array checks.
  * Support Rails 4.1/4.2 and Ruby 2.1/2.2.
  * Add `skip_blanks` configuration option to skip generating blank attributes
    instead of generating them with a default message. (by github.com/moktin)
  * Add `slim` template for the install generator. (by github.com/voanhduy1512)
  * Add `separator` option that overrides the global configuration (by github.com/bernardofire)

### bugfix
  * Do not yield default blank value to the block when using an empty association. (by github.com/aptinio)

## 0.3.0

### bug fix
  * Fix blank value not being applied when using a block. (by github.com/tfwright)

## 0.3.0.rc

### enhancements
  * Support Rails 4.
  * Drop support to Rails < 3.2 and Ruby 1.8.

## 0.2.6

### enhancements
  * Ruby 2.0 support.
  * Add Haml template. (by github.com/nashby) Closes #12.
  * Add `blank_html` tanslation. (by github.com/nashby)
  * Add `show_for_class` configuration option. (by github.com/nashby)

### bug fix
  * Make show_for works with namespaced models. (by github.com/fabiokr)
  * Add `blank_content_class` to the attributes. (by github.com/blakehilscher). Closes #24.
  * Don't call `association.map` if association method is nil (by github.com/nashby). Closes #40.

## 0.2.5

### enhancements
  * Add a `:value` option for attribute (by github.com/ml-gt)
  * Add `label_class`, `content_class`, `wrapper_class` and `collection_class` configuration options (by github.com/wojtekmach)

### bug fix
  * Fix problem with `label => false` and `html_safe` (label => false) (by github.com/nashby)

## 0.2.4

### enhancements
  * Do not add separator if label is not present (by github.com/eugenebolshakov)
  * Add method for output value only (by github.com/jenkek)

### bug fix
  * Fix empty labels to be `html_safe` (label => false) (by github.com/eugenebolshakov)

## 0.2.3

### enhancements
  * added :attributes method to generate all attributes given
  * update generator to use the new syntax show_for:install

### bug fix
  * fix numeric types

## 0.2.2

### bug fix
  * allow show_for to work with AR association proxies

### enhancements
  * improvements on html safe and output buffers

## 0.2.1

### enhancements
  * added label_proc
  * compatibility with latest Rails

## 0.2.0

### enhancements
  * Rails 3 compatibility

## 0.1.4

### bug fix
  * allow show_for to work with AR association proxies

## 0.1.3

### enhancements
  * allow builder to be given to show_for

### bug fix
  * Fix typo in yaml

## 0.1.2

### enhancements
  * allow `f.attribute :nickname, in: :profile` as association shortcut

### deprecations
  * `:method` now becomes `:using`

## 0.1.1

### enhancements
  * HAML compatibility (by github.com/grimen)
  * blank_content support (by github.com/grimen)

## 0.1

### First release


================================================
FILE: Gemfile
================================================
source 'https://rubygems.org'

gemspec

gem 'railties', '~> 8.1.0'
gem 'activemodel', '~> 8.1.0'
gem 'actionpack', '~> 8.1.0'


================================================
FILE: MIT-LICENSE
================================================
Copyright (c) 2020-CURRENT Rafael França, Carlos Antonio da Silva
Copyright (c) 2012-2019 Plataformatec

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# ShowFor

[![Gem Version](https://badge.fury.io/rb/show_for.svg)](https://badge.fury.io/rb/show_for)

ShowFor allows you to quickly show a model information with I18n features.

```erb
<%= show_for @user do |u| %>
  <%= u.attribute :name %>
  <%= u.attribute :nickname, in: :profile %>
  <%= u.attribute :confirmed? %>
  <%= u.attribute :created_at, format: :short %>
  <%= u.attribute :last_sign_in_at, if_blank: "User did not access yet",
                  wrapper_html: { id: "sign_in_timestamp" } %>

  <%= u.attribute :photo do %>
    <%= image_tag(@user.photo_url) %>
  <% end %>

  <%= u.association :company %>
  <%= u.association :tags, to_sentence: true %>
<% end %>
```

## Installation

Install the gem:

    gem install show_for

Or add ShowFor to your Gemfile and bundle it up:

    gem 'show_for'

Run the generator:

    rails generate show_for:install

And you are ready to go.

Note: This branch aims Rails 7 and 8 support, so if you want to use it with
older versions of Rails, check out the available branches.

## Usage

ShowFor allows you to quickly show a model information with I18n features.

```erb
<%= show_for @admin do |a| %>
  <%= a.attribute :name %>
  <%= a.attribute :login, value: :upcase %>
  <%= a.attribute :confirmed? %>
  <%= a.attribute :created_at, format: :short %>
  <%= a.attribute :last_sign_in_at, if_blank: "Administrator did not access yet"
                  wrapper_html: { id: "sign_in_timestamp" } %>

  <%= a.attribute :photo do %>
    <%= image_tag(@admin.photo_url) %>
  <% end %>

  <% a.value :biography %>
<% end %>
```

Will generate something like:

```html
<div id="admin_1" class="show_for admin">
  <div class="wrapper admin_name">
    <strong class="label">Name</strong><br />
    José Valim
  </div>
  <div class="wrapper admin_login">
    <strong class="label">Login</strong><br />
    JVALIM
  </div>
  <div class="wrapper admin_confirmed">
    <strong class="label">Confirmed?</strong><br />
    Yes
  </div>
  <div class="wrapper admin_created_at">
    <strong class="label">Created at</strong><br />
    13/12/2009 - 19h17
  </div>
  <div id="sign_in_timestamp" class="wrapper admin_last_sign_in_at">
    <strong class="label">Last sign in at</strong><br />
    Administrator did not access yet
  </div>
  <div class="wrapper admin_photo">
    <strong class="label">Photo</strong><br />
    <img src="path/to/photo" />
  </div>
  <div class="wrapper admin_biography">
    Etiam porttitor eros ut diam vestibulum et blandit lectus tempor. Donec
    venenatis fermentum nunc ac dignissim. Pellentesque volutpat eros quis enim
    mollis bibendum. Ut cursus sem ac sem accumsan nec porttitor felis luctus.
    Sed purus nunc, auctor vitae consectetur pharetra, tristique non nisi.
  </div>
</div>
```

You can also show a list of attributes, useful if you don't need to change any configuration:

```erb
<%= show_for @admin do |a| %>
  <%= a.attributes :name, :confirmed?, :created_at %>
<% end %>
```

## Value lookup

ShowFor uses the following sequence to get the attribute value:

* use the output of a block argument if given
* use the output of the `:value` argument if given
* check if a `:"human_#{attribute}"` method is defined
* retrieve the attribute directly.

## Options

ShowFor handles a series of options. Those are:

* __:format__ - Sent to `I18n.localize` when the attribute is a date/time object.

* __:value__ - Can be used instead of block. If a `Symbol` is called as instance method.

* __:if_blank__ - An object to be used if the value is blank. Not escaped as well.

* __:separator__ - The piece of html that separates label and content, overriding the global configuration.

In addition, all containers (`:label`, `:content` and `:wrapper`) can have their html
options configured through the `:label_html`, `:content_html` and `:wrapper_html`
options. Containers can have their tags configured on demand as well through
`:label_tag,` `:content_tag` and `:wrapper_tag` options.

## Label

ShowFor also exposes the label method. In case you want to use the default
`human_attribute_name` lookup and the default wrapping:

```ruby
a.label :name                  #=> <strong class="label">Name</strong>
a.label "Name", id: "my_name"  #=> <strong class="label" id="my_name">Name</strong>
```

Optionally, if you want to wrap the inner part of the label with some text
(e.g. adding a semicolon), you can do so by specifying a proc for `ShowFor.label_proc`
that will be called with any label text. E.g.:

```ruby
  ShowFor.label_proc = lambda { |l| l + ":" }
```

When taking this route, you can also skip on a per label basis by passing the
`:wrap_label` option with a value of false.

## Associations

ShowFor also supports associations.

```erb
<%= show_for @artwork do |a| %>
  <%= a.association :artist %>
  <%= a.association :artist, using: :name_with_title %>
  <%= a.attribute :name_with_title, in: :artist %>

  <%= a.association :tags %>
  <%= a.association :tags, to_sentence: true %>
  <%= a.association :tags do
    @artwork.tags.map(&:name).to_sentence
  end %>

  <%= a.association :fans, collection_tag: :ol do |fan| %>
    <li><%= link_to fan.name, fan %></li>
  <% end %>
<% end %>
```

The first is a `has_one` or `belongs_to` association, which works like an attribute
to ShowFor, except it will retrieve the artist association and try to find a
proper method from `ShowFor.association_methods` to be used. You can pass
the option :using to tell (and not guess) which method from the association
to use.

:tags is a `has_and_belongs_to_many` association which will return a collection.
ShowFor can handle collections by default by wrapping them in list (`<ul>` with
each item wrapped by an `<li>`). However, it also allows you to give `:to_sentence`
or `:join` it you want to render them inline.

You can also pass a block which expects an argument to association. In such cases,
a wrapper for the collection is still created and the block just iterates over the
collection objects.

Here are some other examples of the many possibilites to custom the output content:

```erb
<%= u.association :relationships, label: 'test' do  %>
  <% @user.relationships.each do |relation| %>
    <%= relation.related_user.name if relation.related_user_role == 'supervisor' %>
  <% end %>
<% end %>

<%= u.attribute :gender do  %>
  <%= content_tag :span, t("helpers.enum_select.user.gender.#{@user.gender}") %>
<% end %>
```

## Supported Ruby / Rails versions

We intend to maintain support for all Ruby / Rails versions that haven't reached end-of-life.

For more information about specific versions please check [Ruby](https://www.ruby-lang.org/en/downloads/branches/)
and [Rails](https://guides.rubyonrails.org/maintenance_policy.html) maintenance policies, and our test matrix.

## Bugs and Feedback

If you discover any bugs or want to drop a line, feel free to create an issue on GitHub.

http://github.com/heartcombo/show_for/issues

## License

MIT License.
Copyright 2020-CURRENT Rafael França, Carlos Antonio da Silva.
Copyright 2012-2019 Plataformatec.


================================================
FILE: Rakefile
================================================
# encoding: UTF-8

require 'bundler'
Bundler::GemHelper.install_tasks

require 'rake/testtask'
require 'rdoc/task'

desc 'Default: run unit tests.'
task default: :test

desc 'Test the show_form plugin.'
Rake::TestTask.new(:test) do |t|
  t.libs << 'lib'
  t.libs << 'test'
  t.pattern = 'test/**/*_test.rb'
  t.verbose = true
end

desc 'Generate documentation for the show_for plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
  rdoc.rdoc_dir = 'rdoc'
  rdoc.title    = 'ShowFor'
  rdoc.options << '--line-numbers' << '--inline-source'
  rdoc.rdoc_files.include('README.rdoc')
  rdoc.rdoc_files.include('lib/**/*.rb')
end


================================================
FILE: gemfiles/Gemfile-rails-7-0
================================================
source 'https://rubygems.org'

gemspec path: '..'

gem 'railties', '~> 7.0.0'
gem 'activemodel', '~> 7.0.0'
gem 'actionpack', '~> 7.0.0'


================================================
FILE: gemfiles/Gemfile-rails-7-1
================================================
source 'https://rubygems.org'

gemspec path: '..'

gem 'railties', '~> 7.1.0'
gem 'activemodel', '~> 7.1.0'
gem 'actionpack', '~> 7.1.0'


================================================
FILE: gemfiles/Gemfile-rails-7-2
================================================
source 'https://rubygems.org'

gemspec path: '..'

gem 'railties', '~> 7.2.0'
gem 'activemodel', '~> 7.2.0'
gem 'actionpack', '~> 7.2.0'


================================================
FILE: gemfiles/Gemfile-rails-8-0
================================================
source 'https://rubygems.org'

gemspec path: '..'

gem 'railties', '~> 8.0.0'
gem 'activemodel', '~> 8.0.0'
gem 'actionpack', '~> 8.0.0'


================================================
FILE: gemfiles/Gemfile-rails-main
================================================
source 'https://rubygems.org'

gemspec path: '..'

gem 'railties', github: 'rails/rails', branch: 'main'
gem 'activemodel', github: 'rails/rails', branch: 'main'
gem 'actionpack', github: 'rails/rails', branch: 'main'


================================================
FILE: lib/generators/show_for/USAGE
================================================
To copy a ShowFor initializer to your Rails App, with some configuration values, just do:

    rails generate show_for:install


================================================
FILE: lib/generators/show_for/install_generator.rb
================================================
module ShowFor
  module Generators
    class InstallGenerator < Rails::Generators::Base
      desc "Copy ShowFor installation files"
      class_option :template_engine, desc: 'Template engine to be invoked (erb or haml or slim).'
      source_root File.expand_path('../templates', __FILE__)

      def copy_initializers
        copy_file 'show_for.rb', 'config/initializers/show_for.rb'
      end

      def copy_locale_file
        copy_file 'en.yml', 'config/locales/show_for.en.yml'
      end

      def copy_generator_template
        engine = options[:template_engine]
        copy_file "show.html.#{engine}", "lib/templates/#{engine}/scaffold/show.html.#{engine}"
      end
    end
  end
end


================================================
FILE: lib/generators/show_for/templates/en.yml
================================================
en:
  show_for:
    blank: "Not specified"
    # If you want to use html tags with blank value use blank html translation
    # blank_html: "<span>Not specified</span>"
    "yes": "Yes"
    "no": "No"


================================================
FILE: lib/generators/show_for/templates/show.html.erb
================================================
<%%= show_for @<%= singular_name %> do |s| %>
<% attributes.each do |attribute| -%>
  <%%= s.<%= attribute.reference? ? :association : :attribute %> :<%= attribute.name %> %>
<% end -%>
<%% end %>

<%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> |
<%%= link_to 'Back', <%= plural_name %>_path %>


================================================
FILE: lib/generators/show_for/templates/show.html.haml
================================================
= show_for(@<%= singular_name %>) do |s|
<%- attributes.each do |attribute| -%>
  = s.<%= attribute.reference? ? :association : :attribute %> :<%= attribute.name %>
<% end -%>

= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>)
|
= link_to 'Back', <%= plural_name %>_path


================================================
FILE: lib/generators/show_for/templates/show.html.slim
================================================
= show_for(@<%= singular_name %>) do |s|
<%- attributes.each do |attribute| -%>
  = s.<%= attribute.reference? ? :association : :attribute %> :<%= attribute.name %>
<% end -%>

= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>)
|
= link_to 'Back', <%= plural_name %>_path


================================================
FILE: lib/generators/show_for/templates/show_for.rb
================================================
# Use this setup block to configure all options available in ShowFor.
ShowFor.setup do |config|
  # The tag which wraps show_for calls.
  # config.show_for_tag = :div

  # The DOM class set for show_for tag. Default is nil
  # config.show_for_class = :custom

  # The tag which wraps each attribute/association call. Default is :p.
  # config.wrapper_tag = :dl

  # The DOM class set for the wrapper tag. Default is :wrapper.
  # config.wrapper_class = :custom

  # The tag used to wrap each label. Default is :strong.
  # config.label_tag = :dt

  # The DOM class of each label tag. Default is :label.
  # config.label_class = :custom

  # The tag used to wrap each content (value). Default is nil.
  # config.content_tag = :dd

  # The DOM class of each content tag. Default is :content.
  # config.content_class = :custom

  # The DOM class set for blank content tags. Default is "blank".
  # config.blank_content_class = 'no_content'

  # Skip blank attributes instead of generating with a default message. Default is false.
  # config.skip_blanks = true

  # The separator between label and content. Default is "<br />".
  # config.separator = "<br />"

  # The tag used to wrap collections. Default is :ul.
  # config.collection_tag = :ul

  # The DOM class set for the collection tag. Default is :collection.
  # config.collection_class = :custom

  # The default iterator to be used when invoking a collection/association.
  # config.default_collection_proc = lambda { |value| "<li>#{ERB::Util.h(value)}</li>".html_safe }

  # The default format to be used in I18n when localizing a Date/Time.
  # config.i18n_format = :default

  # Whenever a association is given, the first method in association_methods
  # in which the association responds to is used to retrieve the association labels.
  # config.association_methods = [ :name, :title, :to_s ]

  # If you want to wrap the text inside a label (e.g. to append a semicolon),
  # specify label_proc - it will be automatically called, passing in the label text.
  # config.label_proc = lambda { |l| l + ":" }
end


================================================
FILE: lib/show_for/association.rb
================================================
module ShowFor
  module Association
    def attribute(attribute_name, options = {}, &block)
      if association_name = options.delete(:in)
        options[:using] = attribute_name
        association(association_name, options, &block)
      else
        super
      end
    end

    def association(association_name, options = {}, &block)
      apply_default_options!(association_name, options)

      # If a block with an iterator was given, no need to calculate the labels
      # since we want the collection to be yielded. Otherwise, calculate the values.
      value = if collection_block?(block)
        collection_block = block
        @object.send(association_name)
      elsif block
        block
      else
        association = @object.send(association_name)
        values = values_from_association(association, options)

        if options.delete(:to_sentence)
          values.to_sentence
        elsif joiner = options.delete(:join)
          values.join(joiner)
        else
          values
        end
      end

      wrap_label_and_content(association_name, value, options, &collection_block)
    end

  protected

    def values_from_association(association, options) #:nodoc:
      sample = association.respond_to?(:to_ary) ? association.first : association
      method = options.delete(:using) || ShowFor.association_methods.find { |m| sample.respond_to?(m) }

      if method
        association.respond_to?(:to_ary) ? association.map(&method) : association.try(method)
      end
    end
  end
end


================================================
FILE: lib/show_for/attribute.rb
================================================
module ShowFor
  module Attribute
    def attribute(attribute_name, options = {}, &block)
      apply_default_options!(attribute_name, options)
      block = block_from_value_option(attribute_name, options) unless block
      collection_block, block = block, nil if collection_block?(block)

      value = attribute_value(attribute_name, &block)

      wrap_label_and_content(attribute_name, value, options, &collection_block)
    end

    def value(attribute_name, options = {}, &block)
      apply_default_options!(attribute_name, options)
      collection_block, block = block, nil if collection_block?(block)

      value = attribute_value(attribute_name, &block)

      wrap_content(attribute_name, value, options, &collection_block)
    end

    def attributes(*attribute_names)
      attribute_names.map do |attribute_name|
        attribute(attribute_name)
      end.join.html_safe
    end

  private

    def attribute_value(attribute_name, &block)
      if block
        block
      elsif @object.respond_to?(:"human_#{attribute_name}")
        @object.send :"human_#{attribute_name}"
      else
        @object.send(attribute_name)
      end
    end

    def block_from_value_option(attribute_name, options)
      if !options.has_key?(:value)
        nil
      elsif options[:value].is_a?(Symbol)
        block_from_symbol(attribute_name, options)
      else
        lambda { options[:value].to_s }
      end
    end

    def block_from_symbol(attribute_name, options)
      attribute = @object.send(attribute_name)
      case attribute
      when Array, Hash
        lambda { |element| element.send(options[:value]) }
      else
        lambda { attribute.send(options[:value]) }
      end
    end
  end
end


================================================
FILE: lib/show_for/builder.rb
================================================
require 'show_for/attribute'
require 'show_for/association'
require 'show_for/content'
require 'show_for/label'

module ShowFor
  class Builder
    include ShowFor::Attribute
    include ShowFor::Association
    include ShowFor::Content
    include ShowFor::Label

    attr_reader :object, :template

    def initialize(object, template)
      @object, @template = object, template
    end

  protected

    def object_name #:nodoc:
      @object_name ||= begin
                         model_name = @object.class.model_name

                         # TODO Remove this check when we drop support to Rails 3.0
                         if model_name.respond_to?(:param_key)
                           model_name.param_key
                         else
                           model_name.singular
                         end
                       end
    end

    def wrap_label_and_content(name, value, options, &block) #:nodoc:
      return if skip_blanks?(value)
      label = label(name, options, false)
      if label.present? && separator = options.fetch(:separator) { ShowFor.separator }
        label += separator.html_safe
      end
      wrap_with(:wrapper, label + content(value, options, false, &block), apply_wrapper_options!(:wrapper, options, value))
    end

    def wrap_content(name, value, options, &block) #:nodoc:
      wrap_with(:wrapper, content(value, options, false, &block), apply_wrapper_options!(:wrapper, options, value))
    end

    # Set "#{object_name}_#{attribute_name}" as in the wrapper tag.
    def apply_default_options!(name, options) #:nodoc:
      html_class = "#{object_name}_#{name}".gsub(/\W/, '')
      wrapper_html = options[:wrapper_html] ||= {}
      wrapper_html[:class] = "#{html_class} #{wrapper_html[:class]}".rstrip
    end

    def apply_wrapper_options!(type, options, value)
      options[:"#{type}_html"] ||= {}
      options[:"#{type}_html"][:class] = [options[:"#{type}_html"][:class], ShowFor.blank_content_class].join(' ') if is_empty?(value)
      options
    end

    # Gets the default tag set in ShowFor module and apply (if defined)
    # around the given content. It also check for html_options in @options
    # hash related to the current type.
    def wrap_with(type, content, options) #:nodoc:
      return if skip_blanks?(content)
      tag = options.delete(:"#{type}_tag") || ShowFor.send(:"#{type}_tag")

      if tag
        type_class = ShowFor.send :"#{type}_class"
        html_options = options.delete(:"#{type}_html") || {}
        html_options[:class] = [type_class, html_options[:class]].compact.presence
        @template.content_tag(tag, content, html_options)
      else
        content
      end
    end

    # Returns true if the block is supposed to iterate through a collection,
    # i.e. it has arity equals to one.
    def collection_block?(block) #:nodoc:
      block && block.arity == 1
    end

    # Verifies whether the value is blank and its configured to skip blank values.
    def skip_blanks?(value) #:nodoc:
      ShowFor.skip_blanks && value.blank? && value != false
    end

    def is_empty?(value) #:nodoc:
      value = @template.capture(&value) if value.is_a?(Proc)
      value.blank? && value != false
    end
  end
end



================================================
FILE: lib/show_for/content.rb
================================================
module ShowFor
  module Content
    def content(value, options = {}, apply_options = true, &block)
      # cache value for apply_wrapper_options!
      sample_value = value

      # We need to convert value to_a because when dealing with ActiveRecord
      # Array proxies, the follow statement Array# === value return false
      value = value.to_a if value.respond_to?(:to_ary)

      content = case value
        when Date, Time, DateTime
          I18n.l value, format: options.delete(:format) || ShowFor.i18n_format
        when TrueClass
          I18n.t :"show_for.yes", default: "Yes"
        when FalseClass
          I18n.t :"show_for.no", default: "No"
        when Array, Hash
          collection_handler(value, options, &block) unless value.empty?
        when Proc
          @template.capture(&value)
        when Numeric
          value.to_s
        else
          unless value.blank?
            block ? template.capture(value, &block) : value
          end
      end

      if content.blank? && !ShowFor.skip_blanks
        content = blank_value(options)
      end

      options[:content_html] = options.except(:content_tag) if apply_options
      wrap_with(:content, content, apply_wrapper_options!(:content, options, sample_value))
    end

  protected

    def collection_handler(value, options, &block) #:nodoc:
      iterator = collection_block?(block) ? block : ShowFor.default_collection_proc

      response = value.map do |item|
        template.capture(item, &iterator)
      end.join.html_safe

      wrap_with(:collection, response, options)
    end

    def translate_blank_html
      template.t(:'show_for.blank_html', default: translate_blank_text)
    end

    def translate_blank_text
      I18n.t(:'show_for.blank', default: "Not specified")
    end

    def blank_value(options)
      options.delete(:if_blank) || translate_blank_html
    end
  end
end


================================================
FILE: lib/show_for/helper.rb
================================================
module ShowFor
  module Helper
    # Creates a div around the object and yields a builder.
    #
    # Example:
    #
    #   show_for @user do |f|
    #     f.attribute :name
    #     f.attribute :email
    #   end
    #
    def show_for(object, html_options = {}, &block)
      html_options = html_options.dup

      tag = html_options.delete(:show_for_tag) || ShowFor.show_for_tag

      html_options[:id]  ||= dom_id(object)
      html_options[:class] = show_for_html_class(object, html_options)

      builder = html_options.delete(:builder) || ShowFor::Builder
      content = capture(builder.new(object, self), &block)

      content_tag(tag, content, html_options)
    end

    private

    def show_for_html_class(object, html_options)
      "show_for #{dom_class(object)} #{html_options[:class]} #{ShowFor.show_for_class}".squeeze(" ").rstrip
    end
  end
end

ActionView::Base.send :include, ShowFor::Helper


================================================
FILE: lib/show_for/label.rb
================================================
module ShowFor
  module Label
    def label(text_or_attribute, options = {}, apply_options = true)
      label = if text_or_attribute.is_a?(String)
        text_or_attribute
      elsif options.key?(:label)
        options.delete(:label)
      else
        human_attribute_name(text_or_attribute)
      end

      return ''.html_safe if label == false
      options[:label_html] = options.dup if apply_options

      label = ShowFor.label_proc.call(label) if options.fetch(:wrap_label, true) && ShowFor.label_proc
      wrap_with :label, label, options
    end

  protected

    def human_attribute_name(attribute) #:nodoc:
      @object.class.human_attribute_name(attribute.to_s)
    end
  end
end


================================================
FILE: lib/show_for/version.rb
================================================
module ShowFor
  VERSION = "0.9.0".freeze
end


================================================
FILE: lib/show_for.rb
================================================
require 'action_view'
require 'show_for/helper'

module ShowFor
  autoload :Builder, 'show_for/builder'

  mattr_accessor :show_for_tag
  @@show_for_tag = :div

  mattr_accessor :show_for_class
  @@show_for_class = nil

  mattr_accessor :label_tag
  @@label_tag = :strong

  mattr_accessor :label_class
  @@label_class = :label

  mattr_accessor :separator
  @@separator = "<br />"

  mattr_accessor :content_tag
  @@content_tag = nil

  mattr_accessor :content_class
  @@content_class = :content

  mattr_accessor :blank_content_class
  @@blank_content_class = "blank"

  mattr_accessor :skip_blanks
  @@skip_blanks = false

  mattr_accessor :wrapper_tag
  @@wrapper_tag = :div

  mattr_accessor :wrapper_class
  @@wrapper_class = :wrapper

  mattr_accessor :collection_tag
  @@collection_tag = :ul

  mattr_accessor :collection_class
  @@collection_class = :collection

  mattr_accessor :default_collection_proc
  @@default_collection_proc = lambda { |value| "<li>#{ERB::Util.html_escape(value)}</li>".html_safe }

  mattr_accessor :i18n_format
  @@i18n_format = :default

  mattr_accessor :association_methods
  @@association_methods = [ :name, :title, :to_s ]

  mattr_accessor :label_proc
  @@label_proc = nil

  # Yield self for configuration block:
  #
  #   ShowFor.setup do |config|
  #     config.i18n_format = :long
  #   end
  #
  def self.setup
    yield self
  end
end


================================================
FILE: show_for.gemspec
================================================
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "show_for/version"

Gem::Specification.new do |s|
  s.name        = "show_for"
  s.version     = ShowFor::VERSION.dup
  s.platform    = Gem::Platform::RUBY
  s.summary     = "Wrap your objects with a helper to easily show them"
  s.email       = "heartcombo.oss@gmail.com"
  s.homepage    = "https://github.com/heartcombo/show_for"
  s.description = "Wrap your objects with a helper to easily show them"
  s.authors     = ["José Valim"]
  s.licenses    = ["MIT"]
  s.metadata    = {
    "homepage_uri"    => "https://github.com/heartcombo/show_for",
    "changelog_uri"   => "https://github.com/heartcombo/show_for/blob/main/CHANGELOG.md",
    "source_code_uri" => "https://github.com/heartcombo/show_for",
    "bug_tracker_uri" => "https://github.com/heartcombo/show_for/issues",
  }

  s.files         = Dir["CHANGELOG.md", "MIT-LICENSE", "README.md", "lib/**/*"]
  s.require_paths = ["lib"]

  s.required_ruby_version = '>= 2.7.0'

  s.add_dependency('activemodel', '>= 7.0')
  s.add_dependency('actionpack', '>= 7.0')

  s.add_development_dependency('rake')
  s.add_development_dependency('rdoc')
  s.add_development_dependency('ostruct')
end


================================================
FILE: test/association_test.rb
================================================
require 'test_helper'

class AssociationTest < ActionView::TestCase
  test "show_for works with belongs_to/has_one associations" do
    with_association_for @user, :company
    assert_select "div.show_for div.wrapper", /Plataformatec/
  end

  test "show_for accepts :using as option to tell how to retrieve association value" do
    with_association_for @user, :company, using: :alternate_name
    assert_select "div.show_for div.wrapper", /Alternate Plataformatec/
  end

  test "show_for accepts :in to tell to retrieve an attribute from association" do
    with_attribute_for @user, :alternate_name, in: :company
    assert_select "div.show_for div.wrapper", /Alternate Plataformatec/
  end

  test "show_for forwards all options send with :in to association" do
    with_attribute_for @user, :alternate_name, in: :tags, to_sentence: true
    assert_no_select "div.show_for div.wrapper ul.collection"
    assert_select "div.show_for div.wrapper", /Alternate Tag 1, Alternate Tag 2, and Alternate Tag 3/
  end

  test "show_for works with has_many/has_and_belongs_to_many associations" do
    with_association_for @user, :tags
    assert_select "div.show_for div.wrapper ul.collection"
    assert_select "div.show_for div.wrapper ul.collection li", "Tag 1"
    assert_select "div.show_for div.wrapper ul.collection li", "Tag 2"
    assert_select "div.show_for div.wrapper ul.collection li", "Tag 3"
  end

  test "show_for works with has_many/has_and_belongs_to_many blank associations" do
    def @user.tags
      []
    end

    swap ShowFor, association_methods: [:name] do
      with_association_for @user, :tags
      assert_no_select "div.show_for div.wrapper ul.collection"
      assert_no_select "div.show_for div.wrapper", /Enumerator/
    end
  end

  test "show_for accepts a block with has_many/has_and_belongs_to_many blank associations" do
    def @user.tags
      []
    end

    swap ShowFor, association_methods: [:name] do
      with_association_for @user, :tags do |tag|
        tag.name
      end
      assert_no_select "div.show_for div.wrapper ul.collection"
      assert_no_select "div.show_for div.wrapper", /Enumerator/
    end
  end

  test "show_for uses :if_blank when has_many/has_and_belongs_to_many association is blank" do
    def @user.tags
      []
    end

    with_association_for @user, :tags, if_blank: 'No tags' do |tag|
      tag.name
    end
    assert_select "div.show_for div.wrapper.blank", /No tags/
    assert_no_select "div.show_for div.wrapper ul.collection"
    assert_no_select "div.show_for div.wrapper", /Enumerator/
  end

  test "show_for uses :if_blank if given a block when has_many/has_and_belongs_to_many association is blank" do
    def @user.tags
      []
    end

    with_association_for @user, :tags, if_blank: 'No tags'
    assert_select "div.show_for div.wrapper.blank", /No tags/
    assert_no_select "div.show_for div.wrapper ul.collection"
    assert_no_select "div.show_for div.wrapper", /Enumerator/
  end

  test "show_for accepts a block with an argument in belongs_to associations" do
    with_association_for @user, :company do |company|
      company.name.upcase
    end

    assert_select "div.show_for div.wrapper", /PLATAFORMATEC/
  end

  test "show_for accepts :using as option to tell how to retrieve association values" do
    with_association_for @user, :tags, using: :alternate_name
    assert_select "div.show_for div.wrapper ul.collection"
    assert_select "div.show_for div.wrapper ul.collection li", "Alternate Tag 1"
    assert_select "div.show_for div.wrapper ul.collection li", "Alternate Tag 2"
    assert_select "div.show_for div.wrapper ul.collection li", "Alternate Tag 3"
  end

  test "show_for accepts :to_sentence as option in collection associations" do
    with_association_for @user, :tags, to_sentence: true
    assert_no_select "div.show_for div.wrapper ul.collection"
    assert_select "div.show_for div.wrapper", /Tag 1, Tag 2, and Tag 3/
  end

  test "show_for accepts :join as option in collection associations" do
    with_association_for @user, :tags, join: ", "
    assert_no_select "div.show_for div.wrapper ul.collection"
    assert_select "div.show_for div.wrapper", /Tag 1, Tag 2, Tag 3/
  end

  test "show_for accepts a block without argument in collection associations" do
    with_association_for @user, :tags do
      @user.tags.map(&:name).to_sentence
    end
    assert_no_select "div.show_for div.wrapper ul.collection"
    assert_select "div.show_for div.wrapper", /Tag 1, Tag 2, and Tag 3/
  end

  test "show_for accepts a block with argument in collection associations" do
    with_association_for @user, :tags, collection_tag: :p do |tag|
      assert_kind_of Tag, tag
      content_tag(:span, tag.name)
    end
    assert_no_select "div.show_for div.wrapper ul.collection"
    assert_select "div.show_for div.wrapper p.collection"
    assert_select "div.show_for div.wrapper p.collection span", "Tag 1"
    assert_select "div.show_for div.wrapper p.collection span", "Tag 2"
    assert_select "div.show_for div.wrapper p.collection span", "Tag 3"
  end

  test "show_for does not display empty has_many/has_and_belongs_to_many association if skip_blanks option is passed" do
    def @user.tags
      []
    end

    swap ShowFor, skip_blanks: true do
      with_association_for @user, :tags
      assert_no_select "div.show_for div.wrapper"
    end
  end

  test "show_for does not display empty belongs_to/has_one association if skip_blanks option is passed" do
    def @user.company
      nil
    end

    swap ShowFor, skip_blanks: true do
      with_association_for @user, :company
      assert_no_select "div.show_for div.wrapper"
    end
  end
end


================================================
FILE: test/attribute_test.rb
================================================
require 'test_helper'

class AttributeTest < ActionView::TestCase
  # COLLECTIONS
  test "show_for accepts an attribute as a collection" do
    with_attribute_for @user, :scopes
    assert_select "div.show_for div.wrapper ul.collection"
    assert_select "div.show_for div.wrapper ul.collection li", count: 3
  end

  test "show_for accepts an attribute as a collection with a block to iterate the collection" do
    with_attribute_for @user, :scopes do |scope|
      content_tag :span, scope
    end
    assert_select "div.show_for div.wrapper ul.collection"
    assert_select "div.show_for div.wrapper ul.collection span", count: 3
  end

  test "show_for treats symbol for :value as method on each element of collection" do
    with_attribute_for @user, :scopes, value: :upcase
    @user.scopes.each do |scope|
      assert_select "div.show_for div.wrapper ul.collection", /#{scope.upcase}/
    end
  end

  test "show_for allows collection tag to be configured globally" do
    swap ShowFor, collection_tag: :ol, collection_class: "my_collection" do
      with_attribute_for @user, :scopes
      assert_select "div.show_for div.wrapper ol.my_collection"
    end
  end

  test "show_for allows collection class to be disabled globally" do
    swap ShowFor, collection_tag: :ol, collection_class: nil do
      with_attribute_for @user, :scopes
      assert_select "div.show_for div.wrapper ol"
      assert_no_select "ol[class]"
    end
  end

  test "show_for allows collection tag to be changed by attribute" do
    with_attribute_for @user, :scopes, collection_tag: :ol
    assert_select "div.show_for div.wrapper ol.collection"
  end

  test "show_for allows collection tag html to be configured by attribute" do
    with_attribute_for @user, :scopes, collection_html: { id: "thecollection", class: "special" }
    assert_select "div.show_for div.wrapper ul#thecollection.special.collection"
  end

  # CONTENT
  test "show_for allows content tag to be configured globally" do
    swap ShowFor, content_tag: :span, content_class: :my_content do
      with_attribute_for @user, :name
      assert_select "div.show_for div.wrapper span.my_content"
    end
  end

  test "show_for allows content class to be disabled globally" do
    swap ShowFor, content_tag: :span, content_class: nil do
      with_attribute_for @user, :name
      assert_select "div.show_for div.wrapper span"
      assert_no_select "span[class]"
    end
  end

  test "show_for allows content tag to be changed by attribute" do
    with_attribute_for @user, :name, content_tag: :span
    assert_select "div.show_for div.wrapper span.content"
  end

  test "show_for allows content tag html to be configured by attribute" do
    with_attribute_for @user, :name, content_tag: :span, content_html: { id: "thecontent", class: "special" }
    assert_select "div.show_for div.wrapper span#thecontent.special.content"
  end

  test "show_for accepts an attribute as string" do
    with_attribute_for @user, :name
    assert_select "div.show_for div.wrapper", /ShowFor/
  end

  test "show_for accepts an attribute as time" do
    with_attribute_for @user, :created_at
    assert_select "div.show_for div.wrapper", /#{Regexp.escape(I18n.l(@user.created_at))}/
  end

  test "show_for accepts an attribute as date" do
    with_attribute_for @user, :updated_at
    assert_select "div.show_for div.wrapper", /#{Regexp.escape(I18n.l(@user.updated_at))}/
  end

  test "show_for accepts an attribute as time with format options" do
    with_attribute_for @user, :created_at, format: :long
    assert_select "div.show_for div.wrapper", /#{Regexp.escape(I18n.l(@user.created_at, format: :long))}/
  end

  test "show_for accepts an attribute as true" do
    with_attribute_for @user, :active
    assert_select "div.show_for div.wrapper", /Yes/
  end

  test "show_for accepts an attribute as true which can be localized" do
    store_translations(:en, show_for: { yes: "Hell yeah!" }) do
      with_attribute_for @user, :active
      assert_select "div.show_for div.wrapper", /Hell yeah!/
    end
  end

  test "show_for accepts an attribute as false" do
    with_attribute_for @user, :invalid
    assert_select "div.show_for div.wrapper", /No/
  end

  test "show_for accepts an attribute as false which can be localized" do
    store_translations(:en, show_for: { no: "Hell no!" }) do
      with_attribute_for @user, :invalid
      assert_select "div.show_for div.wrapper", /Hell no!/
    end
  end

  test "show_for accepts nil and or blank attributes" do
    with_attribute_for @user, :description
    assert_select "div.show_for div.wrapper", /Not specified/
  end

  test "show_for accepts not spcified message can be localized" do
    store_translations(:en, show_for: { blank: "OMG! It's blank!" }) do
      with_attribute_for @user, :description
      assert_select "div.show_for div.wrapper", /OMG! It's blank!/
    end
  end

  test "show_for accepts not spcified message can be localized with html" do
    store_translations(:en, show_for: { blank_html: "<span>OMG! It's blank!</span>" }) do
      with_attribute_for @user, :description
      assert_select "div.show_for div.wrapper span", "OMG! It's blank!"
    end
  end

  test "show_for uses :if_blank if attribute is blank" do
    with_attribute_for @user, :description, if_blank: "No description provided"
    assert_select "div.show_for div.wrapper", /No description provided/
  end

  test "show_for accepts a block to supply the content" do
    with_attribute_for @user, :description do
      "This description is not blank"
    end
    assert_select "div.show_for div.wrapper", /This description/
  end

  test "show_for uses :if_blank if the block content is blank" do
    with_attribute_for @user, :description, if_blank: "No description provided" do
      ""
    end
    assert_select "div.show_for div.wrapper", /No description provided/
  end

  test "show_for#content given a block should be wrapped in the result" do
    with_attribute_for @user, :name do |name|
      "<div class='block'>#{name}</div>".html_safe
    end
    assert_select "div.wrapper.user_name div.block", /ShowFor/
  end

  test "show_for escapes content by default" do
    @user.name = "<b>hack you!</b>"
    with_attribute_for @user, :name
    assert_no_select "div.show_for div.wrapper b"
    assert_select "div.show_for div.wrapper", "Super User Name!<b>hack you!</b>"
  end

  test "show_for works with html_safe marked strings" do
    @user.name = "<b>hack you!</b>".html_safe
    with_attribute_for @user, :name
    assert_select "div.show_for div.wrapper b", "hack you!"
  end

  test "show_for uses :value if supplied" do
    with_attribute_for @user, :name, value: "Calculated Value"
    assert_select "div.show_for div.wrapper", /Calculated Value/
  end

  test "show_for uses :value and casts to string if supplied" do
    with_attribute_for @user, :name, value: 123
    assert_select "div.show_for div.wrapper", /123/
  end

  test "show_for ignores attribute if :value supplied but with nil value" do
    with_attribute_for @user, :name, value: nil
    assert_select "div.show_for div.wrapper", /Not specified/
  end

  test "show_for ignores :value if a block is supplied" do
    with_attribute_for @user, :name, value: "Calculated Value" do
      @user.name.upcase
    end
    assert_select "div.show_for div.wrapper", /#{@user.name.upcase}/
  end

  test "show_for treats symbol for :value as method on attribute" do
    with_attribute_for @user, :name, value: :upcase
    assert_select "div.show_for div.wrapper", /#{@user.name.upcase}/
  end

  test "show_for does not display blank attribute if skip_blanks option is passed" do
    swap ShowFor, skip_blanks: true do
      with_attribute_for @user, :description
      assert_no_select "div.show_for div.wrapper"
    end
  end

  test "show_for display false attribute if skip_blanks option is passed" do
    swap ShowFor, skip_blanks: true do
      with_attribute_for @user, :invalid
      assert_select "div.show_for div.wrapper", /No/
    end
  end

  # ATTRIBUTES
  test "show_for attributes wraps each attribute with a label and content" do
    with_attributes_for @user, :name, :email
    assert_select "div.show_for div.user_name.wrapper", /ShowFor/
    assert_select "div.user_name strong.label", "Super User Name!"
    assert_select "div.show_for div.user_email.wrapper", /Not specified/
    assert_select "div.user_email strong.label", "Email"
  end

  test "show_for should wrap blank attributes with no_attribute" do
    swap ShowFor, blank_content_class: 'no_attribute' do
      with_attributes_for @user, :name, :birthday, :karma
      assert_select ".wrapper.user_birthday.no_attribute"
      assert_select ".wrapper.user_karma.no_attribute"
      assert_select ".wrapper.user_name.no_attribute", false
    end
  end

end


================================================
FILE: test/builder_test.rb
================================================
require 'test_helper'

class BuilderTest < ActionView::TestCase
  # WRAPPER
  test "show_for allows wrapper to be configured globally" do
    swap ShowFor, wrapper_tag: "li", wrapper_class: "my_wrapper" do
      with_attribute_for @user, :name
      assert_select "div.show_for li.user_name.my_wrapper"
      assert_select "div.show_for li.my_wrapper strong.label"
      assert_select "div.show_for li.my_wrapper"
    end
  end

  test "show_for allows wrapper class to be disabled globally" do
    swap ShowFor, wrapper_tag: "li", wrapper_class: nil do
      with_attribute_for @user, :name
      assert_select "div.show_for li[class='user_name']"
    end
  end

  test "show_for attribute wraps each attribute with a label and content" do
    with_attribute_for @user, :name
    assert_select "div.show_for div.user_name.wrapper"
    assert_select "div.show_for div.wrapper strong.label"
    assert_select "div.show_for div.wrapper"
  end

  test "show_for properly deals with namespaced models" do
    @user = Namespaced::User.new(id: 1, name: "ShowFor")

    with_attribute_for @user, :name
    assert_select "div.show_for div.namespaced_user_name.wrapper"
    assert_select "div.show_for div.wrapper strong.label"
    assert_select "div.show_for div.wrapper"
  end

  test "show_for allows wrapper tag to be changed by attribute" do
    with_attribute_for @user, :name, wrapper_tag: :span
    assert_select "div.show_for span.user_name.wrapper"
  end

  test "show_for allows wrapper html to be configured by attribute" do
    with_attribute_for @user, :name, wrapper_html: { id: "thewrapper", class: "special" }
    assert_select "div.show_for div#thewrapper.user_name.wrapper.special"
  end

  # SEPARATOR
  test "show_for allows separator to be configured globally" do
    swap ShowFor, separator: '<span class="separator"></span>' do
      with_attribute_for @user, :name
      assert_select "div.show_for div.user_name span.separator"
      assert_select "div.show_for div.wrapper span.separator"
      assert_no_select "div.show_for br"
    end
  end

  test "show_for allows separator to be changed by attribute"do
    with_attribute_for @user, :name, separator: '<span class="separator"></span>'
    assert_select "div.show_for div.wrapper span.separator"
    assert_no_select "div.show_for br"
  end

  test "show_for allows disabling separator by attribute" do
    with_attribute_for @user, :name, separator: false
    assert_no_select "div.show_for div.wrapper span.separator"
    assert_no_select "div.show_for div.wrapper br"
    assert_no_select "div.show_for div.wrapper", /false/
  end

  test "show_for uses a separator if requested" do
    with_attribute_for @user, :name
    assert_select "div.show_for div.wrapper br"
  end

  test "show_for does not blow if a separator is not set" do
    swap ShowFor, separator: nil do
      with_attribute_for @user, :name
      assert_select "div.show_for div.wrapper"
    end
  end
end


================================================
FILE: test/content_test.rb
================================================
require 'test_helper'

class ContentTest < ActionView::TestCase
  test "show_for#content accepts any object" do
    with_content_for @user, "Special content"
    assert_select "div.show_for", "Special content"
  end

  test "show_for#content accepts :if_blank as option" do
     with_content_for @user, "", if_blank: "Got blank"
     assert_select "div.show_for", "Got blank"
   end

  test "show_for#content accepts html options" do
    with_content_for @user, "Special content", content_tag: :b, id: "thecontent", class: "special"
    assert_select "div.show_for b#thecontent.special.content", "Special content"
    assert_no_select "div.show_for b[content_tag]"
  end

  test "show_for#content with blank value has a 'no value'-class" do
    swap ShowFor, blank_content_class: "nothing" do
      with_content_for @user, nil, content_tag: :b
      assert_select "div.show_for b.nothing"
    end
  end

  test "show_for#content with blank value does not display content if skip_blanks option is passed" do
    swap ShowFor, skip_blanks: true do
      with_content_for @user, nil, content_tag: :b
      assert_no_select "div.show_for b"
    end
  end
end


================================================
FILE: test/generators/show_for_generator_test.rb
================================================
require 'test_helper'

class ShowForGeneratorTest < Rails::Generators::TestCase
  tests ShowFor::Generators::InstallGenerator
  destination File.expand_path('../../tmp', __FILE__)
  setup :prepare_destination
  teardown { rm_rf(destination_root) }

  test 'generates example locale file' do
    run_generator
    assert_file 'config/locales/show_for.en.yml'
  end

  test 'generates the show_for initializer' do
    run_generator
    assert_file 'config/initializers/show_for.rb',
      /config.show_for_tag = :div/
  end

  %W(erb haml slim).each do |engine|
    test "generates the scaffold template when using #{engine}" do
      run_generator ['-e', engine]
      assert_file "lib/templates/#{engine}/scaffold/show.html.#{engine}"
    end
  end
end


================================================
FILE: test/helper_test.rb
================================================
require "test_helper"

class CustomBuilder < ShowFor::Builder
end

class HelperTest < ActionView::TestCase
  test "show for yields an instance of ShowFor::Builder" do
    show_for(@user) do |f|
      assert f.instance_of?(ShowFor::Builder)
    end
  end

  test "show for yields an instance of builder class specified by builder option" do
    show_for(@user, builder: CustomBuilder) do |f|
      assert f.instance_of?(CustomBuilder)
    end
  end

  test "show for should add default class to form" do
    concat(show_for(@user) do |f| end)
    assert_select "div.show_for"
  end

  test "show for should add object class name as css class to form" do
    concat(show_for(@user) do |f| end)
    assert_select "div.show_for.user"
  end

  test "show for should pass options" do
    concat(show_for(@user, id: "my_div", class: "common") do |f| end)
    assert_select "div#my_div.show_for.user.common"
  end

  test "show for tag should be configurable" do
    swap ShowFor, show_for_tag: :p do
      concat(show_for(@user) do |f| end)
      assert_select "p.show_for"
    end
  end

  test "show for class should be configurable" do
    swap ShowFor, show_for_class: :awesome do
      concat(show_for(@user) do |f| end)
      assert_select "div.show_for.user.awesome"
    end
  end
  
  test "show for options hash should not be modified" do
    html_options = { show_for_tag: :li }
    concat(show_for(@user, html_options) do |f| end)
    assert_equal({ show_for_tag: :li }, html_options)
  end
  
end


================================================
FILE: test/label_test.rb
================================================
require 'test_helper'

class LabelTest < ActionView::TestCase
  test "show_for shows a label using the humanized attribute name from model" do
    with_attribute_for @user, :name
    assert_select "div.show_for div.wrapper strong.label", "Super User Name!"
  end

  test "show_for skips label if requested" do
    with_attribute_for @user, :name, label: false
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
  end

  test "show_for uses custom content_tag and skips label if requested" do
    with_attribute_for @user, :name, label: false, content_tag: :h2
    assert_select "div.show_for div.wrapper h2.content", "ShowFor"
  end

  test "show_for allows label to be configured globally" do
    swap ShowFor, label_tag: :span, label_class: "my_label" do
      with_attribute_for @user, :name
      assert_select "div.show_for div.wrapper span.my_label"
    end
  end

  test "show_for allows label class to be disabled globally" do
    swap ShowFor, label_tag: :span, label_class: nil do
      with_attribute_for @user, :name
      assert_select "div.show_for div.wrapper span"
      assert_no_select "span[class]"
    end
  end

  test "show_for allows label to be changed by attribute" do
    with_attribute_for @user, :name, label_tag: :span
    assert_select "div.show_for div.wrapper span.label"
  end

  test "show_for allows label html to be configured by attribute" do
    with_attribute_for @user, :name, label_html: { id: "thelabel", class: "special" }
    assert_select "div.show_for div.wrapper strong#thelabel.special.label"
  end

  test "show_for allows label to be set without lookup" do
    with_attribute_for @user, :name, label: "Special Label"
    assert_select "div.show_for div.wrapper strong.label", "Special Label"
  end

  test "show_for#label accepts the text" do
    with_label_for @user, "Special Label"
    assert_select "div.show_for strong.label", "Special Label"
  end

  test "show_for#label accepts an attribute name" do
    with_label_for @user, :name
    assert_select "div.show_for strong.label", "Super User Name!"
  end

  test "show_for#label accepts html options" do
    with_label_for @user, :name, id: "thelabel", class: "special"
    assert_select "div.show_for strong#thelabel.special.label"
  end

  test "should let you override the label wrapper" do
    swap ShowFor, label_proc: proc { |l| l + ":" } do
      with_label_for @user, "Special Label"
      assert_select "div.show_for strong.label", "Special Label:"
    end
  end

  test "should you skip wrapping the label on a per item basis" do
    swap ShowFor, label_proc: proc { |l| l + ":" } do
      with_label_for @user, "Special Label", wrap_label: false
      assert_select "div.show_for strong.label", "Special Label"
    end
  end
end


================================================
FILE: test/support/misc_helpers.rb
================================================
module MiscHelpers
  def store_translations(locale, translations, &block)
    begin
      I18n.backend.store_translations locale, translations
      yield
    ensure
      I18n.reload!
    end
  end

  def assert_no_select(selector, value = nil)
    assert_select(selector, text: value, count: 0)
  end

  def swap(object, new_values)
    old_values = {}
    new_values.each do |key, value|
      old_values[key] = object.send key
      object.send :"#{key}=", value
    end
    yield
  ensure
    old_values.each do |key, value|
      object.send :"#{key}=", value
    end
  end

  def with_attribute_for(object, attribute, options = {}, &block)
    concat(show_for(object) do |o|
      concat o.attribute(attribute, options, &block)
    end)
  end

  def with_value_for(object, attribute, options = {}, &block)
    concat(show_for(object) do |o|
      concat o.value(attribute, options, &block)
    end)
  end

  def with_association_for(object, association, options = {}, &block)
    concat(show_for(object) do |o|
      concat o.association(association, options, &block)
    end)
  end

  def with_label_for(object, attribute, options = {})
    concat(show_for(object) do |o|
      concat o.label(attribute, options)
    end)
  end

  def with_content_for(object, value, options = {})
    concat(show_for(object) do |o|
      concat o.content(value, options)
    end)
  end

  def with_attributes_for(object, *attributes)
    concat(show_for(object) do |o|
      concat o.attributes(*attributes)
    end)
  end
end


================================================
FILE: test/support/models.rb
================================================
require 'ostruct'

Company = Struct.new(:id, :name) do
  extend ActiveModel::Naming

  def alternate_name
    "Alternate #{self.name}"
  end
end


Tag = Struct.new(:id, :name) do
  extend ActiveModel::Naming

  def self.all(options = {})
    (1..3).map{ |i| Tag.new(i, "Tag #{i}") }
  end

  def alternate_name
    "Alternate #{self.name}"
  end
end

class User < OpenStruct
  extend ActiveModel::Naming

  # Get rid of deprecation warnings
  undef_method :id if respond_to?(:id)

  def tags
    Tag.all
  end

  def company
    Company.new(1, "Plataformatec")
  end

  def self.human_attribute_name(attribute)
    case attribute
      when 'name'
        'Super User Name!'
      when 'company'
        'Company Human Name!'
      else
        attribute.humanize
    end
  end

  def self.human_name
    "User"
  end
end

module Namespaced
  class User < ::User
  end
end


================================================
FILE: test/test_helper.rb
================================================
require 'bundler/setup'

require 'minitest/autorun'

require 'active_model'
require 'action_controller'
require 'action_view'
require 'action_view/template'
require 'action_view/test_case'

require "rails/generators/test_case"
require 'generators/show_for/install_generator'

$:.unshift File.expand_path("../../lib", __FILE__)
require 'show_for'

Dir["#{File.dirname(__FILE__)}/support/*.rb"].each { |f| require f }
I18n.enforce_available_locales = true
I18n.default_locale = :en

ActiveSupport::TestCase.test_order = :random if ActiveSupport::TestCase.respond_to?(:test_order=)

class ActionView::TestCase
  include MiscHelpers
  include ShowFor::Helper

  setup :setup_new_user

  def setup_new_user(options = {})
    @user = User.new({
      id: 1,
      name: 'ShowFor',
      description: '',
      active: true,
      invalid: false,
      scopes: ["admin", "manager", "visitor"],
      birthday: nil,
      karma: Proc.new { nil },
      created_at: Time.now,
      updated_at: Date.today
    }.merge(options))
  end
end


================================================
FILE: test/value_test.rb
================================================
require 'test_helper'

class ValueTest < ActionView::TestCase
  test "show_for allows content tag to be configured globally, without label and separator" do
    swap ShowFor, content_tag: :span do
      with_value_for @user, :name
      assert_no_select "div.show_for div.wrapper strong.label"
      assert_no_select "div.show_for div.wrapper br"
      assert_select "div.show_for div.wrapper span.content"
    end
  end

  test "show_for allows content with tag to be changed by attribute, without label and separator" do
    with_value_for @user, :name, content_tag: :span
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
    assert_select "div.show_for div.wrapper span.content"
  end

  test "show_for allows content tag html to be configured by attribute, without label and separator" do
    with_value_for @user, :name, content_tag: :span, content_html: { id: "thecontent", class: "special" }
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
    assert_select "div.show_for div.wrapper span#thecontent.special.content"
  end

  test "show_for accepts an attribute as string, without label and separator" do
    with_value_for @user, :name
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
    assert_select "div.show_for div.wrapper", /ShowFor/
  end

  test "show_for accepts an attribute as time, without label and separator" do
    with_value_for @user, :created_at
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
    assert_select "div.show_for div.wrapper", /#{Regexp.escape(I18n.l(@user.created_at))}/
  end

  test "show_for accepts an attribute as date, without label and separator" do
    with_value_for @user, :updated_at
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
    assert_select "div.show_for div.wrapper", /#{Regexp.escape(I18n.l(@user.updated_at))}/
  end

  test "show_for accepts an attribute as time with format options, without label and separator" do
    with_value_for @user, :created_at, format: :long
    assert_select "div.show_for div.wrapper", /#{Regexp.escape(I18n.l(@user.created_at, format: :long))}/
  end

  test "show_for accepts an attribute as nil, without label and separator" do
    with_value_for @user, :birthday
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
    assert_select "div.show_for div.wrapper", /Not specified/
  end

  test "show_for accepts blank attributes, without label and separator" do
    with_value_for @user, :description
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
    assert_select "div.show_for div.wrapper", /Not specified/
  end

  test "show_for uses :if_blank if attribute is nil, without label and separator" do
    with_value_for @user, :birthday, if_blank: "No description provided"
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
    assert_select "div.show_for div.wrapper", /No description provided/
  end

  test "show_for uses :if_blank if attribute is blank, without label and separator" do
    with_value_for @user, :description, if_blank: "No description provided"
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
    assert_select "div.show_for div.wrapper", /No description provided/
  end

  test "show_for escapes content by default, without label and separator" do
    @user.name = "<b>hack you!</b>"
    with_value_for @user, :name
    assert_no_select "div.show_for div.wrapper strong.label"
    assert_no_select "div.show_for div.wrapper br"
    assert_no_select "div.show_for div.wrapper b"
    assert_select "div.show_for div.wrapper", "<b>hack you!</b>"
  end
end
Download .txt
gitextract_7x2s2uzu/

├── .github/
│   ├── code-scanning.yml
│   └── workflows/
│       └── test.yml
├── .gitignore
├── CHANGELOG.md
├── Gemfile
├── MIT-LICENSE
├── README.md
├── Rakefile
├── gemfiles/
│   ├── Gemfile-rails-7-0
│   ├── Gemfile-rails-7-1
│   ├── Gemfile-rails-7-2
│   ├── Gemfile-rails-8-0
│   └── Gemfile-rails-main
├── lib/
│   ├── generators/
│   │   └── show_for/
│   │       ├── USAGE
│   │       ├── install_generator.rb
│   │       └── templates/
│   │           ├── en.yml
│   │           ├── show.html.erb
│   │           ├── show.html.haml
│   │           ├── show.html.slim
│   │           └── show_for.rb
│   ├── show_for/
│   │   ├── association.rb
│   │   ├── attribute.rb
│   │   ├── builder.rb
│   │   ├── content.rb
│   │   ├── helper.rb
│   │   ├── label.rb
│   │   └── version.rb
│   └── show_for.rb
├── show_for.gemspec
└── test/
    ├── association_test.rb
    ├── attribute_test.rb
    ├── builder_test.rb
    ├── content_test.rb
    ├── generators/
    │   └── show_for_generator_test.rb
    ├── helper_test.rb
    ├── label_test.rb
    ├── support/
    │   ├── misc_helpers.rb
    │   └── models.rb
    ├── test_helper.rb
    └── value_test.rb
Download .txt
SYMBOL INDEX (86 symbols across 20 files)

FILE: lib/generators/show_for/install_generator.rb
  type ShowFor (line 1) | module ShowFor
    type Generators (line 2) | module Generators
      class InstallGenerator (line 3) | class InstallGenerator < Rails::Generators::Base
        method copy_initializers (line 8) | def copy_initializers
        method copy_locale_file (line 12) | def copy_locale_file
        method copy_generator_template (line 16) | def copy_generator_template

FILE: lib/show_for.rb
  type ShowFor (line 4) | module ShowFor
    function setup (line 64) | def self.setup

FILE: lib/show_for/association.rb
  type ShowFor (line 1) | module ShowFor
    type Association (line 2) | module Association
      function attribute (line 3) | def attribute(attribute_name, options = {}, &block)
      function association (line 12) | def association(association_name, options = {}, &block)
      function values_from_association (line 40) | def values_from_association(association, options) #:nodoc:

FILE: lib/show_for/attribute.rb
  type ShowFor (line 1) | module ShowFor
    type Attribute (line 2) | module Attribute
      function attribute (line 3) | def attribute(attribute_name, options = {}, &block)
      function value (line 13) | def value(attribute_name, options = {}, &block)
      function attributes (line 22) | def attributes(*attribute_names)
      function attribute_value (line 30) | def attribute_value(attribute_name, &block)
      function block_from_value_option (line 40) | def block_from_value_option(attribute_name, options)
      function block_from_symbol (line 50) | def block_from_symbol(attribute_name, options)

FILE: lib/show_for/builder.rb
  type ShowFor (line 6) | module ShowFor
    class Builder (line 7) | class Builder
      method initialize (line 15) | def initialize(object, template)
      method object_name (line 21) | def object_name #:nodoc:
      method wrap_label_and_content (line 34) | def wrap_label_and_content(name, value, options, &block) #:nodoc:
      method wrap_content (line 43) | def wrap_content(name, value, options, &block) #:nodoc:
      method apply_default_options! (line 48) | def apply_default_options!(name, options) #:nodoc:
      method apply_wrapper_options! (line 54) | def apply_wrapper_options!(type, options, value)
      method wrap_with (line 63) | def wrap_with(type, content, options) #:nodoc:
      method collection_block? (line 79) | def collection_block?(block) #:nodoc:
      method skip_blanks? (line 84) | def skip_blanks?(value) #:nodoc:
      method is_empty? (line 88) | def is_empty?(value) #:nodoc:

FILE: lib/show_for/content.rb
  type ShowFor (line 1) | module ShowFor
    type Content (line 2) | module Content
      function content (line 3) | def content(value, options = {}, apply_options = true, &block)
      function collection_handler (line 40) | def collection_handler(value, options, &block) #:nodoc:
      function translate_blank_html (line 50) | def translate_blank_html
      function translate_blank_text (line 54) | def translate_blank_text
      function blank_value (line 58) | def blank_value(options)

FILE: lib/show_for/helper.rb
  type ShowFor (line 1) | module ShowFor
    type Helper (line 2) | module Helper
      function show_for (line 12) | def show_for(object, html_options = {}, &block)
      function show_for_html_class (line 28) | def show_for_html_class(object, html_options)

FILE: lib/show_for/label.rb
  type ShowFor (line 1) | module ShowFor
    type Label (line 2) | module Label
      function label (line 3) | def label(text_or_attribute, options = {}, apply_options = true)
      function human_attribute_name (line 21) | def human_attribute_name(attribute) #:nodoc:

FILE: lib/show_for/version.rb
  type ShowFor (line 1) | module ShowFor

FILE: test/association_test.rb
  class AssociationTest (line 3) | class AssociationTest < ActionView::TestCase
    method tags (line 34) | def @user.tags
    method tags (line 46) | def @user.tags
    method tags (line 60) | def @user.tags
    method tags (line 73) | def @user.tags
    method tags (line 132) | def @user.tags
    method company (line 143) | def @user.company

FILE: test/attribute_test.rb
  class AttributeTest (line 3) | class AttributeTest < ActionView::TestCase

FILE: test/builder_test.rb
  class BuilderTest (line 3) | class BuilderTest < ActionView::TestCase

FILE: test/content_test.rb
  class ContentTest (line 3) | class ContentTest < ActionView::TestCase

FILE: test/generators/show_for_generator_test.rb
  class ShowForGeneratorTest (line 3) | class ShowForGeneratorTest < Rails::Generators::TestCase

FILE: test/helper_test.rb
  class CustomBuilder (line 3) | class CustomBuilder < ShowFor::Builder
  class HelperTest (line 6) | class HelperTest < ActionView::TestCase

FILE: test/label_test.rb
  class LabelTest (line 3) | class LabelTest < ActionView::TestCase

FILE: test/support/misc_helpers.rb
  type MiscHelpers (line 1) | module MiscHelpers
    function store_translations (line 2) | def store_translations(locale, translations, &block)
    function assert_no_select (line 11) | def assert_no_select(selector, value = nil)
    function swap (line 15) | def swap(object, new_values)
    function with_attribute_for (line 28) | def with_attribute_for(object, attribute, options = {}, &block)
    function with_value_for (line 34) | def with_value_for(object, attribute, options = {}, &block)
    function with_association_for (line 40) | def with_association_for(object, association, options = {}, &block)
    function with_label_for (line 46) | def with_label_for(object, attribute, options = {})
    function with_content_for (line 52) | def with_content_for(object, value, options = {})
    function with_attributes_for (line 58) | def with_attributes_for(object, *attributes)

FILE: test/support/models.rb
  function alternate_name (line 6) | def alternate_name
  function all (line 15) | def self.all(options = {})
  function alternate_name (line 19) | def alternate_name
  class User (line 24) | class User < OpenStruct
    method tags (line 30) | def tags
    method company (line 34) | def company
    method human_attribute_name (line 38) | def self.human_attribute_name(attribute)
    method human_name (line 49) | def self.human_name
  type Namespaced (line 54) | module Namespaced
    class User (line 55) | class User < ::User

FILE: test/test_helper.rb
  class ActionView::TestCase (line 23) | class ActionView::TestCase
    method setup_new_user (line 29) | def setup_new_user(options = {})

FILE: test/value_test.rb
  class ValueTest (line 3) | class ValueTest < ActionView::TestCase
Condensed preview — 40 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (69K chars).
[
  {
    "path": ".github/code-scanning.yml",
    "chars": 26,
    "preview": "paths-ignore:\n  - test/**\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 1796,
    "preview": "name: Test\n\npermissions:\n  contents: read\non:\n  push:\n    branches:\n      - main\n  pull_request:\n  workflow_dispatch:\njo"
  },
  {
    "path": ".gitignore",
    "chars": 30,
    "preview": ".bundle/\npkg/\ngemfiles/*.lock\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 4271,
    "preview": "## Unreleased\n\n* Ruby 4.0 support (no changes required)\n\n## 0.9.0\n\n* Add support for Ruby 3.3/3.4 and Rails 7.2/8.0/8.1."
  },
  {
    "path": "Gemfile",
    "chars": 126,
    "preview": "source 'https://rubygems.org'\n\ngemspec\n\ngem 'railties', '~> 8.1.0'\ngem 'activemodel', '~> 8.1.0'\ngem 'actionpack', '~> 8"
  },
  {
    "path": "MIT-LICENSE",
    "chars": 1128,
    "preview": "Copyright (c) 2020-CURRENT Rafael França, Carlos Antonio da Silva\nCopyright (c) 2012-2019 Plataformatec\n\nPermission is h"
  },
  {
    "path": "README.md",
    "chars": 7056,
    "preview": "# ShowFor\n\n[![Gem Version](https://badge.fury.io/rb/show_for.svg)](https://badge.fury.io/rb/show_for)\n\nShowFor allows yo"
  },
  {
    "path": "Rakefile",
    "chars": 617,
    "preview": "# encoding: UTF-8\n\nrequire 'bundler'\nBundler::GemHelper.install_tasks\n\nrequire 'rake/testtask'\nrequire 'rdoc/task'\n\ndesc"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-0",
    "chars": 137,
    "preview": "source 'https://rubygems.org'\n\ngemspec path: '..'\n\ngem 'railties', '~> 7.0.0'\ngem 'activemodel', '~> 7.0.0'\ngem 'actionp"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-1",
    "chars": 137,
    "preview": "source 'https://rubygems.org'\n\ngemspec path: '..'\n\ngem 'railties', '~> 7.1.0'\ngem 'activemodel', '~> 7.1.0'\ngem 'actionp"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-2",
    "chars": 137,
    "preview": "source 'https://rubygems.org'\n\ngemspec path: '..'\n\ngem 'railties', '~> 7.2.0'\ngem 'activemodel', '~> 7.2.0'\ngem 'actionp"
  },
  {
    "path": "gemfiles/Gemfile-rails-8-0",
    "chars": 137,
    "preview": "source 'https://rubygems.org'\n\ngemspec path: '..'\n\ngem 'railties', '~> 8.0.0'\ngem 'activemodel', '~> 8.0.0'\ngem 'actionp"
  },
  {
    "path": "gemfiles/Gemfile-rails-main",
    "chars": 218,
    "preview": "source 'https://rubygems.org'\n\ngemspec path: '..'\n\ngem 'railties', github: 'rails/rails', branch: 'main'\ngem 'activemode"
  },
  {
    "path": "lib/generators/show_for/USAGE",
    "chars": 127,
    "preview": "To copy a ShowFor initializer to your Rails App, with some configuration values, just do:\n\n    rails generate show_for:i"
  },
  {
    "path": "lib/generators/show_for/install_generator.rb",
    "chars": 699,
    "preview": "module ShowFor\n  module Generators\n    class InstallGenerator < Rails::Generators::Base\n      desc \"Copy ShowFor install"
  },
  {
    "path": "lib/generators/show_for/templates/en.yml",
    "chars": 201,
    "preview": "en:\n  show_for:\n    blank: \"Not specified\"\n    # If you want to use html tags with blank value use blank html translatio"
  },
  {
    "path": "lib/generators/show_for/templates/show.html.erb",
    "chars": 326,
    "preview": "<%%= show_for @<%= singular_name %> do |s| %>\n<% attributes.each do |attribute| -%>\n  <%%= s.<%= attribute.reference? ? "
  },
  {
    "path": "lib/generators/show_for/templates/show.html.haml",
    "chars": 293,
    "preview": "= show_for(@<%= singular_name %>) do |s|\n<%- attributes.each do |attribute| -%>\n  = s.<%= attribute.reference? ? :associ"
  },
  {
    "path": "lib/generators/show_for/templates/show.html.slim",
    "chars": 293,
    "preview": "= show_for(@<%= singular_name %>) do |s|\n<%- attributes.each do |attribute| -%>\n  = s.<%= attribute.reference? ? :associ"
  },
  {
    "path": "lib/generators/show_for/templates/show_for.rb",
    "chars": 2072,
    "preview": "# Use this setup block to configure all options available in ShowFor.\nShowFor.setup do |config|\n  # The tag which wraps "
  },
  {
    "path": "lib/show_for/association.rb",
    "chars": 1524,
    "preview": "module ShowFor\n  module Association\n    def attribute(attribute_name, options = {}, &block)\n      if association_name = "
  },
  {
    "path": "lib/show_for/attribute.rb",
    "chars": 1720,
    "preview": "module ShowFor\n  module Attribute\n    def attribute(attribute_name, options = {}, &block)\n      apply_default_options!(a"
  },
  {
    "path": "lib/show_for/builder.rb",
    "chars": 3233,
    "preview": "require 'show_for/attribute'\nrequire 'show_for/association'\nrequire 'show_for/content'\nrequire 'show_for/label'\n\nmodule "
  },
  {
    "path": "lib/show_for/content.rb",
    "chars": 1891,
    "preview": "module ShowFor\n  module Content\n    def content(value, options = {}, apply_options = true, &block)\n      # cache value f"
  },
  {
    "path": "lib/show_for/helper.rb",
    "chars": 921,
    "preview": "module ShowFor\n  module Helper\n    # Creates a div around the object and yields a builder.\n    #\n    # Example:\n    #\n  "
  },
  {
    "path": "lib/show_for/label.rb",
    "chars": 699,
    "preview": "module ShowFor\n  module Label\n    def label(text_or_attribute, options = {}, apply_options = true)\n      label = if text"
  },
  {
    "path": "lib/show_for/version.rb",
    "chars": 46,
    "preview": "module ShowFor\n  VERSION = \"0.9.0\".freeze\nend\n"
  },
  {
    "path": "lib/show_for.rb",
    "chars": 1383,
    "preview": "require 'action_view'\nrequire 'show_for/helper'\n\nmodule ShowFor\n  autoload :Builder, 'show_for/builder'\n\n  mattr_accesso"
  },
  {
    "path": "show_for.gemspec",
    "chars": 1226,
    "preview": "# -*- encoding: utf-8 -*-\n$:.push File.expand_path(\"../lib\", __FILE__)\nrequire \"show_for/version\"\n\nGem::Specification.ne"
  },
  {
    "path": "test/association_test.rb",
    "chars": 5688,
    "preview": "require 'test_helper'\n\nclass AssociationTest < ActionView::TestCase\n  test \"show_for works with belongs_to/has_one assoc"
  },
  {
    "path": "test/attribute_test.rb",
    "chars": 8814,
    "preview": "require 'test_helper'\n\nclass AttributeTest < ActionView::TestCase\n  # COLLECTIONS\n  test \"show_for accepts an attribute "
  },
  {
    "path": "test/builder_test.rb",
    "chars": 2950,
    "preview": "require 'test_helper'\n\nclass BuilderTest < ActionView::TestCase\n  # WRAPPER\n  test \"show_for allows wrapper to be config"
  },
  {
    "path": "test/content_test.rb",
    "chars": 1155,
    "preview": "require 'test_helper'\n\nclass ContentTest < ActionView::TestCase\n  test \"show_for#content accepts any object\" do\n    with"
  },
  {
    "path": "test/generators/show_for_generator_test.rb",
    "chars": 753,
    "preview": "require 'test_helper'\n\nclass ShowForGeneratorTest < Rails::Generators::TestCase\n  tests ShowFor::Generators::InstallGene"
  },
  {
    "path": "test/helper_test.rb",
    "chars": 1502,
    "preview": "require \"test_helper\"\n\nclass CustomBuilder < ShowFor::Builder\nend\n\nclass HelperTest < ActionView::TestCase\n  test \"show "
  },
  {
    "path": "test/label_test.rb",
    "chars": 2808,
    "preview": "require 'test_helper'\n\nclass LabelTest < ActionView::TestCase\n  test \"show_for shows a label using the humanized attribu"
  },
  {
    "path": "test/support/misc_helpers.rb",
    "chars": 1519,
    "preview": "module MiscHelpers\n  def store_translations(locale, translations, &block)\n    begin\n      I18n.backend.store_translation"
  },
  {
    "path": "test/support/models.rb",
    "chars": 873,
    "preview": "require 'ostruct'\n\nCompany = Struct.new(:id, :name) do\n  extend ActiveModel::Naming\n\n  def alternate_name\n    \"Alternate"
  },
  {
    "path": "test/test_helper.rb",
    "chars": 1028,
    "preview": "require 'bundler/setup'\n\nrequire 'minitest/autorun'\n\nrequire 'active_model'\nrequire 'action_controller'\nrequire 'action_"
  },
  {
    "path": "test/value_test.rb",
    "chars": 4040,
    "preview": "require 'test_helper'\n\nclass ValueTest < ActionView::TestCase\n  test \"show_for allows content tag to be configured globa"
  }
]

About this extraction

This page contains the full source code of the plataformatec/show_for GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 40 files (62.1 KB), approximately 17.7k tokens, and a symbol index with 86 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!