From b35fb618f3b58b9d5cd3f73c194cf5694cf6ab44 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 10 Oct 2012 10:32:21 +1100 Subject: [PATCH] Add base install of Comfortable Mexican Sofa --- Gemfile | 1 + Gemfile.lock | 6 + .../initializers/comfortable_mexican_sofa.rb | 111 ++++++++++++++ .../example.com/layouts/default/_default.yml | 1 + .../example.com/layouts/default/content.html | 5 + .../example.com/layouts/default/css.css | 1 + .../example.com/layouts/default/js.js | 1 + .../layouts/default/nested/_nested.yml | 2 + .../layouts/default/nested/content.html | 2 + .../layouts/default/nested/css.css | 1 + .../example.com/layouts/default/nested/js.js | 1 + .../example.com/pages/index/_index.yml | 2 + .../example.com/pages/index/child/_child.yml | 3 + .../example.com/pages/index/child/left.html | 1 + .../example.com/pages/index/child/right.html | 1 + .../example.com/pages/index/content.html | 2 + .../example.com/snippets/default/_default.yml | 1 + .../example.com/snippets/default/content.html | 1 + db/migrate/20121009232513_create_cms.rb | 137 ++++++++++++++++++ db/schema.rb | 119 ++++++++++++++- 20 files changed, 398 insertions(+), 1 deletion(-) create mode 100644 config/initializers/comfortable_mexican_sofa.rb create mode 100644 db/cms_fixtures/example.com/layouts/default/_default.yml create mode 100644 db/cms_fixtures/example.com/layouts/default/content.html create mode 100644 db/cms_fixtures/example.com/layouts/default/css.css create mode 100644 db/cms_fixtures/example.com/layouts/default/js.js create mode 100644 db/cms_fixtures/example.com/layouts/default/nested/_nested.yml create mode 100644 db/cms_fixtures/example.com/layouts/default/nested/content.html create mode 100644 db/cms_fixtures/example.com/layouts/default/nested/css.css create mode 100644 db/cms_fixtures/example.com/layouts/default/nested/js.js create mode 100644 db/cms_fixtures/example.com/pages/index/_index.yml create mode 100644 db/cms_fixtures/example.com/pages/index/child/_child.yml create mode 100644 db/cms_fixtures/example.com/pages/index/child/left.html create mode 100644 db/cms_fixtures/example.com/pages/index/child/right.html create mode 100644 db/cms_fixtures/example.com/pages/index/content.html create mode 100644 db/cms_fixtures/example.com/snippets/default/_default.yml create mode 100644 db/cms_fixtures/example.com/snippets/default/content.html create mode 100644 db/migrate/20121009232513_create_cms.rb diff --git a/Gemfile b/Gemfile index 64620156ae..e1983b6ee1 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,7 @@ gem 'spree_i18n', :git => 'git://github.com/spree/spree_i18n.git' gem 'spree_paypal_express', :git => 'git://github.com/spree/spree_paypal_express.git', :branch => '1-1-stable' gem 'spree_last_address', :git => 'git://github.com/dancinglightning/spree-last-address.git' +gem 'comfortable_mexican_sofa' # Fix bug in simple_form preventing collection_check_boxes usage within form_for block # When merged, revert to upstream gem diff --git a/Gemfile.lock b/Gemfile.lock index ab046c1c6b..f67a5aadc7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -102,6 +102,7 @@ GEM rack-cache (~> 1.2) rack-test (~> 0.6.1) sprockets (~> 2.1.3) + active_link_to (1.0.0) active_utils (1.0.5) activesupport (>= 2.3.11) i18n @@ -167,6 +168,10 @@ GEM execjs coffee-script-source (1.3.3) columnize (0.3.6) + comfortable_mexican_sofa (1.6.24) + active_link_to (~> 1.0.0) + paperclip (>= 2.3.0) + rails (>= 3.0.0) database_cleaner (0.7.1) debugger (1.1.4) columnize (>= 0.3.1) @@ -351,6 +356,7 @@ DEPENDENCIES bugsnag capybara coffee-rails (~> 3.2.1) + comfortable_mexican_sofa database_cleaner (= 0.7.1) factory_girl_rails faker diff --git a/config/initializers/comfortable_mexican_sofa.rb b/config/initializers/comfortable_mexican_sofa.rb new file mode 100644 index 0000000000..d4c7ab6abc --- /dev/null +++ b/config/initializers/comfortable_mexican_sofa.rb @@ -0,0 +1,111 @@ +# encoding: utf-8 + +ComfortableMexicanSofa.configure do |config| + # Title of the admin area + # config.cms_title = 'ComfortableMexicanSofa CMS Engine' + + # Module responsible for authentication. You can replace it with your own. + # It simply needs to have #authenticate method. See http_auth.rb for reference. + # config.admin_auth = 'ComfortableMexicanSofa::HttpAuth' + + # Module responsible for public authentication. Similar to the above. You also + # will have access to @cms_site, @cms_layout, @cms_page so you can use them in + # your logic. Default module doesn't do anything. + # config.public_auth = 'ComfortableMexicanSofa::DummyAuth' + + # Default url to access admin area is http://yourhost/cms-admin/ + # You can change 'cms-admin' to 'admin', for example. To disable admin area + # entirely set this to '' or nil + # config.admin_route_prefix = 'cms-admin' + + # When arriving at /cms-admin you may chose to redirect to arbirtary path, + # for example '/cms-admin/users' + # config.admin_route_redirect = '' + + # Normally we include default routes from https://github.com/comfy/comfortable-mexican-sofa/blob/master/config/routes.rb + # If you want to include the routes manually set this to false + # config.use_default_routes = true + + # /sitemap.xml that is used by search engines for indexing. It's enabled by + # default, but you may turn it off. + # config.enable_sitemap = true + + # File uploads use Paperclip and can support filesystem or s3 uploads. Override + # the upload method and appropriate settings based on Paperclip. For S3 see: + # http://rdoc.info/gems/paperclip/2.3.8/Paperclip/Storage/S3, and for + # filesystem see: http://rdoc.info/gems/paperclip/2.3.8/Paperclip/Storage/Filesystem + # config.upload_file_options = {:url => '/system/:class/:id/:attachment/:style/:filename'} + + # Sofa allows you to setup entire site from files. Database is updated with each + # request (if necessary). Please note that database entries are destroyed if there's + # no corresponding file. Fixtures are disabled by default. + # config.enable_fixtures = false + + # Path where fixtures can be located. + # config.fixtures_path = File.expand_path('db/cms_fixtures', Rails.root) + + # Importing fixtures into Database + # To load fixtures into the database just run this rake task: + # local: $ rake comfortable_mexican_sofa:fixtures:import FROM=example.local TO=localhost + # Heroku: $ heroku run rake comfortable_mexican_sofa:fixtures:import FROM=example.local TO=yourapp.herokuapp.com + # From indicates folder the fixtures are in and to is the Site hostname you have defined in the database. + + # Exporting fixtures into Files + # If you need to dump database contents into fixture files run: + # local: $ rake comfortable_mexican_sofa:fixtures:export FROM=localhost TO=example.local + # Heroku: $ heroku run rake comfortable_mexican_sofa:fixtures:export FROM=yourapp.herokuapp.com TO=example.local + # This will create example.local folder and dump all content from example.com Site. + + # Content for Layouts, Pages and Snippets has a revision history. You can revert + # a previous version using this system. You can control how many revisions per + # object you want to keep. Set it to 0 if you wish to turn this feature off. + # config.revisions_limit = 25 + + # Locale definitions. If you want to define your own locale merge + # {:locale => 'Locale Title'} with this. + # config.locales = {:en => 'English', :es => 'Español'} + + # Admin interface will respect the locale of the site being managed. However you can + # force it to English by setting this to `:en` + # config.admin_locale = nil + + # If you want to keep your CMS tables in a location other than the default database + # add a database_config. For example, setting it to 'cms' will look for a cms_#{Rails.env} + # definition in your database.yml file + # config.database_config = nil + + # A class that is included as a sweeper to admin base controller if it's set + # config.admin_cache_sweeper = nil + + # By default you cannot have irb code inside your layouts/pages/snippets. + # Generally this is to prevent putting something like this: + # <% User.delete_all %> but if you really want to allow it... + # config.allow_irb = false + + # Whitelist of all helper methods that can be used via {{cms:helper}} tag. By default + # all helpers are allowed except `eval`, `send`, `call` and few others. Empty array + # will prevent rendering of all helpers. + # config.allowed_helpers = nil + + # Whitelist of partials paths that can be used via {{cms:partial}} tag. All partials + # are accessible by default. Empty array will prevent rendering of all partials. + # config.allowed_partials = nil + + # Site aliases, if you want to have aliases for your site. Good for harmonizing + # production env with dev/testing envs. + # e.g. config.site_aliases = {'host.com' => 'host.inv', 'host_a.com' => ['host.lvh.me', 'host.dev']} + # Default is nil (not used) + # config.hostname_aliases = nil + +end + +# Default credentials for ComfortableMexicanSofa::HttpAuth +# YOU REALLY WANT TO CHANGE THIS BEFORE PUTTING YOUR SITE LIVE +ComfortableMexicanSofa::HttpAuth.username = 'username' +ComfortableMexicanSofa::HttpAuth.password = 'password' + +# If you need to inject some html in cms admin views you can define what partial +# should be rendered into the following areas: +# ComfortableMexicanSofa::ViewHooks.add(:navigation, '/layouts/admin/navigation') +# ComfortableMexicanSofa::ViewHooks.add(:html_head, '/layouts/admin/html_head') +# ComfortableMexicanSofa::ViewHooks.add(:page_form, '/layouts/admin/page_form') \ No newline at end of file diff --git a/db/cms_fixtures/example.com/layouts/default/_default.yml b/db/cms_fixtures/example.com/layouts/default/_default.yml new file mode 100644 index 0000000000..6f1626b7c0 --- /dev/null +++ b/db/cms_fixtures/example.com/layouts/default/_default.yml @@ -0,0 +1 @@ +label: Default Fixture Layout \ No newline at end of file diff --git a/db/cms_fixtures/example.com/layouts/default/content.html b/db/cms_fixtures/example.com/layouts/default/content.html new file mode 100644 index 0000000000..f2707392b4 --- /dev/null +++ b/db/cms_fixtures/example.com/layouts/default/content.html @@ -0,0 +1,5 @@ + + + {{ cms:page:content }} + + \ No newline at end of file diff --git a/db/cms_fixtures/example.com/layouts/default/css.css b/db/cms_fixtures/example.com/layouts/default/css.css new file mode 100644 index 0000000000..cd8b4f19df --- /dev/null +++ b/db/cms_fixtures/example.com/layouts/default/css.css @@ -0,0 +1 @@ +body{color: red} \ No newline at end of file diff --git a/db/cms_fixtures/example.com/layouts/default/js.js b/db/cms_fixtures/example.com/layouts/default/js.js new file mode 100644 index 0000000000..6959d8bfc5 --- /dev/null +++ b/db/cms_fixtures/example.com/layouts/default/js.js @@ -0,0 +1 @@ +// default js \ No newline at end of file diff --git a/db/cms_fixtures/example.com/layouts/default/nested/_nested.yml b/db/cms_fixtures/example.com/layouts/default/nested/_nested.yml new file mode 100644 index 0000000000..754f082c41 --- /dev/null +++ b/db/cms_fixtures/example.com/layouts/default/nested/_nested.yml @@ -0,0 +1,2 @@ +label: Default Fixture Nested Layout +position: 42 \ No newline at end of file diff --git a/db/cms_fixtures/example.com/layouts/default/nested/content.html b/db/cms_fixtures/example.com/layouts/default/nested/content.html new file mode 100644 index 0000000000..350a3d016a --- /dev/null +++ b/db/cms_fixtures/example.com/layouts/default/nested/content.html @@ -0,0 +1,2 @@ +
{{ cms:page:left }}
+
{{ cms:page:right }}
\ No newline at end of file diff --git a/db/cms_fixtures/example.com/layouts/default/nested/css.css b/db/cms_fixtures/example.com/layouts/default/nested/css.css new file mode 100644 index 0000000000..034f6fb9c2 --- /dev/null +++ b/db/cms_fixtures/example.com/layouts/default/nested/css.css @@ -0,0 +1 @@ +div{float:left} \ No newline at end of file diff --git a/db/cms_fixtures/example.com/layouts/default/nested/js.js b/db/cms_fixtures/example.com/layouts/default/nested/js.js new file mode 100644 index 0000000000..2508c22ed6 --- /dev/null +++ b/db/cms_fixtures/example.com/layouts/default/nested/js.js @@ -0,0 +1 @@ +// nested js \ No newline at end of file diff --git a/db/cms_fixtures/example.com/pages/index/_index.yml b/db/cms_fixtures/example.com/pages/index/_index.yml new file mode 100644 index 0000000000..548e85356b --- /dev/null +++ b/db/cms_fixtures/example.com/pages/index/_index.yml @@ -0,0 +1,2 @@ +label: Home Fixture Page +layout: default \ No newline at end of file diff --git a/db/cms_fixtures/example.com/pages/index/child/_child.yml b/db/cms_fixtures/example.com/pages/index/child/_child.yml new file mode 100644 index 0000000000..d8602e1484 --- /dev/null +++ b/db/cms_fixtures/example.com/pages/index/child/_child.yml @@ -0,0 +1,3 @@ +label: Child Fixture Page +layout: nested +position: 42 diff --git a/db/cms_fixtures/example.com/pages/index/child/left.html b/db/cms_fixtures/example.com/pages/index/child/left.html new file mode 100644 index 0000000000..15beb8f985 --- /dev/null +++ b/db/cms_fixtures/example.com/pages/index/child/left.html @@ -0,0 +1 @@ +Child Page Left Fixture Content \ No newline at end of file diff --git a/db/cms_fixtures/example.com/pages/index/child/right.html b/db/cms_fixtures/example.com/pages/index/child/right.html new file mode 100644 index 0000000000..3ac08e9ab7 --- /dev/null +++ b/db/cms_fixtures/example.com/pages/index/child/right.html @@ -0,0 +1 @@ +Child Page Right Fixture Content \ No newline at end of file diff --git a/db/cms_fixtures/example.com/pages/index/content.html b/db/cms_fixtures/example.com/pages/index/content.html new file mode 100644 index 0000000000..fb97a42a71 --- /dev/null +++ b/db/cms_fixtures/example.com/pages/index/content.html @@ -0,0 +1,2 @@ +Home Page Fixture Contént +{{ cms:snippet:default }} \ No newline at end of file diff --git a/db/cms_fixtures/example.com/snippets/default/_default.yml b/db/cms_fixtures/example.com/snippets/default/_default.yml new file mode 100644 index 0000000000..64cc262bd9 --- /dev/null +++ b/db/cms_fixtures/example.com/snippets/default/_default.yml @@ -0,0 +1 @@ +label: Default Fixture Snippet \ No newline at end of file diff --git a/db/cms_fixtures/example.com/snippets/default/content.html b/db/cms_fixtures/example.com/snippets/default/content.html new file mode 100644 index 0000000000..48a4995fa8 --- /dev/null +++ b/db/cms_fixtures/example.com/snippets/default/content.html @@ -0,0 +1 @@ +Fixture Content for Default Snippet \ No newline at end of file diff --git a/db/migrate/20121009232513_create_cms.rb b/db/migrate/20121009232513_create_cms.rb new file mode 100644 index 0000000000..d1c1700a5e --- /dev/null +++ b/db/migrate/20121009232513_create_cms.rb @@ -0,0 +1,137 @@ +class CreateCms < ActiveRecord::Migration + + def self.up + + text_limit = case ActiveRecord::Base.connection.adapter_name + when 'PostgreSQL' + { } + else + { :limit => 16777215 } + end + + # -- Sites -------------------------------------------------------------- + create_table :cms_sites do |t| + t.string :label, :null => false + t.string :identifier, :null => false + t.string :hostname, :null => false + t.string :path + t.string :locale, :null => false, :default => 'en' + t.boolean :is_mirrored, :null => false, :default => false + end + add_index :cms_sites, :hostname + add_index :cms_sites, :is_mirrored + + # -- Layouts ------------------------------------------------------------ + create_table :cms_layouts do |t| + t.integer :site_id, :null => false + t.integer :parent_id + t.string :app_layout + t.string :label, :null => false + t.string :identifier, :null => false + t.text :content, text_limit + t.text :css, text_limit + t.text :js, text_limit + t.integer :position, :null => false, :default => 0 + t.boolean :is_shared, :null => false, :default => false + t.timestamps + end + add_index :cms_layouts, [:parent_id, :position] + add_index :cms_layouts, [:site_id, :identifier], :unique => true + + # -- Pages -------------------------------------------------------------- + create_table :cms_pages do |t| + t.integer :site_id, :null => false + t.integer :layout_id + t.integer :parent_id + t.integer :target_page_id + t.string :label, :null => false + t.string :slug + t.string :full_path, :null => false + t.text :content, text_limit + t.integer :position, :null => false, :default => 0 + t.integer :children_count, :null => false, :default => 0 + t.boolean :is_published, :null => false, :default => true + t.boolean :is_shared, :null => false, :default => false + t.timestamps + end + add_index :cms_pages, [:site_id, :full_path] + add_index :cms_pages, [:parent_id, :position] + + # -- Page Blocks -------------------------------------------------------- + create_table :cms_blocks do |t| + t.integer :page_id, :null => false + t.string :identifier, :null => false + t.text :content + t.timestamps + end + add_index :cms_blocks, [:page_id, :identifier] + + # -- Snippets ----------------------------------------------------------- + create_table :cms_snippets do |t| + t.integer :site_id, :null => false + t.string :label, :null => false + t.string :identifier, :null => false + t.text :content, text_limit + t.integer :position, :null => false, :default => 0 + t.boolean :is_shared, :null => false, :default => false + t.timestamps + end + add_index :cms_snippets, [:site_id, :identifier], :unique => true + add_index :cms_snippets, [:site_id, :position] + + # -- Files -------------------------------------------------------------- + create_table :cms_files do |t| + t.integer :site_id, :null => false + t.integer :block_id + t.string :label, :null => false + t.string :file_file_name, :null => false + t.string :file_content_type, :null => false + t.integer :file_file_size, :null => false + t.string :description, :limit => 2048 + t.integer :position, :null => false, :default => 0 + t.timestamps + end + add_index :cms_files, [:site_id, :label] + add_index :cms_files, [:site_id, :file_file_name] + add_index :cms_files, [:site_id, :position] + add_index :cms_files, [:site_id, :block_id] + + # -- Revisions ----------------------------------------------------------- + create_table :cms_revisions, :force => true do |t| + t.string :record_type, :null => false + t.integer :record_id, :null => false + t.text :data, text_limit + t.datetime :created_at + end + add_index :cms_revisions, [:record_type, :record_id, :created_at] + + # -- Categories --------------------------------------------------------- + create_table :cms_categories, :force => true do |t| + t.integer :site_id, :null => false + t.string :label, :null => false + t.string :categorized_type, :null => false + end + add_index :cms_categories, [:site_id, :categorized_type, :label], :unique => true + + create_table :cms_categorizations, :force => true do |t| + t.integer :category_id, :null => false + t.string :categorized_type, :null => false + t.integer :categorized_id, :null => false + end + add_index :cms_categorizations, [:category_id, :categorized_type, :categorized_id], :unique => true, + :name => 'index_cms_categorizations_on_cat_id_and_catd_type_and_catd_id' + end + + def self.down + drop_table :cms_sites + drop_table :cms_layouts + drop_table :cms_pages + drop_table :cms_snippets + drop_table :cms_blocks + drop_table :cms_files + drop_table :cms_revisions + drop_table :cms_categories + drop_table :cms_categorizations + end +end + diff --git a/db/schema.rb b/db/schema.rb index 8b062b492c..419c2ce1b3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,124 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20121005015852) do +ActiveRecord::Schema.define(:version => 20121009232513) do + + create_table "cms_blocks", :force => true do |t| + t.integer "page_id", :null => false + t.string "identifier", :null => false + t.text "content" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "cms_blocks", ["page_id", "identifier"], :name => "index_cms_blocks_on_page_id_and_identifier" + + create_table "cms_categories", :force => true do |t| + t.integer "site_id", :null => false + t.string "label", :null => false + t.string "categorized_type", :null => false + end + + add_index "cms_categories", ["site_id", "categorized_type", "label"], :name => "index_cms_categories_on_site_id_and_categorized_type_and_label", :unique => true + + create_table "cms_categorizations", :force => true do |t| + t.integer "category_id", :null => false + t.string "categorized_type", :null => false + t.integer "categorized_id", :null => false + end + + add_index "cms_categorizations", ["category_id", "categorized_type", "categorized_id"], :name => "index_cms_categorizations_on_cat_id_and_catd_type_and_catd_id", :unique => true + + create_table "cms_files", :force => true do |t| + t.integer "site_id", :null => false + t.integer "block_id" + t.string "label", :null => false + t.string "file_file_name", :null => false + t.string "file_content_type", :null => false + t.integer "file_file_size", :null => false + t.string "description", :limit => 2048 + t.integer "position", :default => 0, :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "cms_files", ["site_id", "block_id"], :name => "index_cms_files_on_site_id_and_block_id" + add_index "cms_files", ["site_id", "file_file_name"], :name => "index_cms_files_on_site_id_and_file_file_name" + add_index "cms_files", ["site_id", "label"], :name => "index_cms_files_on_site_id_and_label" + add_index "cms_files", ["site_id", "position"], :name => "index_cms_files_on_site_id_and_position" + + create_table "cms_layouts", :force => true do |t| + t.integer "site_id", :null => false + t.integer "parent_id" + t.string "app_layout" + t.string "label", :null => false + t.string "identifier", :null => false + t.text "content" + t.text "css" + t.text "js" + t.integer "position", :default => 0, :null => false + t.boolean "is_shared", :default => false, :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "cms_layouts", ["parent_id", "position"], :name => "index_cms_layouts_on_parent_id_and_position" + add_index "cms_layouts", ["site_id", "identifier"], :name => "index_cms_layouts_on_site_id_and_identifier", :unique => true + + create_table "cms_pages", :force => true do |t| + t.integer "site_id", :null => false + t.integer "layout_id" + t.integer "parent_id" + t.integer "target_page_id" + t.string "label", :null => false + t.string "slug" + t.string "full_path", :null => false + t.text "content" + t.integer "position", :default => 0, :null => false + t.integer "children_count", :default => 0, :null => false + t.boolean "is_published", :default => true, :null => false + t.boolean "is_shared", :default => false, :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "cms_pages", ["parent_id", "position"], :name => "index_cms_pages_on_parent_id_and_position" + add_index "cms_pages", ["site_id", "full_path"], :name => "index_cms_pages_on_site_id_and_full_path" + + create_table "cms_revisions", :force => true do |t| + t.string "record_type", :null => false + t.integer "record_id", :null => false + t.text "data" + t.datetime "created_at" + end + + add_index "cms_revisions", ["record_type", "record_id", "created_at"], :name => "index_cms_revisions_on_record_type_and_record_id_and_created_at" + + create_table "cms_sites", :force => true do |t| + t.string "label", :null => false + t.string "identifier", :null => false + t.string "hostname", :null => false + t.string "path" + t.string "locale", :default => "en", :null => false + t.boolean "is_mirrored", :default => false, :null => false + end + + add_index "cms_sites", ["hostname"], :name => "index_cms_sites_on_hostname" + add_index "cms_sites", ["is_mirrored"], :name => "index_cms_sites_on_is_mirrored" + + create_table "cms_snippets", :force => true do |t| + t.integer "site_id", :null => false + t.string "label", :null => false + t.string "identifier", :null => false + t.text "content" + t.integer "position", :default => 0, :null => false + t.boolean "is_shared", :default => false, :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "cms_snippets", ["site_id", "identifier"], :name => "index_cms_snippets_on_site_id_and_identifier", :unique => true + add_index "cms_snippets", ["site_id", "position"], :name => "index_cms_snippets_on_site_id_and_position" create_table "distributors", :force => true do |t| t.string "name"