You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by mf...@redhat.com on 2010/12/09 15:40:31 UTC

[PATCH core 2/6] Added xml_tag_for_* helpers for safe XML tag generation in HAML

From: Michal Fojtik <mf...@redhat.com>

---
 .../lib/deltacloud/helpers/application_helper.rb   |  143 ++++++++++++++++++++
 server/views/buckets/index.xml.haml                |   10 +-
 server/views/buckets/show.xml.haml                 |   13 +-
 server/views/hardware_profiles/index.xml.haml      |    4 +-
 server/views/hardware_profiles/show.xml.haml       |    7 +-
 server/views/images/index.xml.haml                 |   12 +--
 server/views/images/show.xml.haml                  |   11 +-
 server/views/instances/index.xml.haml              |   23 +---
 server/views/instances/show.xml.haml               |   58 +++------
 server/views/keys/index.xml.haml                   |    4 +-
 server/views/keys/show.xml.haml                    |   23 +--
 server/views/load_balancers/index.xml.haml         |    5 +-
 server/views/load_balancers/show.html.haml         |    2 +-
 server/views/load_balancers/show.xml.haml          |   27 ++---
 server/views/realms/index.xml.haml                 |   10 +-
 server/views/realms/show.xml.haml                  |   12 +-
 server/views/storage_snapshots/show.xml.haml       |    5 +-
 server/views/storage_volumes/index.xml.haml        |   13 +--
 server/views/storage_volumes/show.xml.haml         |   13 +-
 19 files changed, 228 insertions(+), 167 deletions(-)

diff --git a/server/lib/deltacloud/helpers/application_helper.rb b/server/lib/deltacloud/helpers/application_helper.rb
index 56815e3..dea50c6 100644
--- a/server/lib/deltacloud/helpers/application_helper.rb
+++ b/server/lib/deltacloud/helpers/application_helper.rb
@@ -142,4 +142,147 @@ module ApplicationHelper
     end
   end
 
