Documenting from the Trenches

          Xavier Noria
             @fxn
          RuPy 2011
module Globalize
  class MigrationError < StandardError; end
  class MigrationMissingTranslatedField < MigrationError; end
  class BadMigrationFieldType < MigrationError; end

  module ActiveRecord
    autoload :Adapter ,       ’globalize/active_record/adapter’
    autoload :Attributes ,    ’globalize/active_record/attributes’
    autoload :Migration ,     ’globalize/active_record/migration’

    def self.included(base)
      base.extend ActMacro
    end
    ...
  end
end
Infer
Community Drivers


⋆   Documentation tools
⋆   Imitation
⋆   Leaders’ commitment
Perl
$ perldoc IO::String
$ perldoc perl
Literate Programming
Essayists
Works of Literature
docrails
Style


⋆   Typography
⋆   Spelling
⋆   Conventions
Content
⋆   Simple, concise exposition
⋆   Comprehensive coverage
⋆   Well-chosen examples
⋆   Edge-cases
⋆   Anticipation
Documenting ∼ Teaching
# actionpack/lib/action_controller/base.rb
module ActionController
  class Base < Metal
    ...
    MODULES = [
      AbstractController::Layouts ,
      AbstractController::Translation ,
      AbstractController::AssetPaths ,

        ... about two dozen modules
    ]

    MODULES.each do |mod|
      include mod
    end
    ...
  end
end
# activerecord/lib/active_record/validations.rb
module ActiveRecord
  module Validations
    extend ActiveSupport::Concern
    include ActiveModel::Validations

    module ClassMethods
      def create!(attributes = nil, &block)
        if attributes.is_a?(Array)
          attributes.collect { |attr| create!(attr , &block) }
        else
          object = new(attributes)
          yield(object) if block_given?
          object.save!
          object
        end
      end
    end
    ...
  end
end
<!DOCTYPE html>
<html>
<head>
  <title>DefaultLayout</title>
  <%= stylesheet_link_tag :all %>
  <%= javascript_include_tag :defaults %>
  <%= csrf_meta_tag %>
</head>
<body>

<%= yield %>

</body>
</html>
# Returns a meta tag with the cross -site request forgery protection
# token for forms to use. Place this in your head.
def csrf_meta_tag
  if protect_against_forgery?
    %(<meta name=”csrf -param” content=”...”/>n<meta ...>).html_safe
  end
end
# Returns a meta tag with the cross -site request forgery protection
# token for forms to use. Place this in your head.
def csrf_meta_tag
  <<-METAS.strip_heredoc.chomp.html_safe if protect_against_forgery?
    <meta name=”csrf -param” content=”...”/>
    <meta name=”csrf -token” content=”...”/>
  METAS
end
# Returns meta tags ”csrf -param” and ”csrf -token” with the name
# of the cross -site request forgery protection parameter and
# token , respectively.
#
#   <head >
#     <%= csrf_meta_tag %>
#   </head >
#
# These are used to generate the dynamic forms that implement
# non-remote links with <tt>:method </tt>.
#
# Note that regular forms generate hidden fields , and that Ajax
# calls are whitelisted , so they do not use these tags.
def csrf_meta_tag
  <<-METAS.strip_heredoc.chomp.html_safe if protect_against_forgery?
    <meta name=”csrf -param” content=”...”/>
    <meta name=”csrf -token” content=”...”/>
  METAS
end
# Returns meta tags ”csrf -param” and ”csrf -token” with the name
# of the cross -site request forgery protection parameter and
# token , respectively.
#
#   <head >
#     <%= csrf_meta_tags %>
#   </head >
#
# These are used to generate the dynamic forms that implement
# non-remote links with <tt>:method </tt>.
#
# Note that regular forms generate hidden fields , and that Ajax
# calls are whitelisted , so they do not use these tags.
def csrf_meta_tags
  <<-METAS.strip_heredoc.chomp.html_safe if protect_against_forgery?
    <meta name=”csrf -param” content=”...”/>
    <meta name=”csrf -token” content=”...”/>
  METAS
end
# Returns meta tags ”csrf -param” and ”csrf -token” with the name
# of the cross -site request forgery protection parameter and
# token , respectively.
#
#   <head >
#     <%= csrf_meta_tags %>
#   </head >
#
# These are used to generate the dynamic forms that implement
# non-remote links with <tt>:method </tt>.
#
# Note that regular forms generate hidden fields , and that Ajax
# calls are whitelisted , so they do not use these tags.
def csrf_meta_tags
  <<-METAS.strip_heredoc.chomp.html_safe if protect_against_forgery?
    <meta name=”csrf -param” content=”...”/>
    <meta name=”csrf -token” content=”...”/>
  METAS
end

# For backwards compatibility.
alias csrf_meta_tag csrf_meta_tags
Documentation Maintenance
$ ack csrf_meta_tag
Wish List


