diff --git a/app/models/communication/block.rb b/app/models/communication/block.rb
index 44c0606c0271938743a4c88de0696603e007239c..27dc22dc0a35af7faa8ca4e4ef9074c60b03f9fa 100644
--- a/app/models/communication/block.rb
+++ b/app/models/communication/block.rb
@@ -62,14 +62,11 @@ class Communication::Block < ApplicationRecord
   after_commit :save_and_sync_about, on: [:update, :destroy]
 
   def data=(value)
-    # Symbol does not work (:data)
-    attributes['data'] = default_data
-    # Template data setter will write properly sanitized values to block data
-    template.data = value
+    attributes['data'] = template.parse(value).to_json
   end
 
   def data
-    attributes['data'] ||= default_data
+    template.to_json
   end
 
   def git_dependencies
@@ -91,12 +88,6 @@ class Communication::Block < ApplicationRecord
 
   protected
 
-  def default_data
-    {
-      'elements': []
-    }
-  end
-
   def attach_template_blobs
     self.template_images = template.active_storage_blobs
   end
diff --git a/app/models/communication/block/component/base.rb b/app/models/communication/block/component/base.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f27eeead107045c18a74e870fed2c6f0d705e369
--- /dev/null
+++ b/app/models/communication/block/component/base.rb
@@ -0,0 +1,20 @@
+class Communication::Block::Component::Base
+  attr_reader :property, :template
+
+  def initialize(property, template)
+    @property = property.to_s
+    @template = template
+  end
+
+  def value
+    data[property]
+  end
+
+  def value=(v)
+    data[property] = v
+  end
+
+  def data
+    template.data
+  end
+end
diff --git a/app/models/communication/block/component/rich_text.rb b/app/models/communication/block/component/rich_text.rb
new file mode 100644
index 0000000000000000000000000000000000000000..587c0b9464625f1f763a634031ec18afddb41c12
--- /dev/null
+++ b/app/models/communication/block/component/rich_text.rb
@@ -0,0 +1,2 @@
+class Communication::Block::Component::RichText < Communication::Block::Component::Base
+end
diff --git a/app/models/communication/block/template.rb b/app/models/communication/block/template/base.rb
similarity index 89%
rename from app/models/communication/block/template.rb
rename to app/models/communication/block/template/base.rb
index 0f3ba1c87db01546359bb0906e7f9e32edc10f91..59922847b7699ab8d4f41c8f8ef7d4c4bb5f679e 100644
--- a/app/models/communication/block/template.rb
+++ b/app/models/communication/block/template/base.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template
+class Communication::Block::Template::Base
   class_attribute :fields
 
   attr_reader :block
@@ -36,11 +36,11 @@ class Communication::Block::Template
     sanitizer_type = sanitizers[kind]
     class_eval <<-CODE, __FILE__, __LINE__ + 1
       def #{property}
-        #{ kind == :image ? "extract_image_alt_and_credit(data, '#{property}')" : "data['#{property}']" }
+        Communication::Block::Component::#{kind.classify}.new(property, self).value
       end
 
       def #{property}=(value)
-        data['#{property}'] = #{ sanitizer_type ? "Osuny::Sanitizer.sanitize(value, '#{sanitizer_type}')" : "value" }
+        Communication::Block::Component::#{kind.classify}.new(property, self).value = value
       end
     CODE
   end
@@ -73,6 +73,12 @@ class Communication::Block::Template
 
   protected
 
+  def default_data
+    {
+      'elements': []
+    }
+  end
+
   def update_field(field, json)
     name = field[:name]
     value = json["#{name}"]