+  # Method will produce a XML tag with value of attribute from given object
+  # Object and attribute should be both supplied as a Symbol 
+  #
+  # Example syntax:
+  # = xml_tag_for :instance, :owner_id
+  # 
+  # Will produce:
+  # <owner_id>self</owner_id>
+  # 
+  # You can pass additional parameters to XML tag using:
+  # = xml_tag_for :instance, :owner_id, :params => { :id => 123 }
+  # 
+  # You can also wrap text value using CDATA writing:
+  # = xml_tag_for :instance, :name, :cdata => true
+  #
+  # There is also possibility to overide tag name using:
+  #
+  # = xml_tag_for :instance, :hardware_profile, :tag_name => :profile
+  #
+  # And finally you can create an 'empty' tag using:
+  #
+  # = xml_tag_for :instance, :hardware_profile, :empty => true, :params => {}
+  #
+  def xml_tag_for(object, attribute, options={}, &block)
+    instance_variable_set("@#{object}", @element) if not defined?("@#{object}")
+    @element = instance_variable_get("@#{object}") if not defined?(@element)
+    return if @element.nil?
+    return if @element.send(:"#{attribute}").nil?
+    capture_haml do
+      haml_tag :"#{options[:tag_name] || attribute}", :"<", options[:params] do
+        if options[:cdata]
+          haml_concat "<![CDATA[#{@element.send(:"#{attribute}")}]]>"
+        elsif not options[:empty]
+          haml_concat @element.send(:"#{attribute}")
+        end
+        block.call if block_given?
+      end
+    end
+  end
+
+  # Will produce a REST link to give resource which is assigned to given object.
+  # This tag will have no value (empty tag).
+  # 
+  # Example syntax:
+  # = xml_tag_for_resource :instance, :image
+  #
+  # You can overide 'href' and 'rel' using:
+  # = xml_tag_for_resource :instance, :image, :href => "..", :rel => "..."
+  #
+  # 
+  def xml_tag_for_resource(object, resource, options={}, &block)
+    instance_variable_set("@#{object}", @element) if not defined?("@#{object}")
+    @element = instance_variable_get("@#{object}") if not defined?(@element)
+    resource_id = @element.send(:"#{resource}_id")
+    xml_tag_for(object, :"#{resource}_id", {
+      :empty => true,
+      :tag_name => options[:tag_name] || resource,
+      :params => {
+        :href => options[:href] || self.send(:"#{resource}_url", resource_id),
+        :id => resource_id,
+        :rel => options[:rel] || resource
+      }
+    }, &block)
+  end
+
+  # This will create an XML tag for action for given object
+  #
+  # Example syntax:
+  #
+  # = xml_tag_for_action :instance, :start
+  # => <link rel="start" method="post" href="..." />
+  #
+  # You can overide default :method and :href here passing those as arguments
+  #
+  def xml_tag_for_action(object, action, options={}, &block)
+    instance_variable_set("@#{object}", @element) if not defined?("@#{object}")
+    @element = instance_variable_get("@#{object}") if not defined?(@element)
+    resource_id = @element.send(:id)
+    xml_tag_for(object, :id, {
+      :empty => true,
+      :tag_name => :link,
+      :params => {
+        :method => options[:method] || self.send(:"#{object.to_s.singularize}_action_method", action),
+        :href => self.send(:"#{action}_#{object.to_s.singularize}_url", resource_id),
+        :rel => action
+      }
+    })
+  end
+
+  # This will create a XML collection, eg. for public_addresses...
+  #
+  # Example syntax:
+  #
+  # = xml_tag_for_array :instance, :public_addresses, :address
+  # => 
+  # <public_addresses>
+  #  <address>123.0.0.1</address>
+  # </public_addresses>
+  #
+  # You can pass a block to this helper if you want to customize subset like:
+  #
+  #  = xml_tag_for_array :instance, :public_addresses, :address do |address|
+  #    %address{ :id => '123'}
+  #     =address
+  #
+  def xml_tag_for_array(object, collection, element, options={}, &block)
+    instance_variable_set("@#{object}", @element) if not defined?("@#{object}")
+    @element = instance_variable_get("@#{object}") if not defined?(@element)
+    return if @element.nil?
+    return if @element.send(:"#{collection}").nil? 
+    items = @element.send(:"#{collection}")
+    return if items.empty? 
+    capture_haml do
+      haml_tag :"#{collection}", :"<", options[:params] do
+        items.each do |item|
+          if block_given?
+            block.call(item)
+          else
+            haml_tag :"#{element}", :"<" do
+              haml_concat item
+            end
+          end
+        end
+      end
+    end
+  end
+
+  # This helper should replace our way how we handle rendering a collection
+  # in :index actions. 
+  #
+  # So instead of writing @elements.each do |item| ... haml(...)
+  # You can use just:
+  #
+  # - render_collection @elements, :image do |item|
+  #   = image
+  #
+  def render_collection(items, name, &block)
+    items.each do |@element|
+      instance_variable_set("@#{name}", @element)
+      yield haml( :"#{name.to_s.pluralize}/show", { :locals => { :partial => true } })
+    end
+  end
+
 end
diff --git a/server/views/buckets/index.xml.haml b/server/views/buckets/index.xml.haml
index d3b113e..ca69643 100644
--- a/server/views/buckets/index.xml.haml
+++ b/server/views/buckets/index.xml.haml
@@ -1,10 +1,4 @@
 !!! XML
 %buckets
-  - @elements.each do |bucket|
-    %bucket{:href => bucket_url(bucket.id), :id => bucket.id}
-      - bucket.attributes.select{ |attr| attr!=:id }.each do |attribute|
-        - unless attribute == :blob_list
-          - haml_tag("#{attribute}".tr('-', '_'), :<) do
-            - haml_concat bucket.send(attribute)
-      - bucket.blob_list.each do |blb|
-        %blob{ :id => blb, :href => bucket_url(bucket.id) +"/#{blb}", :rel => "blob"}
+  - render_collection(@elements, :bucket) do |item|
+    = item
diff --git a/server/views/buckets/show.xml.haml b/server/views/buckets/show.xml.haml
index 166fa60..7004ee0 100644
--- a/server/views/buckets/show.xml.haml
+++ b/server/views/buckets/show.xml.haml
@@ -1,8 +1,7 @@
-!!! XML
+- unless defined?(partial)
+  !!! XML
 %bucket{:href => bucket_url(@bucket.id), :id => @bucket.id}