⋆   Load + introspect for API
⋆   Link API and tests
⋆   Test coverage for guides
Thanks

Documenting from the Trenches

  • 1.
    Documenting from theTrenches Xavier Noria @fxn RuPy 2011
  • 4.
    module Globalize class MigrationError < StandardError; end class MigrationMissingTranslatedField < MigrationError; end class BadMigrationFieldType < MigrationError; end module ActiveRecord autoload :Adapter , ’globalize/active_record/adapter’ autoload :Attributes , ’globalize/active_record/attributes’ autoload :Migration , ’globalize/active_record/migration’ def self.included(base) base.extend ActMacro end ... end end
  • 5.
  • 9.
    Community Drivers ⋆ Documentation tools ⋆ Imitation ⋆ Leaders’ commitment
  • 10.
  • 13.
  • 15.
  • 19.
  • 20.
  • 21.
  • 25.
  • 26.
    Style ⋆ Typography ⋆ Spelling ⋆ Conventions
  • 27.
    Content ⋆ Simple, concise exposition ⋆ Comprehensive coverage ⋆ Well-chosen examples ⋆ Edge-cases ⋆ Anticipation
  • 28.
  • 29.
    # actionpack/lib/action_controller/base.rb module ActionController class Base < Metal ... MODULES = [ AbstractController::Layouts , AbstractController::Translation , AbstractController::AssetPaths , ... about two dozen modules ] MODULES.each do |mod| include mod end ... end end
  • 30.
    # activerecord/lib/active_record/validations.rb module ActiveRecord module Validations extend ActiveSupport::Concern include ActiveModel::Validations module ClassMethods def create!(attributes = nil, &block) if attributes.is_a?(Array) attributes.collect { |attr| create!(attr , &block) } else object = new(attributes) yield(object) if block_given? object.save! object end end end ... end end
  • 31.
    <!DOCTYPE html> <html> <head> <title>DefaultLayout</title> <%= stylesheet_link_tag :all %> <%= javascript_include_tag :defaults %> <%= csrf_meta_tag %> </head> <body> <%= yield %> </body> </html>
  • 32.
    # Returns ameta tag with the cross -site request forgery protection # token for forms to use. Place this in your head. def csrf_meta_tag if protect_against_forgery? %(<meta name=”csrf -param” content=”...”/>n<meta ...>).html_safe end end
  • 33.
    # Returns ameta tag with the cross -site request forgery protection # token for forms to use. Place this in your head. def csrf_meta_tag <<-METAS.strip_heredoc.chomp.html_safe if protect_against_forgery? <meta name=”csrf -param” content=”...”/> <meta name=”csrf -token” content=”...”/> METAS end
  • 34.
    # Returns metatags ”csrf -param” and ”csrf -token” with the name # of the cross -site request forgery protection parameter and # token , respectively. # # <head > # <%= csrf_meta_tag %> # </head > # # These are used to generate the dynamic forms that implement # non-remote links with <tt>:method </tt>. # # Note that regular forms generate hidden fields , and that Ajax # calls are whitelisted , so they do not use these tags. def csrf_meta_tag <<-METAS.strip_heredoc.chomp.html_safe if protect_against_forgery? <meta name=”csrf -param” content=”...”/> <meta name=”csrf -token” content=”...”/> METAS end
  • 35.
    # Returns metatags ”csrf -param” and ”csrf -token” with the name # of the cross -site request forgery protection parameter and # token , respectively. # # <head > # <%= csrf_meta_tags %> # </head > # # These are used to generate the dynamic forms that implement # non-remote links with <tt>:method </tt>. # # Note that regular forms generate hidden fields , and that Ajax # calls are whitelisted , so they do not use these tags. def csrf_meta_tags <<-METAS.strip_heredoc.chomp.html_safe if protect_against_forgery? <meta name=”csrf -param” content=”...”/> <meta name=”csrf -token” content=”...”/> METAS end
  • 36.
    # Returns metatags ”csrf -param” and ”csrf -token” with the name # of the cross -site request forgery protection parameter and # token , respectively. # # <head > # <%= csrf_meta_tags %> # </head > # # These are used to generate the dynamic forms that implement # non-remote links with <tt>:method </tt>. # # Note that regular forms generate hidden fields , and that Ajax # calls are whitelisted , so they do not use these tags. def csrf_meta_tags <<-METAS.strip_heredoc.chomp.html_safe if protect_against_forgery? <meta name=”csrf -param” content=”...”/> <meta name=”csrf -token” content=”...”/> METAS end # For backwards compatibility. alias csrf_meta_tag csrf_meta_tags
  • 37.
  • 38.
  • 39.
    Wish List ⋆ Load + introspect for API ⋆ Link API and tests ⋆ Test coverage for guides
  • 40.