diff --git a/app/models/communication/block/template/call_to_action.rb b/app/models/communication/block/template/call_to_action.rb
index 0bbdb6071d59135e6c50bc7cd6bb51e16cb378ce..4d82b798570c216394dfad3118c4c8437ee5a1fd 100644
--- a/app/models/communication/block/template/call_to_action.rb
+++ b/app/models/communication/block/template/call_to_action.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::CallToAction < Communication::Block::Template
+class Communication::Block::Template::CallToAction < Communication::Block::Template::Base
   def sanitized_data
     {
       "text" => Osuny::Sanitizer.sanitize(text),
diff --git a/app/models/communication/block/template/chapter.rb b/app/models/communication/block/template/chapter.rb
index d2e850c065b8b09ac68407a39536996fe16ffd99..a744759c10b7562d3b504926759b4b43b82c3605 100644
--- a/app/models/communication/block/template/chapter.rb
+++ b/app/models/communication/block/template/chapter.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Chapter < Communication::Block::Template
+class Communication::Block::Template::Chapter < Communication::Block::Template::Base
   has_rich_text :text
   has_rich_text :notes
   has_image :image
diff --git a/app/models/communication/block/template/datatable.rb b/app/models/communication/block/template/datatable.rb
index 6a764e8e1c88262b9f56d80585b4b937e4a92f38..579750d21f832a353b510161d432c324569914fe 100644
--- a/app/models/communication/block/template/datatable.rb
+++ b/app/models/communication/block/template/datatable.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Datatable < Communication::Block::Template
+class Communication::Block::Template::Datatable < Communication::Block::Template::Base
   def build_git_dependencies
   end
 end
diff --git a/app/models/communication/block/template/definition.rb b/app/models/communication/block/template/definition.rb
index 63b6777e510812789f30dd1c28c071ecb0eb46d9..2b9e596eee07563ac7d0280d3de34813897f45df 100644
--- a/app/models/communication/block/template/definition.rb
+++ b/app/models/communication/block/template/definition.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Definition < Communication::Block::Template
+class Communication::Block::Template::Definition < Communication::Block::Template::Base
   def definitions
     @definitions ||= elements.map { |element| definition(element) }
                               .compact
diff --git a/app/models/communication/block/template/embed.rb b/app/models/communication/block/template/embed.rb
index 69df3167241a8a68d6956848afe2006b281a8ea0..556f425af41a367a4c7a00e86fa99e5cd821cff5 100644
--- a/app/models/communication/block/template/embed.rb
+++ b/app/models/communication/block/template/embed.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Embed < Communication::Block::Template
+class Communication::Block::Template::Embed < Communication::Block::Template::Base
   def build_git_dependencies
   end
 
diff --git a/app/models/communication/block/template/file.rb b/app/models/communication/block/template/file.rb
index ad69e9defef42badfa25b1147eb4ef2f2981d7f2..b1172690ac667596f1ad5570913d6c3d95480ec8 100644
--- a/app/models/communication/block/template/file.rb
+++ b/app/models/communication/block/template/file.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::File < Communication::Block::Template
+class Communication::Block::Template::File < Communication::Block::Template::Base
   def build_git_dependencies
     files.each do |file|
       add_dependency file.blob
diff --git a/app/models/communication/block/template/gallery.rb b/app/models/communication/block/template/gallery.rb
index 963063b9fc51ddf61e05fa0d449dc0e1ba08819e..38c7d1b3d46fcdb0613cd995bd39337b1878f0ac 100644
--- a/app/models/communication/block/template/gallery.rb
+++ b/app/models/communication/block/template/gallery.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Gallery < Communication::Block::Template
+class Communication::Block::Template::Gallery < Communication::Block::Template::Base
 
   LAYOUTS = [:grid, :carousel].freeze
 
diff --git a/app/models/communication/block/template/image.rb b/app/models/communication/block/template/image.rb
index f6968d1ee305526e76f9b1c2b0bd41145a42263d..262bf513a14b3b6e033edaab97e63e70496b91fc 100644
--- a/app/models/communication/block/template/image.rb
+++ b/app/models/communication/block/template/image.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Image < Communication::Block::Template
+class Communication::Block::Template::Image < Communication::Block::Template::Base
   def sanitized_data
     {
       "text" => Osuny::Sanitizer.sanitize(text),
diff --git a/app/models/communication/block/template/key_figure.rb b/app/models/communication/block/template/key_figure.rb
index 0c4abee7d7d9722a106e21a5728ced277a7e47b7..38654735513a46d4b2375d6353e0c68f332963e9 100644
--- a/app/models/communication/block/template/key_figure.rb
+++ b/app/models/communication/block/template/key_figure.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::KeyFigure < Communication::Block::Template
+class Communication::Block::Template::KeyFigure < Communication::Block::Template::Base
   def build_git_dependencies
   end
 
diff --git a/app/models/communication/block/template/organization_chart.rb b/app/models/communication/block/template/organization_chart.rb
index 0164c35afb639788f554249c34ce42df3f3d4a00..aebeb9545abe6f66752fb2359e754c54fee9a3e5 100644
--- a/app/models/communication/block/template/organization_chart.rb
+++ b/app/models/communication/block/template/organization_chart.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::OrganizationChart < Communication::Block::Template
+class Communication::Block::Template::OrganizationChart < Communication::Block::Template::Base
   def build_git_dependencies
     add_dependency persons
     persons.each do |person|
diff --git a/app/models/communication/block/template/page.rb b/app/models/communication/block/template/page.rb
index 103560f6db6f197b2f389c9909bb4b5b6c3b22ef..ef482aa88eec827e42ad756763aca05dae7b51dc 100644
--- a/app/models/communication/block/template/page.rb
+++ b/app/models/communication/block/template/page.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Page < Communication::Block::Template
+class Communication::Block::Template::Page < Communication::Block::Template::Base
   has_rich_text :text
 
   LAYOUTS = [:grid, :list, :cards].freeze
diff --git a/app/models/communication/block/template/partner.rb b/app/models/communication/block/template/partner.rb
index 7a30863eac08dca4f45c93373a3f2eda3c878d40..4a19277ae9e131ba53fb97213b3f164115ae7065 100644
--- a/app/models/communication/block/template/partner.rb
+++ b/app/models/communication/block/template/partner.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Partner < Communication::Block::Template
+class Communication::Block::Template::Partner < Communication::Block::Template::Base
   def build_git_dependencies
     add_dependency active_storage_blobs
     add_dependency organizations
diff --git a/app/models/communication/block/template/post.rb b/app/models/communication/block/template/post.rb
index b25c07e1a0efdbe1d21c8fd8a618e937380ea4c7..be7aa8961903d0f999b3a43611cdbcadb50726bf 100644
--- a/app/models/communication/block/template/post.rb
+++ b/app/models/communication/block/template/post.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Post < Communication::Block::Template
+class Communication::Block::Template::Post < Communication::Block::Template::Base
   def build_git_dependencies
     add_dependency category unless category.nil?
     add_dependency selected_posts
diff --git a/app/models/communication/block/template/testimonial.rb b/app/models/communication/block/template/testimonial.rb
index 85a231cddf44da4c1df77e7be6ae896aecb7abfa..4da01d1b9a676d131e1ce8c3e6290204d7ab399e 100644
--- a/app/models/communication/block/template/testimonial.rb
+++ b/app/models/communication/block/template/testimonial.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Testimonial < Communication::Block::Template
+class Communication::Block::Template::Testimonial < Communication::Block::Template::Base
   def build_git_dependencies
     add_dependency active_storage_blobs
   end
diff --git a/app/models/communication/block/template/timeline.rb b/app/models/communication/block/template/timeline.rb
index 94c030a8459d1eca581c158224567fc8e3d827eb..8dcc3d98a7ae2c19f64da6d681ae333d086f0a47 100644
--- a/app/models/communication/block/template/timeline.rb
+++ b/app/models/communication/block/template/timeline.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Timeline < Communication::Block::Template
+class Communication::Block::Template::Timeline < Communication::Block::Template::Base
 
   def description
     "#{data['description']}"
diff --git a/app/models/communication/block/template/video.rb b/app/models/communication/block/template/video.rb
index 9420e9468f17a56dcf160f32e740efddf03caed7..a1f8c3115081edd9162bd8d69e8bd1b3d2cd30a0 100644
--- a/app/models/communication/block/template/video.rb
+++ b/app/models/communication/block/template/video.rb
@@ -1,4 +1,4 @@
-class Communication::Block::Template::Video < Communication::Block::Template
+class Communication::Block::Template::Video < Communication::Block::Template::Base
   has_string :url
   has_text :transcription