-  - @bucket.attributes.select{ |attr| attr!=:id }.each do |attribute|
-    - unless attribute == :blob_list
-      -haml_tag(attribute, :<) do
-        - haml_concat @bucket.send(attribute)
-  - @bucket.blob_list.each do |blb|
-    %blob{:id => blb, :href => bucket_url(@bucket.id) +"/#{blb}", :rel => "blob"}
+  = xml_tag_for :bucket, :name, :cdata => true
+  = xml_tag_for :bucket, :size
+  = xml_tag_for_array :bucket, :blob_list, :blob do |blob|
+    %blob{:id => blob, :href => url_for(bucket_url(@bucket.id)+"/#{blob}"), :rel => "blob"}
diff --git a/server/views/hardware_profiles/index.xml.haml b/server/views/hardware_profiles/index.xml.haml
index cf0a69f..f57d86f 100644
--- a/server/views/hardware_profiles/index.xml.haml
+++ b/server/views/hardware_profiles/index.xml.haml
@@ -1,4 +1,4 @@
 !!! XML
 %hardware_profiles
-  - @profiles.each do |prof|
-    = haml :'hardware_profiles/show', :locals => { :@profile => prof, :partial => true }
+  - render_collection(@elements, :hardware_profile) do |item|
+    = item
diff --git a/server/views/hardware_profiles/show.xml.haml b/server/views/hardware_profiles/show.xml.haml
index 094ffd5..5af4d5e 100644
--- a/server/views/hardware_profiles/show.xml.haml
+++ b/server/views/hardware_profiles/show.xml.haml
@@ -1,9 +1,8 @@
 - unless defined?(partial)
   !!! XML
-%hardware_profile{ :href => hardware_profile_url(@profile.name), :id => @profile.name }
-  %name<
-    =@profile.name
-  - @profile.each_property do |prop|
+%hardware_profile{ :href => hardware_profile_url(@hardware_profile.name), :id => @hardware_profile.name }
+  = xml_tag_for :hardware_profile, :name
+  - @hardware_profile.each_property do |prop|
     - attr = { :name => prop.name, :kind => prop.kind, :unit => prop.unit }
     - if prop.kind == :fixed
       %property{ attr, :value => prop.value }/
diff --git a/server/views/images/index.xml.haml b/server/views/images/index.xml.haml
index 732769f..0744a9f 100644
--- a/server/views/images/index.xml.haml
+++ b/server/views/images/index.xml.haml
@@ -1,12 +1,4 @@
 !!! XML
 %images
-  - @elements.each do |image|
-    %image{:href => image_url(image.id), :id => image.id}
-      - image.attributes.select{ |attr| attr!=:id }.each do |attribute|
-        - haml_tag("#{attribute}".tr('-', '_'), :<) do
-          - if [:name, :description].include?(attribute)
-            =cdata do
-              - haml_concat image.send(attribute)
-          - else
-            - haml_concat image.send(attribute)
-
+  - render_collection(@elements, :image) do |item|
+    = item
diff --git a/server/views/images/show.xml.haml b/server/views/images/show.xml.haml
index c3e2cc4..2817288 100644
--- a/server/views/images/show.xml.haml
+++ b/server/views/images/show.xml.haml
@@ -1,5 +1,8 @@
-!!! XML
+- unless defined?(partial)
+  !!! XML
 %image{:href => image_url(@image.id), :id => @image.id}
-  - @image.attributes.select{ |attr| attr!=:id }.each do |attribute|
-    - haml_tag(attribute, :<) do
-      - haml_concat @image.send(attribute)
+  = xml_tag_for :image, :name, :cdata => true
+  = xml_tag_for :image, :description, :cdata => true
+  = xml_tag_for :image, :owner_id
+  = xml_tag_for :image, :architecture
+  = xml_tag_for :image, :state
diff --git a/server/views/instances/index.xml.haml b/server/views/instances/index.xml.haml
index e8353ec..d1801a9 100644
--- a/server/views/instances/index.xml.haml
+++ b/server/views/instances/index.xml.haml
@@ -1,21 +1,4 @@
-!!! XML
+!!!XML
 %instances
-  - @elements.each do |instance|
-    %instance{:href => instance_url(instance.id), :id => instance.id}
-      %name #{instance.name}
-      %owner_id #{instance.owner_id}
-      %image{:href => image_url(instance.image_id), :id => instance.image_id, :rel => "image" }
-      %realm{:href => realm_url(instance.realm_id), :id => instance.realm_id, :rel => "realm" }
-      %state #{instance.state}
-      - haml_tag :"hardware_profile", { :id => instance.instance_profile.id, :href => hardware_profile_url(instance.instance_profile.id), :rel => "hardware_profile"} do
-        - instance.instance_profile.overrides.each do |p, v|
-          %property{:kind => 'fixed', :name => p, :value => v, :unit => Deltacloud::HardwareProfile::unit(p)}
-      %actions
-        - instance.actions.compact.each do |action|
-          %link{:rel => action, :href => self.send("#{action}_instance_url", instance.id), :method => instance_action_method(action)}
-      %public_addresses
-        - instance.public_addresses.each do |address|
-          %address  #{address}
-      %private_addresses
-        - instance.private_addresses.each do |address|
-          %address  #{address}
+  - render_collection(@elements, :instance) do |item|
+    = item
diff --git a/server/views/instances/show.xml.haml b/server/views/instances/show.xml.haml
index 866171a..341eb14 100644
--- a/server/views/instances/show.xml.haml
+++ b/server/views/instances/show.xml.haml
@@ -1,49 +1,29 @@
-!!! XML
+- unless defined?(partial)
+  !!! XML
 %instance{:href => instance_url(@instance.id), :id => @instance.id}
