EXTJS-like data-driven Hobo example using domain model from Hobo book

Note: Here I am using a tweaked version of Hobo (by Brett), which
allows outputting default params (body) with a comma between the
rendering of each param. The skip-whitespace should discard any param
rendering which results in whitespace only (or remove repeating ","
with only whitespace between them in this example).

Could you please comment whether I am using the right DRYML approach
here :)
What should I do differently or could be improved? How do I correctly
use polymorphism?

Thanks!

PS: Maybe this example (when completed), could be used as an advanced
DRYML example in the Hobo book ;)

<def comma>
  <do param="default" separator="," skip-whitespace/>
</def>

Model
----------------

Recipe
 - name
 - description

 - has_many :ingredients

can_edit?
  user == owner

Ingredient
 - name
 - description

- belongs_to :recipe

Index.dryml for Recipe:

Window
 - Panel (show all)
  - Panel (recipe)
    - panel details
    -  ingredient.each do |ingredient|
      - Panel (ingredient)
      - Form (ingredient)
    - end
    - action buttons (recipe)
    - Form (recipe)

  - Panel (recipe)
    - panel details
    -  ingredient.each do |ingredient|
      - Panel (ingredient)
      - Form (ingredient)
    - end
    - action buttons (recipe)
  - Form (recipe)

 - action buttons (recipes)

-------------
Data example:

- Pancake
  - round, crispy
  - Milk
    - white, liquid

- Toast
  - Bread
    - crispy

user owns Pancake, but NOT Toast
----

Should generates something like:

Window('Recipes window') : {
  Panel('Recipes panel') : {
    Panel('Pancake') : {
       desc: 'crispy, sweet'
      ,Panel('Milk panel') {
        desc: 'white, liquid'
        # no footerbar, only admin can edit ingredients
      }
      # user OWNS this recipe so can edit it!
      ,footerBar : {
         buttons : [
           {'Add ingredient'}
          ,{'Edit pancake'}   -> show form inside panel?
          ,{'Remove pancake'}
         ]
      }
    }.collapsed()

    ,Form('Pancake form') : {
       text-field('text, 'pancake' - name)
      ,html-field('text, 'crispy, sweet' - description)
      ,buttons : [{'submit'}] -> ajax update, hide form
    }.hide()

    ,Panel('Toast panel') : {
       desc: 'crispy'
      ,Panel('Bread panel') {
        desc: 'crispy'
        # no footerbar, only admin can edit ingredients
      }
      # no footerBar since user doesn't OWN this recipe!
    }.collapsed()

    ,Form('Toast form') : {
       text-field('text, 'toast' - name)
      ,html-field('text, 'crispy' - desc)
      ,buttons : [{'submit'}] -> ajax update, hide form
    }.hide()

    # footer for actions on list of recipes
    ,footerBar : {
       buttons : [{'Add new Recipe'}]
      ,buttons : [{'Show all'}]
    }
  }
}

<page name="index">
  ...
  <window: title="Recipes window"/>
</page>


<def name="window" attrs="title">
  <!-- iterate recipes (this) -->
  <collection:>
    <comma>
      <do-model/>
    </comma>
  </collection>
  <!-- button action bar -->
  <footer:>
</window>

<def name="do-model">
  <!-- create panel (polymorphic) -->
  <panel:/>
  <!-- create form (polymorphic) -->

  <!-- only if user allowed to edit this model -->
  <if test="can_edit?">
    <form:>
  </if>
</def>

<def name="footer" for="Recipe">
  footerBar: {
    buttons: {
      <comma>
        <!-- add ingredient to recipe -->
        <button action="create" obj="&ingredient"/>
        <button action="delete"/>
      </comma>
    }
  }
</def>

<def name="create-button" attrs="obj, name">
  <if test="can_create?(obj)">
    <button action="create" name="&obj.try.origin_attribute"/>
  </if>
</def>

<def name="delete-button" attrs="obj, name">
  <if test="can_delete?(obj)">
    <button action="delete" name="&obj.try.origin_attribute"/>
  </if>
</def>

<!-- delete this recipe -->

<def name="panel" for="Recipe">
  <!-- call ext-panel using values from recipe instance -->
  <ext-panel title="&name">
    <desc field="desc"/>
  </ext-panel>
</def>

<def name="ext-panel" attrs="title">
  Panel('<%= title %> panel') : {
    <comma>
      <do-attributes />
      <!-- sub-panels (fx for recipe-ingredients) -->
      <do-model:>
      <!-- button action bar -->
      <footer:>
    </comma>
  }.collapsed()
</def>

<def name="form" for="Recipe">
  <ext-form title="&name" with-fields="name, desc">
  </ext-form>
</def>

<def name="ext-form" attrs="title, with-fields">
  <!-- make input field for each attribute -->
  Form('<%= title %> form') {
    <comma>
      .. fields here
    </comma>
  }.hide()
</def>


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Hobo 
Users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/hobousers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to