The demonstration

You can run a simple demonstration to see docassemble in action.

Run the demo

The interface is based on Bootstrap, which is both mobile-friendly and desktop-friendly. Try it out on a mobile device.

Note that the example interview is not intended to make logical sense as an interview; it is simply intended to demonstrate the features of docassemble.

100% of the source code for the example interview is listed below in the form of two YAML files, which are annotated with comments.

When you are using the demonstration, you can click “Source” to see the YAML source code that generated the question, along with a review of the conditions that led to the question being asked. You can learn a lot about how to do things in docassemble by clicking “Source” and comparing the YAML source to the end result. The “Source” tab is only available because the demo server is configured as a development server (by setting debug: True in the configuration file). End users will not see a “Source” tab.

The YAML file that generates the demonstration interview

The YAML file that generates the interview, questions.yml, is listed below. Note that:

  • It incorporates by reference another YAML file, basic-questions.yml, which specifies how certain common questions should be asked. The content of this file is listed below.
  • The code is not entirely self-explanatory, but for computer code, it is pretty close to plain English.
  • The questions and logic are not specified in any particular order. If docassemble needs to get the value of a variable, it knows where to find it. This makes things easier for the author, who can organize the questions however he or she wants and use keyword searching to navigate. Moreover, the author can represent the underlying legal logic in modular, bite-size pieces. A question or a bit of logic that an author writes for one interview can be packaged and reused in other interviews.
metadata:
  title: |
    Demonstration interview
  short title:
    Demo
  description: |
    This is a demonstration of the docassemble system.
  authors:
    - name: Jonathan Pyle
      organization: none
  revision_date: 2017-05-26
comment: |
  A "metadata" block contains information about the interview, such as
  the title of the interview as displayed in the navigation bar.
---
interview help:
  heading: |
    % if interface() == 'sms':
    About this text messaging service
    % else:
    About this web site
    % endif
  content: |
    Answer each question.  At the end, you may be given a document
    that you can save.
    
    % if interface() == 'web':
    If you see a word written in green text, you can click on it to
    see more information about the word.  You can try this out here 
    to find out more about rhododendron plants.
    % endif
comment: |
  An "interview help" block adds text to the "Help" page of every
  question in the interview.  If the question has help text of its
  own, the "interview help" will appear after the question-specific
  help.

  This help screen displays different text depending on whether the
  web interface or the SMS interface is being used.
---
language: es
interview help:
  heading: Acerca de este sitio web
  content: |
    Conteste cada pregunta. Al final, se le puede dar un documento
    que puede ahorrar.
comment: |
  This interview is not fully translated into Spanish, but this shows
  how you would provide a Spanish translation of the "interview help."
---
include:
  - basic-questions.yml
comment: |
  This loads some question definitions that are common to many legal
  interviews.  It also defines basic variables like "user" and sets
  the names of icons that you can use to "decorate" your questions.

  The "basic-questions.yml" comes from the docassemble.base package
  and is located in the directory docassemble/base/data/questions
  in that package.

  You can include question files from other packages by explicitly
  referring to their package names.  For example,
  "docassemble.helloworld:questions.yml" refers to the file
  questions.yml in the docassemble/helloworld/data/questions
  directory of the docassemble.helloworld package.
