<!--
Provides a read-only view tailored to the type of the object being viewed. `<view>` is a _polymorphic_ tag which means that there are a variety of definitions, each one written for a particular type. For example there are views for `Date`, `Time`, `Numeric`, `String` and `Boolean`. The type specific view is enclosed in a wrapper tag (typically a `<span>` or `<div>`) with some useful classes automatically added.

### Usage

Assuming the context is a blog post...

* Viewing a DateTime field:

        <view:created_at/> -> <span class="view blog-post-created-at">June 09, 2008 15:36</span>
* Viewing a String field:

        <view:title/> -> <span class="view blog-post-title">My First Blog Post</span>
* Viewing an Integer field:

        <view:comment_count/> -> <span class="view blog-post-comment-count">4</span>
* Viewing the blog post itself results in a link to the blog post (using Rapid's `<a>` tag):

        <view/> -> <span class="view model:blog-post-1"><a href="/blog_posts/1">My First Blog Post</a></span>

### if-blank

The `if-blank` attribute can be used to provide alternate content if `this.blank?`.

        <view if-blank="(None)"/>

### force

The `force` attribute causes the permission check to be skipped.

        <view force/>

### Additional Notes

* The wrapper tag is `<span>` unless the field type is `Text` (different to `String`) where it is `<div>`. Use the `inline` or `block` attributes to force a `<span>` or a `<div>`, e.g.

        <view:body/> -> <div class="view blog-post-body">This is my blog post body</div>

        <view:body inline/> -> <span class="view blog-post-body">This is my blog post body</span>

        <view:created_at block/> -> <div class="view blog-post-created-at">June 09, 2008 15:36</div>

* Use the `no-wrapper` attribute to remove the wrapper tag completely. e.g.

        <view:created_at no-wrapper/> -> June 09, 2008 15:36
-->
<def tag="view" attrs="inline, block, if-blank, no-wrapper, truncate, force"><%=
  raise Hobo::PermissionDeniedError, "view of non-viewable field '#{this_field}' of #{this_parent.typed_id rescue this_parent}" unless
    force || can_view?

  res = if this.nil? && if_blank.nil?
          this_type.is_a?(Class) && this_type <= String ? "" : nil_view
        elsif (refl = this_field_reflection) && refl.macro == :has_many
          collection_view(attributes)
        else
          view_tag = find_polymorphic_tag("view")

          if view_tag == "view" # i.e. it didn't find a type specific tag
            if this.respond_to?(:to_html)
              this.to_html(scope.xmldoctype)
            else
              this.to_s
            end
          else
            attrs = add_classes(attributes, "view", type_and_field._?.dasherize, model_id_class)

            view_attrs = attrs_for(view_tag)
            the_view = send(view_tag, attrs & view_attrs)

            the_view = if_blank if if_blank && the_view.blank?

            truncate = 30 if truncate == true
            the_view = self.truncate(the_view, :length => truncate.to_i) if truncate
            the_view = the_view.html_safe? ? the_view.strip.html_safe : the_view.strip

            if no_wrapper
              the_view
            else
              wrapper = if inline
                          :span
                        elsif block || this_type <= HoboFields::Types::Text
                          :div
                        else
                          :span
                        end
              element(wrapper, attrs - view_attrs, the_view)
            end
          end
        end
   Dryml.last_if = !res.blank?
   res
%></def>