-  - if @instance.name
-    %name<
-      =@instance.name
-  - if @instance.owner_id
-    %owner_id<
-      =@instance.owner_id
-  - if @instance.image_id
-    %image{:href => image_url(@instance.image_id), :id => @instance.image_id, :rel => 'image' }
-  - if @instance.realm_id
-    %realm{:href => realm_url(@instance.realm_id), :id => @instance.realm_id, :rel => 'realm' }
-  - if @instance.state
-    %state<
-      =@instance.state
-  - if @instance.instance_profile
-    - haml_tag :"hardware_profile", {:id => @instance.instance_profile.id, :href => hardware_profile_url(@instance.instance_profile.id), :rel => "hardware_profile"} do
-      - @instance.instance_profile.overrides.each do |p, v|
-        %property{:kind => 'fixed', :name => p, :value => v, :unit => Deltacloud::HardwareProfile::unit(p)}
+  = xml_tag_for :instance, :name, :cdata => true
+  = xml_tag_for :instance, :owner_id
+  = xml_tag_for :instance, :state
+  = xml_tag_for :instance, :launch_time
+  = xml_tag_for_resource :instance, :image
+  = xml_tag_for_resource :instance, :realm
+  = xml_tag_for_resource :instance, :hardware_profile do
+    - @instance.instance_profile.overrides.each do |p, v|
+      %property{:kind => 'fixed', :name => p, :value => v, :unit => Deltacloud::HardwareProfile::unit(p)}
   - if @instance.actions
     %actions
       - @instance.actions.compact.each do |instance_action|
-        %link{:rel => instance_action, :method => instance_action_method(instance_action), :href => self.send("#{instance_action}_instance_url", @instance.id)}
-  - if @instance.instance_variables.include?("@launch_time")
-    %launch_time<
-      =@instance.launch_time
-  - if @instance.public_addresses
-    %public_addresses
-      - @instance.public_addresses.each do |address|
-        %address<
-          =address
-  - if @instance.private_addresses
-    %private_addresses
-      - @instance.private_addresses.each do |address|
-        %address<
-          =address
+        = xml_tag_for_action :instance, instance_action
+  = xml_tag_for_array :instance, :public_addresses, :address
+  = xml_tag_for_array :instance, :private_addresses, :address
   - if driver_has_auth_features?
     %authentication{ :type => driver_auth_feature_name }
-      - if @instance.authn_feature_failed?
-        %error  #{@instance.authn_error}
-      - else
+      =xml_tag_for(:instance, :authn_error, :tag_name => :error, :cdata => true) if @instance.authn_feature_failed?
+      - unless @instance.authn_feature_failed?
         - if driver_auth_feature_name == 'password'
           %login
-            %username #{@instance.username}
-            %password #{@instance.password}
+            =xml_tag_for :instance, :username, :cdata => true
+            =xml_tag_for :instance, :password, :cdata => true
         - if driver_auth_feature_name == 'key'
           %login
-            %keyname #{@instance.keyname}
-
+            =xml_tag_for :instance, :keyname, :cdata => true
diff --git a/server/views/keys/index.xml.haml b/server/views/keys/index.xml.haml
index 9256716..384e1b9 100644
--- a/server/views/keys/index.xml.haml
+++ b/server/views/keys/index.xml.haml
@@ -1,4 +1,4 @@
 !!!XML
 %keys
-  - @elements.each do |c|
-    = haml :'keys/show', :locals => { :@key => c, :partial => true }
+  - render_collection(@elements, :key) do |item|
+    = item
diff --git a/server/views/keys/show.xml.haml b/server/views/keys/show.xml.haml
index abb513b..784331a 100644
--- a/server/views/keys/show.xml.haml
+++ b/server/views/keys/show.xml.haml
@@ -1,21 +1,14 @@
 - unless defined?(partial)
   !!! XML
 %key{ :href => key_url(@key.id), :id => @key.id, :type => "#{@key.credential_type}" }