---
image sets:
  freepik:
    attribution: |
      Icon made by [Freepik](http://www.flaticon.com/authors/freepik)
    images:
      baby: crawling.svg
      people: users6.svg
      injury: accident3.svg
comment: |
  An "image sets" block defines the names of icons that you can use to
  "decorate" your questions.  Loading the "basic-questions.yml" file
  already defined a number of icons, but this block defines some more
  icons.

  Since most free icons available on the internet require attribution,
  the "image sets" block allows you to specify what attribution text
  to use for particular icons.  The web app shows the appropriate
  attribution text at the bottom of any page that uses one of the
  icons.
  
  Since this file, questions.yml, is in the docassemble.demo package,
  the image files referenced here are also in the docassemble.demo
  package.  The files are located in the directory
  docassemble/demo/data/static.
---
objects:
  - village_idiot: Individual
comment: |
  In a later question we will refer to the variable "village_idiot."
  This "objects" block creates the variable "village_idiot" and
  specifies that it is an object of type "Individual."
---
auto terms:
  rhododendron: |
     A genus of shrubs or small trees, often having handsome
     evergreen leaves, and remarkable for the beauty of their
     flowers.
  custody order: |
    An order signed by a family court judge that says who gets to have
    what kind of custody over a child.
  complaint: |
    A document that you file in court to start a lawsuit.
  lawyer: |
    Someone with a license to practice law.
  plaintiff: |
    The person who starts a case.
  defendant: |
    The person who is on the defensive in a case.  In a lawsuit, the
    plaintiff sues the defendant.
comment: |
  Sometimes you will use vocabulary that the user may or may not know.
  Instead of interrupting the flow of your questions to define every
  term, you can define certain vocabulary words, and docassemble will
  turn them into hyperlinks wherever they appear.  When the user
  clicks on the hyperlink, a popup appears with the word's definition.
---
mandatory: True
code: |
  client.asset.new('checking account', 'savings account', 'stocks and bonds', 'automobiles')
  client.asset.gathered = True
  client.income.new('employment', 'self employment', 'SSI', 'TANF', 'rent', period=12)
  client.income.gathered = True
comment: |
  This interview will ask whether the client has particular income and assets.

  The objects client.asset and client.income are docassemble objects that function
  like Python "dictionaries."
  
  This code initializes the list of income and asset items.

  The attribute "gathered" is set to True because after being initialized with
  the given items, we want the list to be considered complete.  That is, we
  do not want the interview to ask the user if there are any additional items
  to add.
  
  "Mandatory" sections like this one are evaluated in the order they
  appear in the question file.
---
initial: True
code: |
  set_language(user.language)
comment: |
  When providing interviews in multiple languages, you need to tell docassemble
  what language it should use for the built-in words and expressions
  that the user will see.  This needs to be set up-front in "initial" code, which
  will run every time the screen loads.

  When the interview first loads, user.language is undefined.  Therefore
  docassemble will ask the user a question in order to obtain a definition for
  user.language.  We will encounter this question below.
  
  "Mandatory" and "initial" sections are evaluated in the order they
  appear in the question file.  But "mandatory" sections are different because
  as soon as they run to completion, they will subsequently be skipped.
  "Initial" sections will always be run every time the screen loads.
---
mandatory: True
code: |
  need(user_saw_initial_screen)
  if user_understands_no_attorney_client_relationship == "understands":
    need(client_done)
  else:
    need(client_kicked_out)
comment: |
  This is the code that directs the flow of the interview.

  It runs after the user's language is set by the previous "initial" block.

  Note that there are no other "mandatory" or "initial" questions in the
  interview.  This code block determines how the interview will end.
  
  This code indicates to the system that we need to get to the
  endpoint "client_done."  There is a question elsewhere that contains
  "event: client_done."  Docassemble will ask all the questions
  necessary to get the information need to pose that that final
  question to the user.

  However, if the answer to the question
  user_understands_no_attorney_client_relationship is not
  "understands," the interview will looks for a question that sets the
  variable "client_kicked_out."  There is a question elsewhere that
  contains "event: client_kicked_out."

  This is the code that determines the entire path of the interview,
  and yet it is very short, even though the interview has many questions.
  That is because interview flow in docassemble is automatic.  The order
  in which questions are asked can vary depending on the user input.  In
  some interviews, a question is asked early, and in another, it is asked
  later.  Questions are asked if and when there is a necessity to
  gather information.

  There is one additional bit of the interview flow that is manual: the
  requirement of "user_saw_initial_screen."  This causes a "welcome" screen
  to be shown.  We always want this screen to be displayed first (at
  least as soon as we determine the user's language).
---
code: |
  if client not in case.plaintiff.elements and client.is_plaintiff:
    case.plaintiff.append(client)
  if client not in case.defendant.elements and not client.is_plaintiff and client.is_defendant:
    case.defendant.append(client)
  case.plaintiff.there_are_any = True
  case.defendant.there_are_any = True
comment: |
  This interview relates to a court case.  It takes advantage of the
  basic-questions.yml file in the docassemble.base package.  This
  interview file provides some functionality for legal interviews.

  For example, basic-questions.yml defines the objects "case" and "client."

  But in our interview, what do we want to do with "case" and "client"?
  What is the relation of the client to the case?  Is the client the user,
  or a different person from the user?

  The purpose of the above code is to set initial values for the
  objects case.plaintiff and case.defendant.  These objects are
  docassemble objects that function as Python lists.  They represent
  the plaintiffs and defendants in the case.

  This code will add the client as a plaintiff, or add the client as a
  defendant, depending on whether the client is a plaintiff or a
  defendant.  This code will trigger the asking of questions to
  determine whether the client is a plaintiff or a defendant, if those
  facts are unknown.  Elsewhere there is a question that defines the
  "is_plaintiff" attribute and another question that defines the
  "is_defendant" attribute.

  The end result of this code is to define the "there_are_any"
  attributes of the two lists.  Note that this code is not
  "mandatory."  It will be run when and if the interview needs to know
  whether the lists are empty.  We set the attributes to True because
  all court cases need to have at least one plaintiff and at least one
  defendant.
---
event: client_kicked_out
progress: 100
question: |
  Sorry, you cannot proceed with the interview.
subquestion: |
  You can only proceed with the interview if you agree that your
  completion of the interview does not create an attorney-client
  relationship.

  % if user_understands_no_attorney_client_relationship == 'unsure':
  We suggest that you call us at 215-981-3800 to talk to us about the
  kinds of services we provide.
  % endif
decoration: exit
buttons:
  - Exit: exit
  - Restart: restart
comment: |
  This is an endpoint question (note that the only options are exiting
  or restarting).

  If the interview was configured to show a progress bar, the progress
  bar would be set to 100% on this question.

  This question uses the "event" directive.  "client_kicked_out" is a
  variable, just like any other variable, except that it is never
  defined, only sought.

  We saw above in the "mandatory" code block that if the user does not
  understand that no attorney-client relationship will be created, the
  "client_kicked_out" variable will be sought.  When that variable is
  sought, this question will be displayed to the user.

  This question also uses a "decoration."  This places an icon in the
  corner of the screen.  The image by the name of "exit" is defined
  in the basic-questions.yml file.
---
question: |
  Welcome to the **docassemble** demonstration.
subquestion: |
  The following interview is designed to demonstrate almost all of
  **docassemble**'s features.  At the end, you will be provided with a
  fake client letter and a fake pleading.

  % if interface() == 'web':
  In the navigation bar above, you can click "[Help]" to see the help
  text associated with the interview and with the individual question
  (if any).  If "Help <i class="glyphicon glyphicon-star"></i>"
  appears in the navigation bar, that means help text specific to the
  question is available.

  Click "Source" to toggle the display of the [YAML] code used to
  generate the question.  (Note: the "Source" tab is available because
  this server is configured as a development server; end users would
  not see a "Source" tab.)
  % endif

  [Help]: ${ url_of('help') }
  [YAML]: https://en.wikipedia.org/wiki/YAML
field: user_saw_initial_screen
buttons:
  - Ok, got it: True
comment: |
  This is the "splash screen" for the interview.  The question is a
  multiple-choice question with one option.

  This example demonstrates that HTML can be combined with Markdown
  in the text of questions.  Here, we wanted to show a particular icon
  available in Bootstrap, so we inserted raw HTML.
---
generic object: Individual
question: |
  What language ${ x.do_question('speak') }?
field: x.language
choices:
  - English: en
  - Español: es
default: ${ language_from_browser() }
comment: |
  This is the first question that will be asked because there is
  an "initial" block above that needs the definition of user.language.

  This is a "generic object" question.  It is written in a "generic"
  way so that it will ask "What language do you speak?" or "What language
  does John Smith speak?" depending on whether "x" is the user or not.

  The language_from_browser() function sets the default choice to
  English or Spanish if the web server detects that the user's browser
  is set to either of these languages.  This method of determining the
  user's language is not 100% reliable, but it will save the user from
  making an extra click.
---
generic object: Individual
question: |
  ${ x.do_question('have', capitalize=True) } a support order?
subquestion: |
  If you aren't sure, look through your papers for a document that
  looks something like this.  If this document is signed by the judge,
  then you have a support order.
    
  [FILE sample-support-order.jpg, 100%]
yesno: x.has_support_order
comment: |
  This question illustrates how you can include images in your
  questions.  The file sample-support-order.jpg is stored in the
  docassemble.demo package in the subdirectory
  docassemble/demo/data/static.  This is how you refer to a "static"
  file that exists within a docassemble subpackage.

  The "100%" indicates that the image width should fill the screen.
---
question: What form do you want to prepare?
decoration: document
buttons:
  - Custody Complaint:
      code: |
        law_category = "custody"
        pleading.type = "complaint"
        pleading.title = "Complaint for Custody"
    image: parentchild
  - Support Complaint:
      code: |
        law_category = "support"
        pleading.type = "complaint"
        pleading.title = "Complaint for Support"
    image: coins
comment: |
  This is an example of a multiple-choice question that runs Python
  code (as opposed to simply setting the value of a single variable).

  This example also shows how you can create square buttons with icons
  and labels: you just add an "image" value to the button item.
---
code: |
  if client_has_injury and injury_in_jurisdiction and \
     statute_of_limitations_ok:
    client_has_standing = True
  else:
    client_has_standing = False
comment: |
  This is an example of how docassemble can serve as a legal "expert
  system."  The variable "client_has_standing" (a legal concept) can
  be set using simple logical expressions in Python.  Legal concepts
  can be expressed as true/false variables and the law can be coded in
  logical expressions like these.

  Note that the "\" character at the end of a line is merely a
  formatting aid.  Python normally considers line breaks to indicate
  that a statement is finished.  The "\" character at the end of a
  line tells Python that the statement isn't finished yet.
---
question: Were you injured?
decoration: injury
yesno: client_has_injury
help:
  content: |
    An injury can take many forms.  It can be a physical injury or a
    purely financial injury.
  audio: schumann-clip-3.mp3
progress: 50
comment: |
  This question demonstrates how an audio file can be provided on the
  help screen of a question.
---
question: |
  What is the village idiot's name?
fields:
  - Somebody already mentioned: village_idiot
    datatype: object
    disable others: True
    choices:
      - case.plaintiff
      - case.defendant
  - First Name: village_idiot.name.first
  - Middle Name: village_idiot.name.middle
    required: False
  - Last Name: village_idiot.name.last
  - Suffix: village_idiot.name.suffix
    required: False
    code: name_suffix()
comment: |
  This question demonstrates the use of objects in a multiple choice
  question, as well as the feature of disabling fields when they are
  not necessary.  The question allows the user to indicate who the
  "village_idiot" is.  If the village idiot is a plaintiff or
  defendant, the user will be able to select the person's name from a
  list.  If the village idiot is not a plaintiff or defendant, the
  user can enter the person's name.  Either way, village_idiot will be
  an object.
---
question: |
  I understand that you live in ${ client.address.city }.
  Were you injured in ${ jurisdiction_state }?
yesno: injury_in_jurisdiction
---
question: When did your injury take place?
decoration: calendar
fields:
  - html: |
      The current date and time is <span class="mytime" id="today_time"></span>.
  - Date of Injury: injury_date
    datatype: date
css: |
  <style>
    .mytime {
       color: green;
    }
  </style>
script: |
  <script>
    $("#today_time").html(Date());
  </script>
comment: |
  You can embed raw HTML into a list of fields using the 'html' key.
  You can also expand the capabilities of what you do with this HTML by
  adding 'script' and 'css' keys.

  The text of 'script' is added to the bottom of the page, while the
  text of 'css' is added to the <head>.

  Note that you can use Mako templates in each of these declarations.
---
question: |
  Why do you think you deserve to win this case?
fields:
  - no label: explanation
    datatype: area
    hint: |
      I should win because . . .
---
code: |
  court.jurisdiction = ['US', 'state', 'PA', 'trial', 'Philadelphia County']
  jurisdiction_state = "Pennsylvania"
  jurisdiction_county = "Philadelphia"
comment: |
  This code sets some information about the current jurisdiction.  The
  interview assumes that the legal case is in a Pennsylvania court.

  The court.jurisdiction variable uses a special format that is
  particular to the docassemble.base.legal module.  It is used to
  facilitate the use of "layers" of code, where there is a common
  layer of questions and code applicable at a federal level, another
  layer of questions and code applicable at a state level, another
  layer of questions and code applicable at a county level, etc.

  Note that this code is not "mandatory."  It will be called when and
  if the interview needs to know any of these variables.
---
code: |
  if jurisdiction_state == "Pennsylvania":
      statute_of_limitations_years = 5
  else:
      statute_of_limitations_years = 2
---
code: |
  if jurisdiction_state == "Pennsylvania":
      if law_category == "custody" or law_category == "support":
          court.name = "Court of Common Pleas of " + \
          jurisdiction_county + " County, " + jurisdiction_state
---
code: |
  cutoff_date = current_datetime() - date_interval(years=statute_of_limitations_years)
  if as_datetime(injury_date) > cutoff_date:
      statute_of_limitations_ok = True
  else:
      statute_of_limitations_ok = False
comment: |
  This code uses some date/time functions to determine whether the
  date of the injury is within the statute of limitations period.

  The variable cutoff_date represents the latest date in the past when
  an injury could have occurred that would still be actionable under
  the statute of limitations.

  To calculate cutoff_date, we start with today's date and subtract a
  number of number of years given by the applicable statute of
  limitations.

  The number of years in the applicable statute of limitations period
  is the number stored in the variable statute_of_limitations_years.
---
generic object: Individual
decoration: home
question: |
  What is ${ x.possessive('home') } like?
fields:
  - Type of home: x.address.type
    datatype: radio
    shuffle: True
    choices:
      - Apartment
      - Leased house
      - Owned house
      - Mobile home
  - Amenities: x.address.amenities
    datatype: checkboxes
    code: |
      {u'chimney': u'Chimney', 'stove': 'Stove'}
  - note: |
      How would you describe the general *milieu* of ${ x.possessive('abode') }?
  - no label: x.address.milieu
    required: False
comment: |
  In this question, the type of home uses a "radio" selector.  The
  address type will be set to one of "Apartment," "Leased house,"
  "Owned house," or "Mobile home."  Because "shuffle" is true, the
  order of the choices will be random (different every time the page
  is loaded).

  The "amenities" of the home, by contrast, use a "checkbox" selector.
  This means that the variable will be defined not as text, but as a
  Python dictionary containing key/value pairs.  For example, if
  this question is asked regarding an Individual with the variable
  name "client," and the user selects "Chimney" only, the value of
  client.address.amenities will be a Python dictionary in which
  "chimney" is set to True and "stove" is set to False.

  The "amenities" field demonstrates that checkbox values and labels
  can be set using Python code.  The code needs to evaluate to a
  Python dictionary, where the values are the labels to be shown to
  the user and the keys are the keys that will be used in the
  resulting Python dictionary (x.address.amenities).

  The third "field" is not really a field; it is a "note."  This
  places text onto the screen.  The text can include Markdown and can
  be a Mako template.  In this case, the text introduces the fourth
  field, which is a text field with no label.  Since the label has the
  special value "no label," the field fills the width of the form.
---
generic object: Individual
decoration: home
question: |
  Where ${ x.do_question('live') }?
fields:
  - Address: x.address.address
  - Unit: x.address.unit
    required: False
    help: The apartment, suite, or unit number of the residence.
  - City: x.address.city
  - State: x.address.state
    code: states_list()
  - Zip: x.address.zip
    required: False
comment: |
  This question demonstrates fields that have the style of dropdown
  lists.  The values of a dropdown list can be generated with code
  that runs at the time the question is asked, or they can be
  hard-coded into the question itself.  In this case, we use the
  states_list() function to provide a list of U.S. states.
---
generic object: Individual
question: |
  Please upload one or more pictures of ${ x.yourself_or_name() }.
decoration: picture
fields:
  - A test file: x.picture
    datatype: files
comment: |
  You can accept file uploads from users by using the datatypes "file"
  (for a single file) or "files" (for one or more files).
---
generic object: Individual
question: |
  % if x.picture.number() > 1:
  Are these the pictures you uploaded?
  % else:
  Is this the picture you uploaded?
  % endif
subquestion: |  
  ${ x.picture }
yesno: x.picture_verified
comment: |
  This question demonstrates displaying a picture that a user has uploaded.
---
question: |
  On a scale of 1 to 10, how much hatred do you harbor toward
  ${ case.defendant }?
fields:
  no label: hatred_level
  datatype: range
  min: 1
  max: 10
---
def: kid_defs
mako: |
  <%def name="describe_as_adorable(person)"> \
  ${ person } is adorable. \
  </%def>
comment: |
  docassemble uses the Mako templating system to expand variables
  within Markdown text.  Mako allows functions to be defined within
  source text using "def" constructs.  If you write Mako "def"
  functions, you may want to use them in more than one document.  This
  section shows how you can attach a name (e.g., kid_defs) to some
  Mako text, and an example below shows how an attachment can include
  this Mako text by referring to it by its name (kid_defs).

  Another way to write functions in docassemble is to write methods
  that act on docassemble objects, which you define in your objects.py
  file within your package.
---
comment: |
  This very long question is the interview's main endpoint (it offers
  to define client_done, which was referred to in the mandatory code
  block above.  This question has two "attachment" documents.  Most of
  the questions in the interview are asked because they are needed by
  this question or one of its attachments.

  This question also demonstrates use of the "need" directive to
  gather information about the case's plaintiffs and defendants up
  front.  This is not strictly necessary, because the case caption
  will cause those questions to be answered.  However, the "need"
  clause forces docassemble to gather the information up front, before
  it starts processing the question and its attachments.  This helps
  to direct the order of the questions in a more sensible fashion.
event: client_done
progress: 100
question: |
  % if client_has_standing:
    Congratulations!  You have a valid claim.
  % else:
    Sorry, you do not have a valid claim.
  % endif
decoration: finishline
subquestion: |
  Here is an advice letter and a pleading you can file.

  (Note: the options to see documents in Markdown and LaTeX format are
  hidden when **docassemble** is configured as a production server.
  End users will not see these options.)
help: |
  This is the end of the interview, ${ client }.  You can exit or
  restart.

  I hope you enjoyed this interview.
buttons:
  - Exit: exit
  - Restart: restart
attachments:
  - name: Advice Letter for ${ client }
    filename: Advice_letter_${ space_to_underscore(client) }
    description: |
      This is a *very* helpful advice letter.
    metadata:
      FirstHeaderRight: |
        Example, LLP [BR] 123 Main Street, Suite 1500 [BR] Philadelphia, PA 19102
      HeaderLeft: |
        ${ client } [BR] ${ today() } [BR] Page [PAGENUM]
      HeaderLines: "3"
      SingleSpacing: True
    content: |
      ${ today() }

      ${ client.address_block() }

      Dear ${ client.salutation() } ${ client.name.last }:

      Your marital status is ${ client.marital_status.lower() }.
      % if client.marital_status == 'Single' and village_idiot is not client:
      Perhaps you should marry ${ village_idiot }.
      % endif
      Your annual income is ${ currency(client.income.total()) }
      and the value of all you own is 
      ${ currency(client.asset.total()) }.  Your home is best described as
      a "${ client.address.type }."

      % if hatred_level > 8:
      You seem to dislike ${ case.defendant }.
      % endif

      % if client_has_standing:
      You have a valid claim.
      % else:
      Sorry, you do not have a valid claim.
      % endif

      Carles 8-bit polaroid, banjo bespoke Intelligentsia actually
      PBR&B hashtag. Asymmetrical banjo mustache fashion axe cardigan,
      polaroid literally taxidermy cornhole authentic 3 wolf moon yr
      meditation. Kale chips cliche distillery, stumptown mustache DIY
      hella cred. Cardigan church-key stumptown organic. IPhone street
      art leggings, art party 8-bit Blue Bottle mustache aesthetic
      selvage cold-pressed High Life semiotics Bushwick retro
      Banksy. Aesthetic hella mumblecore, readymade gluten-free
      locavore cliche keytar XOXO tote bag. Put a bird on it swag
      bicycle rights trust fund, hella small batch tousled church-key
      bitters Brooklyn normcore Portland gentrify keytar Austin.

      Semiotics DIY cronut, stumptown McSweeney's 90's plaid pork
      belly Brooklyn squid gentrify chillwave. Occupy forage irony
      banjo heirloom. Irony health goth gentrify, plaid hella Etsy 3
      wolf moon American Apparel chillwave Truffaut retro synth
      artisan wolf bitters. Williamsburg flannel VHS, quinoa banjo
      fingerstache plaid vinyl meditation. Banksy Vice salvia pickled,
      selvage stumptown narwhal artisan Bushwick tilde Portland
      keffiyeh Carles food truck. Master cleanse Echo Park cardigan,
      selvage health goth next level keffiyeh shabby chic hashtag
      aesthetic taxidermy Carles irony fixie. Hella organic swag pork
      belly Bushwick.

      Banh mi stumptown migas, raw denim iPhone distillery
      Pinterest Schlitz. Raw denim Marfa typewriter mustache PBR&B
      cold-pressed. Locavore crucifix occupy, quinoa actually pickled
      ugh ennui VHS normcore literally jean shorts cred
      post-ironic. Godard Pitchfork narwhal direct trade deep v
      drinking vinegar, fingerstache authentic listicle. Kitsch
      literally VHS readymade distillery tattooed. Aesthetic High Life
      shabby chic, typewriter swag plaid Etsy photo booth craft
      beer. Disrupt yr semiotics, wayfarers meh scenester tattooed
      keffiyeh fingerstache meditation chia roof party migas.

      Chambray art party craft beer pork belly health goth,
      locavore photo booth pickled. Cold-pressed gentrify street art,
      butcher direct trade salvia twee hashtag. Flannel semiotics wolf
      next level Tumblr gluten-free. Sustainable shabby chic migas
      Intelligentsia, swag synth meh lumbersexual gentrify. Gastropub
      lumbersexual Blue Bottle, +1 sustainable heirloom meditation
      Pitchfork deep v try-hard blog vinyl. Tofu banjo Kickstarter
      post-ironic cray tilde Tumblr, Marfa polaroid wolf. Schlitz
      selvage narwhal fanny pack, mustache scenester leggings cardigan
      Kickstarter street art polaroid fixie aesthetic PBR&B.

      Semiotics DIY cronut, stumptown McSweeney's 90's plaid pork
      belly Brooklyn squid gentrify chillwave. Occupy forage irony
      banjo heirloom. Irony health goth gentrify, plaid hella Etsy 3
      wolf moon American Apparel chillwave Truffaut retro synth
      artisan wolf bitters. Williamsburg flannel VHS, quinoa banjo
      fingerstache plaid vinyl meditation. Banksy Vice salvia pickled,
      selvage stumptown narwhal artisan Bushwick tilde Portland
      keffiyeh Carles food truck. Master cleanse Echo Park cardigan,
      selvage health goth next level keffiyeh shabby chic hashtag
      aesthetic taxidermy Carles irony fixie. Hella organic swag pork
      belly Bushwick.

      If you have any questions, you can call us at 215-391-9686.

      Sincerely,

      /s/

      John Smith, Attorney
  - name: ${ pleading.title }
    filename: ${ space_to_underscore(pleading.title) }
    metadata:
      FirstFooterCenter: "[HYPHEN] [PAGENUM] [HYPHEN]"
      FooterCenter: "[HYPHEN] [PAGENUM] [HYPHEN]"
      FirstFooterLeft: "${ pleading.title }"
      FooterLeft: "${ pleading.title }"
    usedefs:
      - kid_defs
    content: |
      ${ pleading.caption() }

      I am the ${ case.role_of(client) } in this case.
      % if client.child.number() > 0:
      I have ${ client.child.number_as_word() } ${ client.child.as_noun() }:

      % for child in client.child:
      #. ${ child }
      % endfor

      % for child in client.child:
      ${ describe_as_adorable(child) }
      % endfor
      Aren't children :baby: such a blessing?
      % if client.has_support_order:
      I already have a support order.
      % endif
      % endif

      <%
        index = 0
      %>
      % for party in case.parties():
      The ${ ordinal(index) } party in this case is ${ party },
      a ${ case.role_of(party) },
      % if party.child.number() > 0:
      who has the following ${ party.child.as_noun() }:

      % for child in party.child:
      * ${ child }
      % endfor

      % else:
      who has no children.
      % endif
      <%
        index += 1
      %>
      % endfor
      
      This petition should be granted.
      ${ fix_punctuation(explanation) }
      % if client.picture_verified:
      Look how cute I am:

      [FLUSHLEFT] ${ client.picture }
      % endif

      Chambray art party craft beer pork belly health goth, locavore
      photo booth pickled. Cold-pressed gentrify street art, butcher
      direct trade salvia twee hashtag. Flannel semiotics wolf next
      level Tumblr gluten-free. Sustainable shabby chic migas
      Intelligentsia, swag synth meh lumbersexual gentrify. Gastropub
      lumbersexual Blue Bottle, +1 sustainable heirloom meditation
      Pitchfork deep v try-hard blog vinyl. Tofu banjo Kickstarter
      post-ironic cray tilde Tumblr, Marfa polaroid wolf. Schlitz
      selvage narwhal fanny pack, mustache scenester leggings cardigan
      Kickstarter street art polaroid fixie aesthetic PBR&B.

      Please grant me the relief I request!

      [FLUSHLEFT] Respectfully submitted,

      % if client.signature_verified:
      [FLUSHLEFT] ${ client.signature.show(width='2in') }
      % else:
      [FLUSHLEFT] ${ blank_signature }
      % endif

      [FLUSHLEFT] ${ client }, ${ title_case(case.role_of(client)) }
---
language: es
question: |
  Bienvenido a la demostración **docassemble**.
subquestion: |
  La siguiente entrevista está diseñado para demostrar la casi
  totalidad de características de **docassemble**. Al final, se le
  proporcionará un carta cliente falso y un escrito falso.

  En la barra de navegación de arriba, puede hacer clic en "Ayuda"
  para ver el texto de ayuda asociado a la entrevista y con la
  pregunta individual. Si "Ayuda <i class="glyphicon
  glyphicon-star"></i>" aparece en la barra de navegación, eso
  significa que el texto de ayuda específica a la cuestión está
  disponible.

  Haga clic en "Fuente" para cambiar la visualización del código
  [YAML] utilizado para generar la pregunta.
  
  (This demonstration interview has not been fully translated into
  Spanish; only this page has.  The remainder of the interview will
  fall back to using the available English versions of each question.)

  [YAML]: https://en.wikipedia.org/wiki/YAML
field: user_saw_initial_screen
datatype: boolean
buttons:
  - Comprendo: True
comment: |
  This demonstration interview is not available in Spanish, but this
  question and the question after it demonstrate how multi-lingual
  interviews can be constructed.  This question offers to set
  "user_saw_initial_screen," just like a previous question block did,
  except that this question has a "language: es" directive, indicating
  that this question should only be used if the current language (as
  set by the "initial" code block above using the set_language()
  function) is Spanish.
---
language: es
auto terms:
  cliente: |
    El cliente es la persona que está llenando este formulario
comment: |
  This demonstrates how vocabulary terms can be provided in a
  language other than the default language.
---
generic object: Individual
question: |
  What is ${ x.possessive('gender') }?
field: x.gender
choices:
  - "Male :male:": male
  - "Female :female:": female
  - Other: other
comment: |
  You can include "emoji-style" images by putting colons around an
  image name (as defined in an "images" block).  This feature works
  within labels as well as within question text.
---
generic object: Individual
question: |
  How much ${ x.do_question("make") } from ${ i }?
fields:
  - Amount: x.income[i].value
    datatype: currency
  - "": x.income[i].period
    datatype: number
    code: |
      period_list()
comment: |
  If you do not want a field to be labeled, you can use "" as the
  label name.

  The function period_list() provides a list of options (12 for "Per
  Month," 1 for "Per Year," and 52 for "Per Week").

  The datatype "currency" is like the datatype "number" except that
  causes the input field to be displayed with a locale-specific
  currency symbol.
---
generic object: Individual
question: |
  How much ${ x.do_question("make") } from employment?
decoration: bills
fields:
  - Employment Income: x.income['employment'].value
    datatype: currency
  - "": x.income['employment'].period
    datatype: number
    code: |
      period_list()
comment: |
  The previous question was a general question; this is a specific
  question that asks the question a certain way if the income type is
  "employment."  Although this question and the previous question are
  both capable of defining x.income['employment'].value, this one
  takes precedence because it is more specific.

  The following questions are also specific cases.  The decorations
  are different for each question.
---
generic object: Individual
question: |
  How much ${ x.do_question("make") } from self-employment?
decoration: bills
fields:
  - Self-employment Income: x.income['self employment'].value
    datatype: currency
  - "": x.income['self employment'].period
    datatype: number
    code: |
      period_list()
---
generic object: Individual
question: |
  How much ${ x.do_question("make") } from SSI?
decoration: bills
fields:
  - SSI Income: x.income['SSI'].value
    datatype: currency
  - "": x.income['SSI'].period
    datatype: number
    code: |
      period_list()
---
generic object: Individual
question: |
  How much ${ x.do_question("make") } from cash assistance 
  (Temporary Assistance to Needy Families or TANF)?
decoration: bills
fields:
  - TANF Income: x.income['TANF'].value
    datatype: currency
  - "": x.income['TANF'].period
    datatype: number
    code: |
      period_list()
---
generic object: Individual
question: |
  How much ${ x.do_question("have") } in 
  ${ i }?
fields:
  - Amount: x.asset[i].value
    datatype: currency
---
generic object: Individual
question: |
  How much ${ x.do_question("have") } in 
  ${ x.pronoun_possessive("checking account") }?
decoration: piggybank
fields:
  - Amount in Checking Account: x.asset['checking account'].value
    datatype: currency
---
generic object: Individual
question: |
  How much ${ x.do_question("have") } in 
  ${ x.pronoun_possessive("savings account") }?
decoration: piggybank
fields:
  - Amount in Savings Account: x.asset['savings account'].value
    datatype: currency
---
generic object: Individual
question: |
  How much ${ x.do_question("have") } in stocks and bonds?
decoration: stocks
fields:
  - Amount in Stocks and Bonds: x.asset['stocks and bonds'].value
    datatype: currency
---
generic object: Individual
question: |
  ${ x.do_question("have", capitalize=True) } income from ${ i }?
yesno: x.income[i].exists
comment: |
  This question and the following questions ask the threshold question
  of whether the income or assets is applicable.  If it does not
  "exist," there is no need to ask for its value.
---
generic object: Individual
question: |
  What kinds of income ${ x.do_question("have") }?
decoration: bills
fields:
  - Employment: x.income['employment'].exists
    datatype: yesnowide
  - Self-employment: x.income['self employment'].exists
    datatype: yesnowide
  - SSI: x.income['SSI'].exists
    datatype: yesnowide
  - Cash assistance: x.income['TANF'].exists
    datatype: yesnowide
comment: |
  The datatype "yesnowide" is just like the data type "yesno" except
  that it fills the width of the form rather than aligning with other
  fields that use labels.
---
generic object: Individual
question: |
  ${ x.do_question("own", capitalize=True) } any ${ i }?
yesno: x.asset[i].exists
---
generic object: Individual
question: |
  What kinds of assets ${ x.do_question("own") }?
decoration: piggybank
fields:
  - Checking Account: x.asset['checking account'].exists
    datatype: yesnowide
  - Savings Account: x.asset['savings account'].exists
    datatype: yesnowide
  - Stocks and Bonds: x.asset['stocks and bonds'].exists
    datatype: yesnowide
...

The basic-questions.yml file, incorporated by reference into the demo

Many of the questions asked in the demonstration interview do not need to be defined in the YAML source file because they are already defined in the basic-questions.yml file. Here is an annotated guide to this file.

---
metadata:
  description: |
    This question file contains questions that are common in
    law-related interviews.  It also imports docassemble functions,
    initializes a role system involving a "client" and an "advocate,"
    and defines objects including "client," "advocate," "case,"
    "spouse," "pleading," and "court."    
  authors:
    - name: Jonathan Pyle
      organization: none
  revision_date: 2017-05-26
comment: |
  A "metadata" block contains information about the interview, such as
  the title of the interview as displayed in the navigation bar.
---
modules:
  - docassemble.base.legal
comment: |
  A "modules" section imports class names and function names from
  Python modules.  The docassemble.base.legal module defines some
  object classes and functions that are useful in legal applications.
  
  Using docassemble.base.legal in "modules" also has the effect of
  importing all of the class names and function names that are in
  docassemble.base.util.  So you never need to include both
  docassemble.base.legal and docassemble.base.util together in the
  same "modules" block.
---
default role: client
code: |
  if user_logged_in() and user_has_privilege('advocate'):
    user = advocate
    role = 'advocate'
  else:
    user = client
    role = 'client'
  set_info(user=user, role=role)
comment: |
  This is a special "initial block" that initializes the "roles" system
  for the interview.  (This is an advanced feature.)
  
  The default user role is "client" and a secondary role is
  "advocate."  Unless modified with a "role" directive, all questions
  will require the user to be a "client."  The user is assumed to have
  the role of "advocate" role in this interview if the user is logged
  in and the user has "advocate" as one of his or her user roles.

  Many docassemble functions and methods need to know who the user is.
  The set_info() function communicates that information to the
  docassemble code.

  Since the code here is paired with the "default role" declaration,
  it is run as "initial" code, meaning that it is run every time
  docassemble processes the interview (i.e., every time the screen
  loads).  This is important because in a multi-user interview, a
  "client" and an "advocate" could be interacting with the same
  interview with the same dictionary of variables at the same time.
  But they would need to see different things, so it isn't enough just
  to use a variable in the interview to keep track of the current
  user; this needs to be reconsidered every time the screen loads.
---
event: role_event
question: You are done for now.
subquestion: |
  % if 'advocate' in role_needed:
    An advocate needs to review your answers before you can proceed.

    Please remember the following link and come back to it when you
    receive notice to do so:

    [${ interview_url() }](${ interview_url() })
    
  % else:
    Thanks, the client needs to resume the interview now.
  % endif
decoration: exit
buttons:
  - Exit: leave
comment: |
  This block is related to the "roles" system that was initialized in
  the previous block.  (This is an advanced feature.)

  When docassemble needs to ask a question that requires a role other
  than the role of the current user, it needs to display a special
  message for the user.  It does this by searching for a question that
  offers to define the variable "role_event," and displaying that
  question.  The question above is an example of such a question.  It
  will be displayed in the event of a "role change" because it
  contains the directive "event: role_event."
---
objects:
  - case: Case
  - client: Individual
  - spouse: Individual
  - advocate: Individual
  - pleading: LegalFiling
  - court: Court
comment: |
  An "objects" section initializes variables that are docassemble
  objects.  The object types here (Case, Individual, LegalFiling, and
  Court) are imported through the docassemble.base.legal module.
  (See the "modules" block above.)
---
mandatory: true
code: |
  case.court = court
  pleading.case = case
comment: |
  This code defines some basic relations among the objects created in
  the objects block of this YAML file.

  The objects created by the `objects` block do not have any
  connections among themselves, initially.  The interview needs to
  make those connections.  This "mandatory" code block establishes
  those connections.

  These connections among objects are what allows you to write things
  like pleading.caption().  In order to write the caption for a
  pleading, it is necessary to know the case of which the pleading is
  a part and the court in which the case is filed.  The ".caption()"
  method only has access to the attributes of "pleading," but these
  connections allow the ".caption()" method to gain access to the case
  and the court.
---
image sets:
  freepik:
    attribution: |
      Icon made by [Freepik](http://www.flaticon.com/authors/freepik)
    images:
      bills: money146.svg
      children: children2.svg
      finishline: checkered12.svg
      gavel: court.svg
      gaveljudge: magistrate.svg
      home: home168.svg
      piggybank: savings1.svg
      scalesofjustice: judge1.svg
      stocks: increasing10.svg
      wallet: commerce.svg
      document: contract11.svg
      calendar: calendar146.svg
      picture: picture64.svg
      parentchild: man32.svg
      coins: coins36.svg
      exit: open203.svg
      man: silhouette21.svg
      person: silhouette21.svg
      woman: women13.svg
      girl: girl4.svg
      male: male244.svg
      female: female243.svg
      map: map32.svg
comment: |
  Here we define some icons for inclusion as decorations or emoji.
  These files are located in the docassemble.base package in the
  subdirectory docassemble/base/data/static.
---
generic object: Individual
question: |
  What is ${ x.possessive('date of birth') }?
fields:
  - Date of Birth: x.birthdate
    datatype: date
comment: |
  This question file defines a number of "generic" questions like
  these.  If your interview refers to a variable called user.birthdate,
  docassemble will first look for a question that sets "user.birthdate"
  specifically, but if it does not find it, it will look for a
  question for which the generic object property is set to the object
  type of the user object, which is Individual, and where the question
  offers to set the variable x.birthdate.
  
  It will find that question here.

  The question uses the possessive() method, which is a method of the
  Individual class.  The result is that the question will be "What is
  your date of birth?" if x is the user, but will otherwise ask "What
  is Jane Doe's date of birth?"

  By using "generic" questions, you can write a single question that
  works in a variety of circumstances.  This saves you from having to
  write multiple questions, and also helps ensure that if you want to
  make a global change to the way a question is asked, you can do so
  in one place.

  If you ever want to use a more specific question for a specific
  variable, you can.  For example, if your code calls for
  spouse.birthdate, you may to ask the question in a different way.
  (E.g., "What is the birthdate of your lovely spouse?  If you don't
  know this, you are in deep trouble!")  You would do this by defining
  a non-generic question that sets spouse.birthdate, in which case
  docassemble would use that question instead of the generic question.
---
generic object: Individual
question: |
  What is ${ x.possessive('time zone') }?
fields:
  - Time Zone: x.timezone
    code: timezone_list()
---
generic object: Individual
question: |
  What is ${ x.possessive('Social Security Number') }?
fields:
  - Social Security Number: x.ssn
---
generic object: Individual
question: |
  ${ x.is_are_you(capitalize=True) } a defendant in this case?
yesno: x.is_defendant
---
generic object: Individual
field: x.marital_status
question: |
  What is ${ x.possessive('marital status') }?
choices:
  - Married: Married
  - Single: Single
  - Divorced: Divorced
  - Separated: Separated
comment: |
  This is an example of a multiple-choice question.  Each of the
  choices can be a key/value pair, or it can be a single text item.
  If the choice is a key/value pair, the key is the label that is
  shown to the user and value is the value to which the variable will
  be set.
---
field: user_understands_how_to_use_signature_feature
question: Instructions for signing your name
subquestion: |
  On the next screen, you will see a box in which you can sign your
  name using your mouse, track pad, or touch screen.  If you make a
  mistake, you can press "Clear" and try again.  For best results, try
  signing your name *slowly*.
---
generic object: Individual
question: |
  Please sign your name below.
signature: x.signature
need:
  - x.name.first
  - user_understands_how_to_use_signature_feature
under: |
  ${ x.name }
comment: |
  docassemble can collect signatures from users, who can write their
  signature with their finger on a touchscreen device, or use a mouse
  or trackpad.  The signatures can be added to documents.
---
template: blank_signature
content: |
  \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
comment: |
  This template can be used to insert into a document a blank line
  that someone might sign.
---
template: empty_signature
content: |
  \_\_\_[Your signature here]\_\_\_
comment: |
  This template can be used in place of a user's signature.  It is a
  good practice to show users where their signature would go on a
  document before asking the user for his or her signature.
---
generic object: Individual
question: |
  Is this ${ x.possessive('signature') }?
subquestion: |
  ${ x.signature.show() }
buttons:
  - "Yes":
      generic object: Individual
      code: |
        x.signature_verified = True
  - "No":
      generic object: Individual
      code: |
        x.signature_verified = False
  - "Let me try again":
      generic object: Individual
      code: |
        force_ask('x.signature')
comment: |
  This is an example of a multiple choice question where selecting an
  option causes code to be run.  Each multiple choice option contains
  an embedded block.
  
  Note that in order for an "embedded" code or question block to use
  the special variable "x," you need to declare a generic object
  within the embedded code or question.
---
generic object: Individual
question: |
  ${ x.is_are_you(capitalize=True) } a citizen of the United States?
yesno: x.is_citizen
---
field: user_understands_no_attorney_client_relationship
question: |
  Your use of this system does not mean that you have a lawyer.  Do
  you understand this?
buttons:
  - "I understand": understands
  - code: |
      [{'does not understand':"I do not understand"}, {'unsure':"I'm not sure"}]
comment: |
  You can specify whether you want multiple choices to appear as
  buttons by using the word "buttons" instead of the word "choices."

  Also, the example above shows how you can use Python code to
  generate the selections of multiple-choice question.  The code is
  evaluated at the time the question is asked.
---
generic object: Individual
question: |
  What is ${ x.possessive('e-mail address') }?
fields:
  - E-mail: x.email
    datatype: email
comment: |
  The datatype "email" presents a text box that is like ordinary text
  boxes except that validation is applied that checks to make sure the
  e-mail address is valid.  Also, on supporting mobile web browsers,
  there is a different keyboard option (e.g, the @ sign is readily
  available).
---
generic object: Individual
question: |
  What is ${ x.possessive('gender') }?
field: x.gender
choices:
  - Male: male
  - Female: female
  - Other: other
---
generic object: Individual
question: |
  What is ${ x.object_possessive('name') }?
fields:
  - First Name: x.name.first
    default: ${ x.first_name_hint() }
  - Middle Name: x.name.middle
    required: False
  - Last Name: x.name.last
    default: ${ x.last_name_hint() }
  - Suffix: x.name.suffix
    required: False
    code: |
      name_suffix()
comment: |
  If an object does not have a name yet, generic questions can refer
  to it by the name of the variable itself, using the method
  .object_possessive().  For example, suppose you create an object,
  case.judge, with the class of Individual.  If the name of case.judge
  is ever needed, docassemble will use the question above to ask "What
  is the name of the judge in the case?"  If the object is called
  user, it will ask "What is your name?"  If the object is called
  village_idiot, it will ask "What is the village idiot's name?"
---
generic list object: Individual
question: |
  What is the name of the ${ x[i].object_name() }?
fields:
  - First Name: x[i].name.first
  - Middle Name: x[i].name.middle
    required: False
  - Last Name: x[i].name.last
  - Suffix: x[i].name.suffix
    required: False
    code: |
      name_suffix()
comment: |
  Generic questions can also use indices, for example to fill out the
  names of a list of people.  (E.g., case.plaintiff.)

  This example also illustrates how the author can control whether the
  user can leave a field blank.  By default, all fields are required,
  but the author can add required: False to a field to indicate that
  the field can be left blank.
---
generic list object: Individual
question: |
  What is ${ x.possessive(ordinal(i) + " child") }'s name?
fields:
  - Somebody already mentioned: x.child[i]
    datatype: object
    disable others: True
    choices: case.all_known_people()
    exclude:
      - x
      - x.child
  - First Name: x.child[i].name.first
  - Middle Name: x.child[i].name.middle
    required: False
  - Last Name: x.child[i].name.last
    default: ${ x.name.last }
  - Suffix: x.child[i].name.suffix
    required: False
    code: |
      name_suffix()
comment: |
  This illustrates the use of the ".possessive()" method of the class
  Individual.  Depending on who x is, this question will ask different
  things:

  Example 1: What is your second child's name?

  Example 2: What is John Doe's first child's name?
---
generic object: DAList
question: |
  Are there any ${ x.as_noun(plural=True) }?
yesno: x.there_are_any
comment: |
  The attributes .there_are_any and .there_is_another are special
  attributes that are used in the gathering of "groups" of things
  in docassemble interviews.
---
generic object: Individual
question: |
  ${ x.do_question('have', capitalize=True) } any children?
yesno: x.child.there_are_any
decoration: children
comment: |
  This illustrates the use of the ".do_question()" method of the class
  Individual.  Depending on who x is, this question will ask different
  things:

  Example 1: Do you have any children?

  Example 2: Does Jane Doe have any children?
---
generic object: DAList
question: |
  You have told me that there ${ x.does_verb("is") }
  ${ x.number_as_word() } ${ x.as_noun() }, ${ x }.
  Is there another ${ x.as_singular_noun() }?
yesno: x.there_is_another
comment: |
  It is possible to write highly generalized "generic" questions that
  use functions that ask questions of users based on variable names
  and linguistic variations of variable names.  For that reason, it is
  a good practice to give your variables meaningful, plain-English
  names.

  For example, if you create a PartyList called "plaintiff," this
  generic question will ask something like: "You have told me that
  there is one plaintiff, John Smith.  Is there another plaintiff?"
  This would not be possible if your variable name was something that
  only made sense to you, like "bad_guys_list_two."
---
generic object: Individual
question: |
  So far, you have told me about
  ${ x.possessive(x.child.number_as_word()) }
  ${ x.child.as_noun() }, ${ x.child }.
  ${ x.do_question('have', capitalize=True) } any other children?
yesno: x.child.there_is_another
decoration: children
comment: |
  This also illustrates the use of various methods of the class Individual.
  Depending on who x is, this question will ask different things:

  Example 1: So far, you have told me about John Doe's two children, 
  Sally Doe and Harold Doe.  Does John Doe have any other children?

  Example 2: So far, you have told me about your one child, Kathleen 
  Smith.  Do you have any other children?
---
generic object: Individual
question: |
  ${ x.is_are_you(capitalize=True) } a plaintiff in this case?
subquestion: |
  A "plaintiff" is a person who starts a case by filing a lawsuit
  against a person called a "defendant."  Plaintiffs and defendants
  are the "parties" in a case.
decoration: scalesofjustice
yesno: x.is_plaintiff
---
generic object: Individual
question: |
  Where ${ x.do_question('live') } in ${ case.state }?
fields:
  - Address: x.address.address
  - Unit: x.address.unit
    required: False
    help: The apartment, suite, or unit number of the residence.
  - City: x.address.city
  - State: x.address.state
    default: 
      code: |
        case.state
    code: |
      us.states.mapping('abbr', 'name')
  - Zip: x.address.zip
    required: False
---
generic object: Address
question: |
  In which county is
  ${ x.on_one_line() }
  located?
fields:
  - County: x.county
---
generic object: Address
sets: x.county
code: |
  x.geolocate()
comment: |
  This code block and the question before it illustrate the concept
  of "fallback" questions.  If the interview needs the "county"
  attribute of an address, but finds that it is not defined, it will
  first run this code block, which "geolocates" the address.  That is,
  it goes on to the internet and runs the address through a
  geolocation service, which returns geographic information about the
  address.

  This code block uses the "sets" directive to indicate that the code
  block offers sets the attribute "county."  Normally, you don't have
  to use "sets" with code blocks because docassemble can see by
  looking at the code what variables the code will set.  In the case
  of the code "x.geolocate()," however, it is not apparent that the
  code is offering to set the "county" attribute.  Therefore we need
  to manually specify what the code block is offering to do.

  It is significant that the code block merely "offers" to set these
  variables.  The "x.geolocate()" code might fail.  The user might put
  in an address that the geolocation service does not understand.  Or
  the geolocation service might be down at the time.  If that happens,
  the code block will run, but the attributes will not be set.

  If the variable that a code block offers to set is not actually set
  when the code is run, docassemble will look for another block that
  offers to set the variables.  In the case of the "county" attribute
  of an address, the question immediately preceding this one offers to
  set the "county" attribute.  It does so by asking the user a
  question, rather than by using a geolocation service.  This question
  serves as a "fallback" question.

  Note that when docassemble looks for a block that offers to set a
  variable, it starts at the end of the interview and proceeds
  backward.  Therefore, the order in which these blocks appear in
  the [YAML] file is significant.
---
generic object: City
question: |
  In which county in
  ${ state_name(x.state) }
  is
  ${ x.city }
  located?
fields:
  - County: x.county
    hint: |
      e.g., Springfield County
---
generic object: City
sets: x.county
code: |
  x.geolocate()
comment: |

  Suppose you have an object "birthplace" of type "City."  A "City"
  object is a subtype of an "Address," and an "Address" is a type of
  "DAObject."  If your interview needs a definition of
  birthplace.county, docassemble will first look for blocks that offer
  to define "birthplace.county," then for "generic object: City"
  blocks that offer to define "x.county," then for "generic object:
  Address" blocks that offer to define "x.county," then for "generic
  object: DAObject" blocks that offer to define "x.county."

  Therefore, the "generic object: Address" code block is capable of
  defining "birthplace.county."  However, if we wish to have a
  fallback question that is "City"-specific, and we tag it with
  "generic object: City," this question will take priority over the
  "generic object: Address" code block.

  Therefore, in order to have a "City"-specific fallback question, we
  also need a "City"-specific code block.
---
generic object: Document
question: |
  Are you able to attach or take a picture of ${ x.title }?
yesno: x.able_to_attach
---
generic object: Document
question: |
  Please attach or take a picture of ${ x.title }.
fields:
  - label: |
      ${ capitalize(x.title) }
    field: x.file
    datatype: file
comment: |
  These two questions facilitate using the "Document" object type to
  gather uploaded documents if the user is able to upload the document.
---
generic object: Individual
question: |
  In what country ${ x.do_question('live') }?
fields:
  - Country: x.address.country
---
generic object: Individual
question: |
  In what neighborhood ${ x.do_question('live') }?
fields:
  - Neighborhood: x.address.neighborhood
---
generic object: Individual
question: |
  In what county ${ x.do_question('live') }?
fields:
  - County: x.address.county
---
generic object: Address
sets:
  - x.county
  - x.country
  - x.neighborhood
code: |
  x.geolocate()
comment: |
...