diff --git a/.gitignore b/.gitignore
index f35b9ea93..64f5e1ff9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,4 @@ set_aws_credentials.sh
# Ignore map images uploaded to Locations
/locations
+public/sitemap.xml.gz
diff --git a/Gemfile b/Gemfile
index 7e2d43b54..ebd700ce4 100644
--- a/Gemfile
+++ b/Gemfile
@@ -26,6 +26,9 @@ gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'rails-jquery-autocomplete'
+# SEO
+gem 'meta-tags'
+
# Smarts
# gem 'serendipitous', :path => "~/Code/indent/serendipitous-gem"
gem 'serendipitous', git: 'git://github.com/indentlabs/serendipitous-gem.git'
diff --git a/Gemfile.lock b/Gemfile.lock
index 9fe868ff8..83886477f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -164,6 +164,8 @@ GEM
railties (>= 3.2)
medium-editor-rails (2.2.0)
railties (>= 3.0)
+ meta-tags (2.2.0)
+ actionpack (>= 3.2.0)
method_source (0.8.2)
mime-types (3.0)
mime-types-data (~> 3.2015)
@@ -317,6 +319,7 @@ DEPENDENCIES
jquery-ui-rails
material_icons
medium-editor-rails
+ meta-tags
paperclip (~> 4.2.0)
pg
pry
diff --git a/app/assets/images/card-headers/characters.jpg b/app/assets/images/card-headers/characters.jpg
index c9d1d1eff..802d8b592 100644
Binary files a/app/assets/images/card-headers/characters.jpg and b/app/assets/images/card-headers/characters.jpg differ
diff --git a/app/assets/images/card-headers/items.jpg b/app/assets/images/card-headers/items.jpg
index 157866871..d213925c6 100644
Binary files a/app/assets/images/card-headers/items.jpg and b/app/assets/images/card-headers/items.jpg differ
diff --git a/app/assets/images/card-headers/locations.jpg b/app/assets/images/card-headers/locations.jpg
index 6d726b12b..738c067dd 100644
Binary files a/app/assets/images/card-headers/locations.jpg and b/app/assets/images/card-headers/locations.jpg differ
diff --git a/app/assets/images/card-headers/universes.jpg b/app/assets/images/card-headers/universes.jpg
index d110c17c8..411455cc9 100644
Binary files a/app/assets/images/card-headers/universes.jpg and b/app/assets/images/card-headers/universes.jpg differ
diff --git a/app/assets/images/landing/digital-notebook.jpg b/app/assets/images/landing/digital-notebook.jpg
new file mode 100644
index 000000000..ab9327fac
Binary files /dev/null and b/app/assets/images/landing/digital-notebook.jpg differ
diff --git a/app/assets/images/landing/screenshot.png b/app/assets/images/landing/screenshot.png
new file mode 100644
index 000000000..f5f5e9a87
Binary files /dev/null and b/app/assets/images/landing/screenshot.png differ
diff --git a/app/assets/stylesheets/landing.scss b/app/assets/stylesheets/landing.scss
new file mode 100644
index 000000000..e633f0c80
--- /dev/null
+++ b/app/assets/stylesheets/landing.scss
@@ -0,0 +1,5 @@
+.perks-section {
+ i[class=material-icons] {
+ font-size: 120%;
+ }
+}
\ No newline at end of file
diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb
index 107f73289..367d0d9fc 100644
--- a/app/controllers/main_controller.rb
+++ b/app/controllers/main_controller.rb
@@ -1,10 +1,15 @@
# Controller for top-level pages of the site that do not have
# an associated model
class MainController < ApplicationController
+ layout "landing", only: [:index, :about_notebook]
+
def index
redirect_to :dashboard if user_signed_in?
end
+ def about_notebook
+ end
+
def comingsoon
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 11d01ba53..5110ea7ff 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -16,6 +16,25 @@ class User < ActiveRecord::Base
has_many :magics
has_many :universes
+ # as_json creates a hash structure, which you then pass to ActiveSupport::json.encode to actually encode the object as a JSON string.
+ # This is different from to_json, which converts it straight to an escaped JSON string,
+ # which is undesireable in a case like this, when we want to modify it
+ def as_json(options={})
+ options[:except] ||= blacklisted_attributes
+ super(options)
+ end
+
+ # Returns this object as an escaped JSON string
+ def to_json(options={})
+ options[:except] ||= blacklisted_attributes
+ super(options)
+ end
+
+ def to_xml(options={})
+ options[:except] ||= blacklisted_attributes
+ super(options)
+ end
+
def content
{
characters: characters,
@@ -37,4 +56,18 @@ def content_count
universes.length
].sum
end
+
+ private
+
+ # Attributes that are non-public, and should be blacklisted from any public
+ # export (ex. in the JSON api, or SEO meta info about the user)
+ def blacklisted_attributes
+ [
+ :password_digest,
+ :old_password,
+ :encrypted_password,
+ :reset_password_token,
+ :email
+ ]
+ end
end
diff --git a/app/views/cards/intros/_item_intro.html.erb b/app/views/cards/intros/_item_intro.html.erb
index 5046dd79f..2b5d6163c 100644
--- a/app/views/cards/intros/_item_intro.html.erb
+++ b/app/views/cards/intros/_item_intro.html.erb
@@ -5,7 +5,7 @@
- Every weapon was made by someone, and every book has an owner. Keep track of every aspect of your items.
+ Every weapon was made by someone; every book has a story. Track of every aspect of your items.
\ No newline at end of file
diff --git a/app/views/cards/intros/_location_intro.html.erb b/app/views/cards/intros/_location_intro.html.erb
index f74f75d7f..fd9ce11d8 100644
--- a/app/views/cards/intros/_location_intro.html.erb
+++ b/app/views/cards/intros/_location_intro.html.erb
@@ -5,7 +5,7 @@
- Upload maps, link areas, track demographics, and keep track of history.
+ Upload maps, link areas, track demographics, and keep track of your world's history.
\ No newline at end of file
diff --git a/app/views/characters/show.html.erb b/app/views/characters/show.html.erb
index b14974f03..a7b3eda34 100644
--- a/app/views/characters/show.html.erb
+++ b/app/views/characters/show.html.erb
@@ -1 +1,14 @@
+<%# to_json will escape any values into unicode escape sequences, so we can call html_safe %>
+
+
+
<%= render partial: 'content/show', locals: { content: @content } %>
diff --git a/app/views/content/_show.html.erb b/app/views/content/_show.html.erb
index 0bd976fd8..b963865f3 100644
--- a/app/views/content/_show.html.erb
+++ b/app/views/content/_show.html.erb
@@ -1,4 +1,14 @@
-<% title @content.name %>
+<% if @content.present? && @content.respond_to?(:as_jsonld) %>
+
+<% end %>
+
+<%
+set_meta_tags title: content.name, description: content.description
+%>
+
+
<% content_for :sidebar_top do %>
<%= render partial: 'cards/serendipitous/content_question', locals: { question: @question, content: @content } %>
diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb
index a640dd124..188b0f789 100644
--- a/app/views/devise/registrations/new.html.erb
+++ b/app/views/devise/registrations/new.html.erb
@@ -26,6 +26,11 @@
<%= f.password_field :password_confirmation, autocomplete: "off" %>
+
diff --git a/app/views/items/show.html.erb b/app/views/items/show.html.erb
index b14974f03..4c2964555 100644
--- a/app/views/items/show.html.erb
+++ b/app/views/items/show.html.erb
@@ -1 +1,12 @@
+
+
<%= render partial: 'content/show', locals: { content: @content } %>
diff --git a/app/views/layouts/_ganalytics.html.erb b/app/views/layouts/_ganalytics.html.erb
index 839a9917a..5bcc7fd91 100644
--- a/app/views/layouts/_ganalytics.html.erb
+++ b/app/views/layouts/_ganalytics.html.erb
@@ -2,7 +2,7 @@
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-39217500-1']);
- _gaq.push(['_setDomainName', 'indentapp.com']);
+ _gaq.push(['_setDomainName', 'notebook.ai']);
_gaq.push(['_trackPageview']);
(function() {
@@ -11,4 +11,4 @@
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
-
\ No newline at end of file
+
diff --git a/app/views/layouts/_seo.html.erb b/app/views/layouts/_seo.html.erb
new file mode 100644
index 000000000..11b13053d
--- /dev/null
+++ b/app/views/layouts/_seo.html.erb
@@ -0,0 +1,32 @@
+
+<%=
+# This belongs inside the tag.
+# Default values and pointers here only.
+# Most content should be set in the pages themselves.
+# Any values set here can be overridden.
+
+# Default & site-wide values
+
+display_meta_tags site: 'Notebook',
+publisher: 'https://plus.google.com/118076966717703203223',
+image_src: image_url('card-headers/hero.png'),
+description: 'Notebook is a set of tools for writers, game designers, and roleplayers to create magnificent universes — and everything within them.',
+# Recommended keywords tag length: up to 255 characters, 20 words.
+keywords: %w[writing author nanowrimo novel character fiction fantasy universe creative dnd roleplay larp game design],
+og: {
+ title: :title,
+ site_name: 'Notebook',
+ url: request.url,
+ image: :image_src,
+ description: :description,
+},
+twitter: {
+ card: 'summary',
+ title: :title,
+ site: '@IndentLabs',
+ image: :image_src,
+ url: request.url,
+ description: :description
+}
+%>
+
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 5acd21dfd..f181e22b7 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -1,7 +1,6 @@
- <%= content_for?(:title) ? yield(:title) : 'Notebook' %>
<%= stylesheet_link_tag 'application' %>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tags %>
@@ -10,6 +9,9 @@
+
+ <%# is set in _seo.html.erb %>
+ <%= render 'layouts/seo' %>
@@ -29,7 +31,6 @@
<%= render 'layouts/ganalytics' %>
-
<%= render 'layouts/footer' %>
diff --git a/app/views/layouts/landing.html.erb b/app/views/layouts/landing.html.erb
new file mode 100644
index 000000000..8785bd536
--- /dev/null
+++ b/app/views/layouts/landing.html.erb
@@ -0,0 +1,27 @@
+
+
+
+ <%= content_for?(:title) ? yield(:title) : 'Notebook' %>
+ <%= stylesheet_link_tag 'application' %>
+ <%= javascript_include_tag 'application' %>
+ <%= csrf_meta_tags %>
+
+
+
+
+
+
+
+
+ <%= render 'layouts/navbar' %>
+
+
+ <%= yield %>
+
+ <%= render 'layouts/ganalytics' %>
+
+
+
+
+
+
diff --git a/app/views/locations/show.html.erb b/app/views/locations/show.html.erb
index b14974f03..96ba891ec 100644
--- a/app/views/locations/show.html.erb
+++ b/app/views/locations/show.html.erb
@@ -1 +1,12 @@
+
+
<%= render partial: 'content/show', locals: { content: @content } %>
diff --git a/app/views/main/about_notebook.html.erb b/app/views/main/about_notebook.html.erb
new file mode 100644
index 000000000..8ab53b933
--- /dev/null
+++ b/app/views/main/about_notebook.html.erb
@@ -0,0 +1,65 @@
+
+
+
+ <%= image_tag 'landing/digital-notebook.jpg', style: "height: 600px;" %>
+ Your digital notebook is here.
+
+
+
+ Notebook is a set of tools for writers, game designers, and roleplayers to create magnificent universes – and everything within them.
+
+
+ From a simple interface in your browser, on your phone, or on your tablet, you can do everything you'd ever want to do while creating your own little (or big!) world.
+
We did most of the heavy lifting for you to provide a default stylings that incorporate our custom components.
+
+
+
+
+ group
+
User Experience Focused
+
By utilizing elements and principles of Material Design, we were able to create a framework that focuses on User Experience.
+
+
+
+
+ settings
+
Easy to work with
+
We have provided detailed documentation as well as specific code examples to help new users get started.
+
+
+
\ No newline at end of file
diff --git a/app/views/main/dashboard.html.erb b/app/views/main/dashboard.html.erb
index 88419bd37..262232186 100644
--- a/app/views/main/dashboard.html.erb
+++ b/app/views/main/dashboard.html.erb
@@ -211,4 +211,4 @@
-
\ No newline at end of file
+
diff --git a/app/views/main/index.html.erb b/app/views/main/index.html.erb
index 51181999e..60f6f243c 100644
--- a/app/views/main/index.html.erb
+++ b/app/views/main/index.html.erb
@@ -1,22 +1,411 @@
-
-
-
-
- <%= image_tag 'card-headers/hero.jpg', width: '100%' %>
- Your digital notebook is here.
-
-
-
- Notebook is a set of tools for writers, game designers, and roleplayers to create magnificent universes – and everything within them.
-
-
- From a simple interface in your browser, on your phone, or on your tablet, you can do everything you'd ever want to do while creating your own little (or big!) world.
+
+
+
+
+
+ Your digital notebook is here.
+
+
+
+ Notebook.ai grows with your ideas and collaborates back with you.
+