+  = xml_tag_for :key, :state
   %actions
-    - if driver.respond_to?(:destroy_key)
-      %link{ :rel => "destroy", :method => "delete", :href => destroy_key_url(@key.id)}
+    = xml_tag_for_action(:key, :destroy, :method => :delete) if driver.respond_to? :destroy_key
   - if @key.is_key?
-    %fingerprint<
-      =@key.fingerprint
-    - unless @key.pem_rsa_key.nil?
-      %pem
-        ~render_cdata(@key.pem_rsa_key)
+    = xml_tag_for :key, :fingerprint
+  - unless @key.pem_rsa_key.nil?
+    %pem
+      ~render_cdata(@key.pem_rsa_key)
   - if @key.is_password?
-    %username<
-      =cdata do
-        =@key.username
-    %password<
-      =cdata do
-        =@key.password
-  %state<
-    =@key.state
+    = xml_tag_for :key, :username, :cdata => true
+    = xml_tag_for :key, :password, :cdata => true
diff --git a/server/views/load_balancers/index.xml.haml b/server/views/load_balancers/index.xml.haml
index 22c6911..bc27840 100644
--- a/server/views/load_balancers/index.xml.haml
+++ b/server/views/load_balancers/index.xml.haml
@@ -1,5 +1,4 @@
-
 !!!XML
 %load_balancers
-  - @elements.each do |c|
-    = haml :'load_balancers/show', :locals => { :@load_balancer => c, :partial => true }
+  - render_collection @elements, :load_balancer do |item|
+    = item
diff --git a/server/views/load_balancers/show.html.haml b/server/views/load_balancers/show.html.haml
index 26e1766..074ec8c 100644
--- a/server/views/load_balancers/show.html.haml
+++ b/server/views/load_balancers/show.html.haml
@@ -25,7 +25,7 @@
       - @load_balancer.instances.each do |inst|
         %dd
           =inst.id
-          =link_to_action, 'Delete', unregister_load_balancer_url(@load_balancer.id, :instance_id => inst.id), :post
+          =link_to_action 'Delete', unregister_load_balancer_url(@load_balancer.id, :instance_id => inst.id), :post
 
 %form{:action => url_for("/api/load_balancers/#{@load_balancer.id}/register"), :method => :post}
   %p
diff --git a/server/views/load_balancers/show.xml.haml b/server/views/load_balancers/show.xml.haml
index 985770d..ce34860 100644
--- a/server/views/load_balancers/show.xml.haml
+++ b/server/views/load_balancers/show.xml.haml
@@ -1,21 +1,16 @@
 - unless defined?(partial)
   !!! XML
 %load_balancer{ :href => key_url(@load_balancer.id), :id => @load_balancer.id}
+  = xml_tag_for_array :load_balancer, :public_addresses, :address
+  = xml_tag_for :load_balancer, :created_at
+  = xml_tag_for_array :load_balancer, :realms, :realm do |realm|
+    %realm{ :href => realm_url(realm.id), :rel => "realm", :id => realm.id } 
+  = xml_tag_for_array :load_balancer, :listeners, :listener do |listener|
+    %listener{ :protocol => listener.protocol }
+      %load_balancer_port #{listener.load_balancer_port}
+      %instance_port #{listener.instance_port}
+  = xml_tag_for_array :load_balancer, :instances, :instance do |instance|
+    %instance{ :href => instance_url(instance.id), :id => instance.id, :rel => "instance" }
+      %link{:rel => "unregister", :href => unregister_load_balancer_url(@load_balancer.id, { :instance_id => instance.id})}
   %actions
     %link{ :rel => "destroy", :method => "delete", :href => destroy_load_balancer_url(@load_balancer.id)}
-  %public_addresses
-    - @load_balancer.public_addresses.each do |address|
-      %address #{address}
-  %created_at<
-    = @load_balancer.created_at
-  %realm{ :href => realm_url(@load_balancer.realms.first.id), :id => @load_balancer.realms.first.id}
-  %listeners
-    - @load_balancer.listeners.each do |listener|
-      %listener{ :protocol => listener.protocol}
-        %load_balancer_port #{listener.load_balancer_port}
-        %instance_port #{listener.instance_port}
-  %instances
-    - @load_balancer.instances.each do |instance|
-      %instance{:href => instance_url(instance.id), :id => instance.id, :rel => "instance"}
-        %link{:rel => "unregister", :href => unregister_load_balancer_url(@load_balancer.id, { :instance_id => instance.id})}
-
diff --git a/server/views/realms/index.xml.haml b/server/views/realms/index.xml.haml
index e67f282..6951982 100644
--- a/server/views/realms/index.xml.haml
+++ b/server/views/realms/index.xml.haml
@@ -1,10 +1,4 @@
 !!!XML
 %realms
-  - @elements.each do |realm|
-    %realm{:href => realm_url(realm.id), :id => realm.id }
-      %name<
-        =realm.name
-      %state<
-        =realm.state
-      %limit<
-        =realm.limit.eql?(:unlimited) ? '' : realm.limit
+  - render_collection(@elements, :realm) do |item|
+    = item
diff --git a/server/views/realms/show.xml.haml b/server/views/realms/show.xml.haml
index f53c46a..244732e 100644
--- a/server/views/realms/show.xml.haml
+++ b/server/views/realms/show.xml.haml
@@ -1,9 +1,7 @@
-!!!XML
+- unless defined?(partial)
+  !!! XML
 %realm{:href => realm_url(@realm.id), :id => @realm.id }
-  %name<
-    =@realm.name
-  %state<
-    =@realm.state
+  = xml_tag_for :realm, :name
+  = xml_tag_for :realm, :state
   - unless @realm.limit.eql?(:unlimited)
-    %limit<
-      =@realm.limit
+    = xml_tag_for :realm, :limit
diff --git a/server/views/storage_snapshots/show.xml.haml b/server/views/storage_snapshots/show.xml.haml
index 3cfa8a6..3821804 100644
--- a/server/views/storage_snapshots/show.xml.haml
+++ b/server/views/storage_snapshots/show.xml.haml
@@ -1,5 +1,4 @@
 !!!XML
 %storage_snapshot{:href => storage_snapshot_url(@storage_snapshot.id), :id => @storage_snapshot.id }
-  %created<
-    =@storage_snapshot.created
-  %storage_volume{:href => storage_volume_url(@storage_snapshot.storage_volume_id), :id => @storage_snapshot.storage_volume_id}
+  = xml_tag_for :storage_snapshot, :created
+  = xml_tag_for_resource :storage_snapshot, :storage_volume
diff --git a/server/views/storage_volumes/index.xml.haml b/server/views/storage_volumes/index.xml.haml
index 471169c..966cb74 100644
--- a/server/views/storage_volumes/index.xml.haml
+++ b/server/views/storage_volumes/index.xml.haml
@@ -1,13 +1,4 @@
 !!!XML
 %storage_volumes
-  - @elements.each do |volume|
-    %storage_volume{ :href => storage_volume_url(volume.id), :id => volume.id }
-      %created<
-        =volume.created
-      %capacity{ :unit => "GB" }<
-        = volume.capacity
-      - unless volume.instance_id.nil?
-        %mount
-          %instance{:href => instance_url(volume.instance_id), :id => volume.instance_id}
-          - unless volume.device.nil?
-            %device{ :name => volume.device }
+  - render_collection @elements, :storage_volume do |item|
+    = item
diff --git a/server/views/storage_volumes/show.xml.haml b/server/views/storage_volumes/show.xml.haml
index ebf1b24..551a6f1 100644
--- a/server/views/storage_volumes/show.xml.haml
+++ b/server/views/storage_volumes/show.xml.haml
@@ -1,11 +1,10 @@
-!!!XML
+- unless defined?(partial)
+  !!! XML
 %storage_volume{ :href => storage_volume_url(@storage_volume.id), :id => @storage_volume.id}
-  %created<
-    =@storage_volume.created
-  %capacity{ :unit => "GB" }<
-    = @storage_volume.capacity
+  = xml_tag_for :storage_volume, :created
+  = xml_tag_for :storage_volume, :capacity, :params => { :unit => "GB"}
   - unless @storage_volume.instance_id.nil?
     %mount
-      %instance{:href => @storage_volume.instance_id, :id => @storage_volume.instance_id}
+      = xml_tag_for_resource :storage_volume, :instance
       - unless @storage_volume.device.nil?
-        %device{ :name => @storage_volume.device }
+        = xml_tag_for :storage_volume, :device, { :empty => true, :params => { :name => @storage_volume.device }}
-- 
1.7.3.2