From 59bb2e2d8a74e640ceb64658e2763f898ef9c09c Mon Sep 17 00:00:00 2001 From: git4ruby Date: Wed, 18 May 2016 01:20:46 -0500 Subject: [PATCH 01/17] Added Redcarpet & Pygments.rb for Markdown & Syntax Highlighting --- Gemfile | 33 +- Gemfile.lock | 8 + app/assets/css/application.css.css | 51 ++++ app/assets/css/pygments.css.css | 287 ++++++++++++++++++ .../application.css.scssc | Bin 36503 -> 36606 bytes .../pygments.css.scssc | Bin 0 -> 49395 bytes app/assets/stylesheets/application.css.scss | 1 + app/assets/stylesheets/pygments.css.scss | 82 +++++ app/helpers/application_helper.rb | 18 ++ app/views/posts/show.html.erb | 5 +- 10 files changed, 451 insertions(+), 34 deletions(-) create mode 100644 app/assets/css/application.css.css create mode 100644 app/assets/css/pygments.css.css create mode 100644 app/assets/stylesheets/.sass-cache/ab5c96180a20dcd6f1c0c702a2059ca1c5a69e5d/pygments.css.scssc create mode 100644 app/assets/stylesheets/pygments.css.scss diff --git a/Gemfile b/Gemfile index 1e4f013..995ae83 100644 --- a/Gemfile +++ b/Gemfile @@ -1,50 +1,21 @@ source 'https://rubygems.org' - -# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.2.4' -# Use sqlite3 as the database for Active Record gem 'sqlite3' -# Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' -# Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' -# Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.1.0' -# See https://github.com/rails/execjs#readme for more supported runtimes -# gem 'therubyracer', platforms: :ruby - -# Use jquery as the JavaScript library gem 'jquery-rails' -# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks gem 'turbolinks' -# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.0' -# bundle exec rake doc:rails generates the API under doc/api. gem 'sdoc', '~> 0.4.0', group: :doc - gem 'font-awesome-sass' - - -# Use ActiveModel has_secure_password -# gem 'bcrypt', '~> 3.1.7' - -# Use Unicorn as the app server -# gem 'unicorn' - -# Use Capistrano for deployment -# gem 'capistrano-rails', group: :development +gem 'pygments.rb', '~>0.6.0' +gem 'redcarpet', '~>3.2.2' group :development, :test do - # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' -end - -group :development do - # Access an IRB console on exception pages or by using <%= console %> in views gem 'web-console', '~> 2.0' - - # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' end diff --git a/Gemfile.lock b/Gemfile.lock index 847a042..e96879d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,6 +77,10 @@ GEM multi_json (1.12.0) nokogiri (1.6.7.2) mini_portile2 (~> 2.0.0.rc2) + posix-spawn (0.3.11) + pygments.rb (0.6.3) + posix-spawn (~> 0.3.6) + yajl-ruby (~> 1.2.0) rack (1.6.4) rack-test (0.6.3) rack (>= 1.0) @@ -107,6 +111,7 @@ GEM rake (11.1.2) rdoc (4.2.2) json (~> 1.4) + redcarpet (3.2.3) sass (3.4.22) sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) @@ -140,6 +145,7 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) + yajl-ruby (1.2.1) PLATFORMS ruby @@ -150,7 +156,9 @@ DEPENDENCIES font-awesome-sass jbuilder (~> 2.0) jquery-rails + pygments.rb (~> 0.6.0) rails (= 4.2.4) + redcarpet (~> 3.2.2) sass-rails (~> 5.0) sdoc (~> 0.4.0) spring diff --git a/app/assets/css/application.css.css b/app/assets/css/application.css.css new file mode 100644 index 0000000..254e551 --- /dev/null +++ b/app/assets/css/application.css.css @@ -0,0 +1,51 @@ +/* +Error: File to import not found or unreadable: normalize. + Load paths: + /Users/mohit/Desktop/Portfolio/Portfolio/app/assets/stylesheets + Sass::Globbing::Importer + on line 1 of /Users/mohit/Desktop/Portfolio/Portfolio/app/assets/stylesheets/application.css.scss + +1: @import 'normalize'; +2: +3: $dark: #424652; +4: $white: #FFFFFF; +5: $light: #9a9da4; +6: $highlight: #8bc6db; + +Backtrace: +/Users/mohit/Desktop/Portfolio/Portfolio/app/assets/stylesheets/application.css.scss:1 +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/import_node.rb:67:in `rescue in import' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/import_node.rb:45:in `import' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/import_node.rb:28:in `imported_file' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/import_node.rb:37:in `css_import?' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:311:in `visit_import' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:36:in `visit' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:158:in `block in visit' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/stack.rb:79:in `block in with_base' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/stack.rb:115:in `with_frame' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/stack.rb:79:in `with_base' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:158:in `visit' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:52:in `block in visit_children' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:52:in `map' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:52:in `visit_children' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:167:in `block in visit_children' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:179:in `with_environment' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:166:in `visit_children' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:36:in `block in visit' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:186:in `visit_root' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/base.rb:36:in `visit' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:157:in `visit' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/visitors/perform.rb:8:in `visit' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/root_node.rb:36:in `css_tree' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/tree/root_node.rb:20:in `render' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/engine.rb:278:in `render' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/exec/sass_scss.rb:423:in `run' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/exec/sass_scss.rb:63:in `process_result' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/exec/base.rb:52:in `parse' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/lib/sass/exec/base.rb:19:in `parse!' +/Users/mohit/Downloads/CodeKit.app/Contents/Resources/engines/scss/bin/scss:13:in `
' +*/ +body:before { + white-space: pre; + font-family: monospace; + content: "Error: File to import not found or unreadable: normalize.\A Load paths:\A /Users/mohit/Desktop/Portfolio/Portfolio/app/assets/stylesheets\A Sass::Globbing::Importer\A on line 1 of /Users/mohit/Desktop/Portfolio/Portfolio/app/assets/stylesheets/application.css.scss\A \A 1: @import 'normalize';\A 2: \A 3: $dark: #424652;\A 4: $white: #FFFFFF;\A 5: $light: #9a9da4;\A 6: $highlight: #8bc6db;"; } diff --git a/app/assets/css/pygments.css.css b/app/assets/css/pygments.css.css new file mode 100644 index 0000000..1d25ef5 --- /dev/null +++ b/app/assets/css/pygments.css.css @@ -0,0 +1,287 @@ +/* + Some simple Github-like styles, with syntax highlighting CSS via Pygments. +*/ +pre { + background-color: #eee; + padding: 1.5rem 3.5%; + margin: 2rem 0; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + overflow: auto; } + +code { + background-color: #eee; + padding: 1px 3px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; } + +.hll { + background-color: #ffffcc; } + +.c { + color: #999988; + font-style: italic; } + +/* Comment */ +.err { + color: #a61717; + background-color: #e3d2d2; } + +/* Error */ +.k { + color: #000000; + font-weight: bold; } + +/* Keyword */ +.o { + color: #000000; + font-weight: bold; } + +/* Operator */ +.cm { + color: #999988; + font-style: italic; } + +/* Comment.Multiline */ +.cp { + color: #999999; + font-weight: bold; + font-style: italic; } + +/* Comment.Preproc */ +.c1 { + color: #999988; + font-style: italic; } + +/* Comment.Single */ +.cs { + color: #999999; + font-weight: bold; + font-style: italic; } + +/* Comment.Special */ +.gd { + color: #000000; + background-color: #ffdddd; } + +/* Generic.Deleted */ +.ge { + color: #000000; + font-style: italic; } + +/* Generic.Emph */ +.gr { + color: #aa0000; } + +/* Generic.Error */ +.gh { + color: #999999; } + +/* Generic.Heading */ +.gi { + color: #000000; + background-color: #ddffdd; } + +/* Generic.Inserted */ +.go { + color: #888888; } + +/* Generic.Output */ +.gp { + color: #555555; } + +/* Generic.Prompt */ +.gs { + font-weight: bold; } + +/* Generic.Strong */ +.gu { + color: #aaaaaa; } + +/* Generic.Subheading */ +.gt { + color: #aa0000; } + +/* Generic.Traceback */ +.kc { + color: #000000; + font-weight: bold; } + +/* Keyword.Constant */ +.kd { + color: #000000; + font-weight: bold; } + +/* Keyword.Declaration */ +.kn { + color: #000000; + font-weight: bold; } + +/* Keyword.Namespace */ +.kp { + color: #000000; + font-weight: bold; } + +/* Keyword.Pseudo */ +.kr { + color: #000000; + font-weight: bold; } + +/* Keyword.Reserved */ +.kt { + color: #445588; + font-weight: bold; } + +/* Keyword.Type */ +.m { + color: #009999; } + +/* Literal.Number */ +.s { + color: #d01040; } + +/* Literal.String */ +.na { + color: #008080; } + +/* Name.Attribute */ +.nb { + color: #0086B3; } + +/* Name.Builtin */ +.nc { + color: #445588; + font-weight: bold; } + +/* Name.Class */ +.no { + color: #008080; } + +/* Name.Constant */ +.nd { + color: #3c5d5d; + font-weight: bold; } + +/* Name.Decorator */ +.ni { + color: #800080; } + +/* Name.Entity */ +.ne { + color: #990000; + font-weight: bold; } + +/* Name.Exception */ +.nf { + color: #990000; + font-weight: bold; } + +/* Name.Function */ +.nl { + color: #990000; + font-weight: bold; } + +/* Name.Label */ +.nn { + color: #555555; } + +/* Name.Namespace */ +.nt { + color: #000080; } + +/* Name.Tag */ +.nv { + color: #008080; } + +/* Name.Variable */ +.ow { + color: #000000; + font-weight: bold; } + +/* Operator.Word */ +.w { + color: #bbbbbb; } + +/* Text.Whitespace */ +.mf { + color: #009999; } + +/* Literal.Number.Float */ +.mh { + color: #009999; } + +/* Literal.Number.Hex */ +.mi { + color: #009999; } + +/* Literal.Number.Integer */ +.mo { + color: #009999; } + +/* Literal.Number.Oct */ +.sb { + color: #d01040; } + +/* Literal.String.Backtick */ +.sc { + color: #d01040; } + +/* Literal.String.Char */ +.sd { + color: #d01040; } + +/* Literal.String.Doc */ +.s2 { + color: #d01040; } + +/* Literal.String.Double */ +.se { + color: #d01040; } + +/* Literal.String.Escape */ +.sh { + color: #d01040; } + +/* Literal.String.Heredoc */ +.si { + color: #d01040; } + +/* Literal.String.Interpol */ +.sx { + color: #d01040; } + +/* Literal.String.Other */ +.sr { + color: #009926; } + +/* Literal.String.Regex */ +.s1 { + color: #d01040; } + +/* Literal.String.Single */ +.ss { + color: #990073; } + +/* Literal.String.Symbol */ +.bp { + color: #999999; } + +/* Name.Builtin.Pseudo */ +.vc { + color: #008080; } + +/* Name.Variable.Class */ +.vg { + color: #008080; } + +/* Name.Variable.Global */ +.vi { + color: #008080; } + +/* Name.Variable.Instance */ +.il { + color: #009999; } + +/* Literal.Number.Integer.Long */ diff --git a/app/assets/stylesheets/.sass-cache/ab5c96180a20dcd6f1c0c702a2059ca1c5a69e5d/application.css.scssc b/app/assets/stylesheets/.sass-cache/ab5c96180a20dcd6f1c0c702a2059ca1c5a69e5d/application.css.scssc index c952072e69f891a00e05354c8b072787ade3e950..14a74c82f3f2647e542b56695ecb08c57dd774a4 100644 GIT binary patch delta 178 zcmbO}m+9YJrU{Z7=7#2mNkC|Bo|0r~oR(%_oMvKZXqs%AY+_+#Vs2(>mI#tdndqp_ zD7P_Fx+N;#nw`g*!&8a3pfWu-HLs+Y&6+dBnk|~an#;hNJCkvXHBY`ZFQ+wMzBNBP zL_i>u&sq?fD`73eiFv G`YZvJR4@ww delta 87 zcmex2mudQ3rU{Z7CT2#-CW$F&W{D}5iDo8dhGvPz#+GK5hAAeNi782zW~Pa$DaI)# r6CKqVWjAI@x3F1rc`7ko-h8j+3MU7fHD`!5cP889LT%y65BlT)p9dP* diff --git a/app/assets/stylesheets/.sass-cache/ab5c96180a20dcd6f1c0c702a2059ca1c5a69e5d/pygments.css.scssc b/app/assets/stylesheets/.sass-cache/ab5c96180a20dcd6f1c0c702a2059ca1c5a69e5d/pygments.css.scssc new file mode 100644 index 0000000000000000000000000000000000000000..905b72b3af28179e4e97592148290197d5561e7e GIT binary patch literal 49395 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 literal 0 HcmV?d00001 diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss index 5b68a18..b28370c 100644 --- a/app/assets/stylesheets/application.css.scss +++ b/app/assets/stylesheets/application.css.scss @@ -177,3 +177,4 @@ input[type="submit"], .button { @import 'welcome'; @import 'posts_projects'; +@import 'pygments'; \ No newline at end of file diff --git a/app/assets/stylesheets/pygments.css.scss b/app/assets/stylesheets/pygments.css.scss new file mode 100644 index 0000000..44e7ef4 --- /dev/null +++ b/app/assets/stylesheets/pygments.css.scss @@ -0,0 +1,82 @@ +/* + Some simple Github-like styles, with syntax highlighting CSS via Pygments. +*/ + +pre{ + background-color: #eee; + padding: 1.5rem 3.5%; + margin: 2rem 0; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + overflow: auto; +} +code{ + background-color: #eee; + padding: 1px 3px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; +} + +.hll { background-color: #ffffcc } +.c { color: #999988; font-style: italic } /* Comment */ +.err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.k { color: #000000; font-weight: bold } /* Keyword */ +.o { color: #000000; font-weight: bold } /* Operator */ +.cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */ +.c1 { color: #999988; font-style: italic } /* Comment.Single */ +.cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.ge { color: #000000; font-style: italic } /* Generic.Emph */ +.gr { color: #aa0000 } /* Generic.Error */ +.gh { color: #999999 } /* Generic.Heading */ +.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.go { color: #888888 } /* Generic.Output */ +.gp { color: #555555 } /* Generic.Prompt */ +.gs { font-weight: bold } /* Generic.Strong */ +.gu { color: #aaaaaa } /* Generic.Subheading */ +.gt { color: #aa0000 } /* Generic.Traceback */ +.kc { color: #000000; font-weight: bold } /* Keyword.Constant */ +.kd { color: #000000; font-weight: bold } /* Keyword.Declaration */ +.kn { color: #000000; font-weight: bold } /* Keyword.Namespace */ +.kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */ +.kr { color: #000000; font-weight: bold } /* Keyword.Reserved */ +.kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.m { color: #009999 } /* Literal.Number */ +.s { color: #d01040 } /* Literal.String */ +.na { color: #008080 } /* Name.Attribute */ +.nb { color: #0086B3 } /* Name.Builtin */ +.nc { color: #445588; font-weight: bold } /* Name.Class */ +.no { color: #008080 } /* Name.Constant */ +.nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */ +.ni { color: #800080 } /* Name.Entity */ +.ne { color: #990000; font-weight: bold } /* Name.Exception */ +.nf { color: #990000; font-weight: bold } /* Name.Function */ +.nl { color: #990000; font-weight: bold } /* Name.Label */ +.nn { color: #555555 } /* Name.Namespace */ +.nt { color: #000080 } /* Name.Tag */ +.nv { color: #008080 } /* Name.Variable */ +.ow { color: #000000; font-weight: bold } /* Operator.Word */ +.w { color: #bbbbbb } /* Text.Whitespace */ +.mf { color: #009999 } /* Literal.Number.Float */ +.mh { color: #009999 } /* Literal.Number.Hex */ +.mi { color: #009999 } /* Literal.Number.Integer */ +.mo { color: #009999 } /* Literal.Number.Oct */ +.sb { color: #d01040 } /* Literal.String.Backtick */ +.sc { color: #d01040 } /* Literal.String.Char */ +.sd { color: #d01040 } /* Literal.String.Doc */ +.s2 { color: #d01040 } /* Literal.String.Double */ +.se { color: #d01040 } /* Literal.String.Escape */ +.sh { color: #d01040 } /* Literal.String.Heredoc */ +.si { color: #d01040 } /* Literal.String.Interpol */ +.sx { color: #d01040 } /* Literal.String.Other */ +.sr { color: #009926 } /* Literal.String.Regex */ +.s1 { color: #d01040 } /* Literal.String.Single */ +.ss { color: #990073 } /* Literal.String.Symbol */ +.bp { color: #999999 } /* Name.Builtin.Pseudo */ +.vc { color: #008080 } /* Name.Variable.Class */ +.vg { color: #008080 } /* Name.Variable.Global */ +.vi { color: #008080 } /* Name.Variable.Instance */ +.il { color: #009999 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be79..4bd55cf 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,20 @@ module ApplicationHelper + class HTMLwithPygments < Redcarpet::Render::HTML + def block_code(code, language) + Pygments.highlight(code, lexer: language) + end + end + def markdown(content) + renderer = HTMLwithPygments.new(hard_wrap: true, filter_html:true) + options = { + autolink: true, + no_intra_emphasis: true, + disable_indented_code_blocks: true, + fenced_code_blocks: true, + lax_html_blocks: true, + strikethrough: true, + superscript: true + } + Redcarpet::Markdown.new(renderer, options).render(content).html_safe + end end diff --git a/app/views/posts/show.html.erb b/app/views/posts/show.html.erb index 547efe9..1cb6600 100644 --- a/app/views/posts/show.html.erb +++ b/app/views/posts/show.html.erb @@ -6,7 +6,7 @@
- <%= @post.content%> + <%= markdown @post.content %>
@@ -24,8 +24,7 @@

-<% if false %> + <%= link_to "Back", root_path %> <%= link_to "Edit", edit_post_path(@post) %> <%= link_to "Delete", post_path(@post), method: :delete, data: { confirm: "Are you sure you want to delete this post?"} %> -<% end %> \ No newline at end of file From 583aefe349cd26356014b1e9e4d90e18bea55e37 Mon Sep 17 00:00:00 2001 From: git4ruby Date: Wed, 18 May 2016 01:34:17 -0500 Subject: [PATCH 02/17] Added pg& Rai;s_12factor gems to heroku --- Gemfile | 11 ++++++++++- Gemfile.lock | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 995ae83..9a80e11 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,8 @@ source 'https://rubygems.org' +ruby '2.2.0' + gem 'rails', '4.2.4' -gem 'sqlite3' gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.1.0' @@ -19,3 +20,11 @@ group :development, :test do gem 'spring' end +group :development do + gem 'sqlite3' +end + +group :production do + gem 'pg' + gem 'rails_12factor' +end \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index e96879d..f4403ef 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,6 +77,7 @@ GEM multi_json (1.12.0) nokogiri (1.6.7.2) mini_portile2 (~> 2.0.0.rc2) + pg (0.18.4) posix-spawn (0.3.11) pygments.rb (0.6.3) posix-spawn (~> 0.3.6) @@ -103,6 +104,11 @@ GEM rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) + rails_12factor (0.0.3) + rails_serve_static_assets + rails_stdout_logging + rails_serve_static_assets (0.0.5) + rails_stdout_logging (0.0.4) railties (4.2.4) actionpack (= 4.2.4) activesupport (= 4.2.4) @@ -156,8 +162,10 @@ DEPENDENCIES font-awesome-sass jbuilder (~> 2.0) jquery-rails + pg pygments.rb (~> 0.6.0) rails (= 4.2.4) + rails_12factor redcarpet (~> 3.2.2) sass-rails (~> 5.0) sdoc (~> 0.4.0) From a5e67906e8d7b782906b5b6ef5cb465345c4b3ad Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 12:57:54 -0500 Subject: [PATCH 03/17] Changed name showing near share --- app/views/posts/show.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/show.html.erb b/app/views/posts/show.html.erb index 1cb6600..4b659b9 100644 --- a/app/views/posts/show.html.erb +++ b/app/views/posts/show.html.erb @@ -12,7 +12,7 @@
-

Share The Do List

+

Share <%= @post.title %>

From f2166529a87966424352506f67c7f1c57ec0cd20 Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 14:14:42 -0500 Subject: [PATCH 04/17] Added disqus comments to posts show page --- app/views/posts/_disqus.html.erb | 17 +++++++++++++++++ app/views/posts/show.html.erb | 2 ++ 2 files changed, 19 insertions(+) create mode 100644 app/views/posts/_disqus.html.erb diff --git a/app/views/posts/_disqus.html.erb b/app/views/posts/_disqus.html.erb new file mode 100644 index 0000000..87b6514 --- /dev/null +++ b/app/views/posts/_disqus.html.erb @@ -0,0 +1,17 @@ +
+ + \ No newline at end of file diff --git a/app/views/posts/show.html.erb b/app/views/posts/show.html.erb index 1cb6600..de49a54 100644 --- a/app/views/posts/show.html.erb +++ b/app/views/posts/show.html.erb @@ -19,6 +19,8 @@

+ + <%= render 'disqus' %>
From 80a60e244cbb03593659c19cab8f42d2a6d5e7bb Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 14:42:02 -0500 Subject: [PATCH 05/17] Added Friendly_ID gem & setup friendly_id to posts --- Gemfile | 1 + Gemfile.lock | 3 + app/controllers/posts_controller.rb | 4 +- app/models/post.rb | 2 + config/initializers/friendly_id.rb | 88 +++++++++++++++++++ ...20160520193405_create_friendly_id_slugs.rb | 15 ++++ .../20160520193541_add_slug_to_posts.rb | 6 ++ db/schema.rb | 18 +++- 8 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 config/initializers/friendly_id.rb create mode 100644 db/migrate/20160520193405_create_friendly_id_slugs.rb create mode 100644 db/migrate/20160520193541_add_slug_to_posts.rb diff --git a/Gemfile b/Gemfile index 9a80e11..72900d1 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,7 @@ gem 'sdoc', '~> 0.4.0', group: :doc gem 'font-awesome-sass' gem 'pygments.rb', '~>0.6.0' gem 'redcarpet', '~>3.2.2' +gem 'friendly_id', '~> 5.1' group :development, :test do gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index f4403ef..9c0d6a0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,6 +54,8 @@ GEM execjs (2.6.0) font-awesome-sass (4.6.2) sass (>= 3.2) + friendly_id (5.1.0) + activerecord (>= 4.0.0) globalid (0.3.6) activesupport (>= 4.1.0) i18n (0.7.0) @@ -160,6 +162,7 @@ DEPENDENCIES byebug coffee-rails (~> 4.1.0) font-awesome-sass + friendly_id (~> 5.1) jbuilder (~> 2.0) jquery-rails pg diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 7cfa2e7..f45862a 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -43,10 +43,10 @@ def destroy private def post_params - params.require(:post).permit(:title,:content) + params.require(:post).permit(:title,:content, :slug) end def find_post - @post = Post.find(params[:id]) + @post = Post.friendly.find(params[:id]) end end diff --git a/app/models/post.rb b/app/models/post.rb index 791dcb5..2d666bb 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,2 +1,4 @@ class Post < ActiveRecord::Base + extend FriendlyId + friendly_id :title, use: :slugged end diff --git a/config/initializers/friendly_id.rb b/config/initializers/friendly_id.rb new file mode 100644 index 0000000..f064f1e --- /dev/null +++ b/config/initializers/friendly_id.rb @@ -0,0 +1,88 @@ +# FriendlyId Global Configuration +# +# Use this to set up shared configuration options for your entire application. +# Any of the configuration options shown here can also be applied to single +# models by passing arguments to the `friendly_id` class method or defining +# methods in your model. +# +# To learn more, check out the guide: +# +# http://norman.github.io/friendly_id/file.Guide.html + +FriendlyId.defaults do |config| + # ## Reserved Words + # + # Some words could conflict with Rails's routes when used as slugs, or are + # undesirable to allow as slugs. Edit this list as needed for your app. + config.use :reserved + + config.reserved_words = %w(new edit index session login logout users admin + stylesheets assets javascripts images) + + # ## Friendly Finders + # + # Uncomment this to use friendly finders in all models. By default, if + # you wish to find a record by its friendly id, you must do: + # + # MyModel.friendly.find('foo') + # + # If you uncomment this, you can do: + # + # MyModel.find('foo') + # + # This is significantly more convenient but may not be appropriate for + # all applications, so you must explicity opt-in to this behavior. You can + # always also configure it on a per-model basis if you prefer. + # + # Something else to consider is that using the :finders addon boosts + # performance because it will avoid Rails-internal code that makes runtime + # calls to `Module.extend`. + # + # config.use :finders + # + # ## Slugs + # + # Most applications will use the :slugged module everywhere. If you wish + # to do so, uncomment the following line. + # + # config.use :slugged + # + # By default, FriendlyId's :slugged addon expects the slug column to be named + # 'slug', but you can change it if you wish. + # + # config.slug_column = 'slug' + # + # When FriendlyId can not generate a unique ID from your base method, it appends + # a UUID, separated by a single dash. You can configure the character used as the + # separator. If you're upgrading from FriendlyId 4, you may wish to replace this + # with two dashes. + # + # config.sequence_separator = '-' + # + # ## Tips and Tricks + # + # ### Controlling when slugs are generated + # + # As of FriendlyId 5.0, new slugs are generated only when the slug field is + # nil, but if you're using a column as your base method can change this + # behavior by overriding the `should_generate_new_friendly_id` method that + # FriendlyId adds to your model. The change below makes FriendlyId 5.0 behave + # more like 4.0. + # + # config.use Module.new { + # def should_generate_new_friendly_id? + # slug.blank? || _changed? + # end + # } + # + # FriendlyId uses Rails's `parameterize` method to generate slugs, but for + # languages that don't use the Roman alphabet, that's not usually sufficient. + # Here we use the Babosa library to transliterate Russian Cyrillic slugs to + # ASCII. If you use this, don't forget to add "babosa" to your Gemfile. + # + # config.use Module.new { + # def normalize_friendly_id(text) + # text.to_slug.normalize! :transliterations => [:russian, :latin] + # end + # } +end diff --git a/db/migrate/20160520193405_create_friendly_id_slugs.rb b/db/migrate/20160520193405_create_friendly_id_slugs.rb new file mode 100644 index 0000000..770f626 --- /dev/null +++ b/db/migrate/20160520193405_create_friendly_id_slugs.rb @@ -0,0 +1,15 @@ +class CreateFriendlyIdSlugs < ActiveRecord::Migration + def change + create_table :friendly_id_slugs do |t| + t.string :slug, :null => false + t.integer :sluggable_id, :null => false + t.string :sluggable_type, :limit => 50 + t.string :scope + t.datetime :created_at + end + add_index :friendly_id_slugs, :sluggable_id + add_index :friendly_id_slugs, [:slug, :sluggable_type] + add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], :unique => true + add_index :friendly_id_slugs, :sluggable_type + end +end diff --git a/db/migrate/20160520193541_add_slug_to_posts.rb b/db/migrate/20160520193541_add_slug_to_posts.rb new file mode 100644 index 0000000..3d2f216 --- /dev/null +++ b/db/migrate/20160520193541_add_slug_to_posts.rb @@ -0,0 +1,6 @@ +class AddSlugToPosts < ActiveRecord::Migration + def change + add_column :posts, :slug, :string + add_index :posts, :slug, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index a4e0767..e7942d7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,13 +11,29 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160517210914) do +ActiveRecord::Schema.define(version: 20160520193541) do + + create_table "friendly_id_slugs", force: :cascade do |t| + t.string "slug", null: false + t.integer "sluggable_id", null: false + t.string "sluggable_type", limit: 50 + t.string "scope" + t.datetime "created_at" + end + + add_index "friendly_id_slugs", ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true + add_index "friendly_id_slugs", ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type" + add_index "friendly_id_slugs", ["sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_id" + add_index "friendly_id_slugs", ["sluggable_type"], name: "index_friendly_id_slugs_on_sluggable_type" create_table "posts", force: :cascade do |t| t.string "title" t.text "content" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "slug" end + add_index "posts", ["slug"], name: "index_posts_on_slug", unique: true + end From bbe50b5e4c05e7767d6bcc0f291b06bd945cec44 Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 15:38:57 -0500 Subject: [PATCH 06/17] Added posts to Posts index file --- app/controllers/posts_controller.rb | 1 + app/views/posts/index.html.erb | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index f45862a..c7e5eda 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -3,6 +3,7 @@ class PostsController < ApplicationController before_action :find_post, only: [:show, :update, :destroy, :edit] def index + @posts = Post.all.order("created_at desc") end diff --git a/app/views/posts/index.html.erb b/app/views/posts/index.html.erb index 715f4a3..a81fe85 100644 --- a/app/views/posts/index.html.erb +++ b/app/views/posts/index.html.erb @@ -1 +1,19 @@ -

This is Index Page

\ No newline at end of file +

Stuff I've Written

+ + +
+ <% @posts.each do |post| %> +
+

<%= post.created_at.strftime('%A, %B %d') %>

+

<%= link_to post.title, post %>

+
+
+ <% end %> +
+ + From a189af0fc6d8a2809d063c7eb999cb017bed0a8d Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 16:00:47 -0500 Subject: [PATCH 07/17] Added will paginate gem for pagination for posts --- Gemfile | 1 + Gemfile.lock | 2 ++ app/controllers/posts_controller.rb | 2 +- app/views/posts/index.html.erb | 7 +------ 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 72900d1..81189c5 100644 --- a/Gemfile +++ b/Gemfile @@ -14,6 +14,7 @@ gem 'font-awesome-sass' gem 'pygments.rb', '~>0.6.0' gem 'redcarpet', '~>3.2.2' gem 'friendly_id', '~> 5.1' +gem 'will_paginate', '~> 3.1' group :development, :test do gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index 9c0d6a0..73aa52f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -153,6 +153,7 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) + will_paginate (3.1.0) yajl-ruby (1.2.1) PLATFORMS @@ -177,6 +178,7 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) web-console (~> 2.0) + will_paginate (~> 3.1) BUNDLED WITH 1.10.6 diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index c7e5eda..f5dcbe0 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -3,7 +3,7 @@ class PostsController < ApplicationController before_action :find_post, only: [:show, :update, :destroy, :edit] def index - @posts = Post.all.order("created_at desc") + @posts = Post.all.order("created_at desc").paginate(page: params[:page], per_page: 3) end diff --git a/app/views/posts/index.html.erb b/app/views/posts/index.html.erb index a81fe85..3e1d0f2 100644 --- a/app/views/posts/index.html.erb +++ b/app/views/posts/index.html.erb @@ -10,10 +10,5 @@ <% end %> - +<%= will_paginate @posts %> \ No newline at end of file From d9f8dac3de219dea190038ae54e42f876c60b0d1 Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 17:15:05 -0500 Subject: [PATCH 08/17] Created Projects and its functionality --- app/assets/javascripts/projects.coffee | 3 ++ .../application.css.scssc | Bin 36606 -> 38799 bytes app/assets/stylesheets/application.css.scss | 12 +++++++ app/assets/stylesheets/projects.scss | 3 ++ app/controllers/projects_controller.rb | 34 ++++++++++++++++++ app/controllers/welcome_controller.rb | 1 + app/helpers/projects_helper.rb | 2 ++ app/models/project.rb | 2 ++ app/views/layouts/application.html.erb | 1 + app/views/posts/_form.html.erb | 2 +- app/views/projects/_form.html.erb | 31 ++++++++++++++++ app/views/projects/index.html.erb | 12 +++++++ app/views/projects/new.html.erb | 4 +++ app/views/projects/show.html.erb | 23 ++++++++++++ app/views/welcome/index.html.erb | 11 +++--- config/routes.rb | 1 + db/migrate/20160520210635_create_projects.rb | 11 ++++++ db/schema.rb | 10 +++++- test/controllers/projects_controller_test.rb | 7 ++++ test/fixtures/projects.yml | 11 ++++++ test/models/project_test.rb | 7 ++++ 21 files changed, 179 insertions(+), 9 deletions(-) create mode 100644 app/assets/javascripts/projects.coffee create mode 100644 app/assets/stylesheets/projects.scss create mode 100644 app/controllers/projects_controller.rb create mode 100644 app/helpers/projects_helper.rb create mode 100644 app/models/project.rb create mode 100644 app/views/projects/_form.html.erb create mode 100644 app/views/projects/index.html.erb create mode 100644 app/views/projects/new.html.erb create mode 100644 app/views/projects/show.html.erb create mode 100644 db/migrate/20160520210635_create_projects.rb create mode 100644 test/controllers/projects_controller_test.rb create mode 100644 test/fixtures/projects.yml create mode 100644 test/models/project_test.rb diff --git a/app/assets/javascripts/projects.coffee b/app/assets/javascripts/projects.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/projects.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/.sass-cache/ab5c96180a20dcd6f1c0c702a2059ca1c5a69e5d/application.css.scssc b/app/assets/stylesheets/.sass-cache/ab5c96180a20dcd6f1c0c702a2059ca1c5a69e5d/application.css.scssc index 14a74c82f3f2647e542b56695ecb08c57dd774a4..46173cd14800ba9a3afe527dd851bb348746ca58 100644 GIT binary patch delta 1323 zcmZuxOHUI~7*wTX2B1kmBK55IvI3~J)m=K5?B?8k2?I^UhDQO}>MY=Na zf#1TFVWFGW z{INtl5DG5)gW-5`-0M$7LXq)E#P1WM;ZQ6hdY2Q??ORtUzAWXo;JLfUVjIilvyYPT z!eVT#P{?NB#pH;cZLM`7-94n2s4|GxhJa^HkTWx8s*Fax^>SlxHqF|~$Rc$iYZjTi z8#@+>gQfX?I4!aOFRu>oAww1!b;#6&>|usYV<^i(pu(5#P#vK?ZBW!J7!fO&(9K3$ zf&Qf`p$O`wOE{}c8L zY~zO2`xNL?!uT?5_YUZ6V~tEL0&f_Boyl%Hs}_oRF_%l`o57M>gC(oMk`)CRaIh>g zJ`fQs8D_Xa_+WK1reJcF_bLxi582^ryAxGRv}jH!O9!0Zx4Szc2{Wp2vcwsu2s5hi zJLoh}YDa;dX5i%MjJwt@S;HDcq-)??cXdV)ay6KpIj~c0_eCMb=-wpf{+S{MzP@rs sb7CSPWl|Ho4_~=Ixr&$#hG|AjO_b7gRm`WP%ml9`5HnA`=F*ma`O9aWKOmtLd zl-rnD&^&oxx2)nOYo2^-UQTPid~1GoYwk?OP1XXLeAa?+?&Lq+mXnRzL diff --git a/app/views/posts/_form.html.erb b/app/views/posts/_form.html.erb index 55f191a..d84cac7 100644 --- a/app/views/posts/_form.html.erb +++ b/app/views/posts/_form.html.erb @@ -2,7 +2,7 @@ <% if @post.errors.any? %>

<%= pluraize(@post.errors.count, "error") %> prevented this post from saving:

    - <% @posts.errors.full_messages.each do |msg| %> + <% @post.errors.full_messages.each do |msg| %>
  • <%= msg %>
  • <% end %>
diff --git a/app/views/projects/_form.html.erb b/app/views/projects/_form.html.erb new file mode 100644 index 0000000..be6f0cc --- /dev/null +++ b/app/views/projects/_form.html.erb @@ -0,0 +1,31 @@ +<%= form_for @project do |f| %> + <% if @project.errors.any? %> +

<%= pluraize(@project.errors.count, "error") %> prevented this project from saving:

+
    + <% @project.errors.full_messages.each do |msg| %> +
  • <%= msg %>
  • + <% end %> +
+ <% end %> + + <%= f.label :title %>
+ <%= f.text_field :title %> + +
+
+ + <%= f.label :description %>
+ <%= f.text_area :description %> + +
+
+ + <%= f.label :link %>
+ <%= f.text_field :link %> + +
+
+ + <%= f.submit %> + +<% end %> \ No newline at end of file diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb new file mode 100644 index 0000000..6cfedb0 --- /dev/null +++ b/app/views/projects/index.html.erb @@ -0,0 +1,12 @@ +

Stuff I've Built

+ + +
+ <% @projects.each do |project| %> +
+

<%= project.created_at.strftime('%A, %B %d') %>

+

<%= link_to project.title, project %>

+
+
+ <% end %> +
diff --git a/app/views/projects/new.html.erb b/app/views/projects/new.html.erb new file mode 100644 index 0000000..257a612 --- /dev/null +++ b/app/views/projects/new.html.erb @@ -0,0 +1,4 @@ +
+

New Project

+ <%= render 'form' %> +
\ No newline at end of file diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb new file mode 100644 index 0000000..8ba628f --- /dev/null +++ b/app/views/projects/show.html.erb @@ -0,0 +1,23 @@ +
+
+

<%= @project.created_at.strftime('%A, %B %d') %>

+

<%= @project.title %>

+
+
+
+ + <%= markdown @project.description %> + + +
+ +
+
+ + + +<%= link_to "Back", root_path %> +<%= link_to "Edit", edit_post_path(@project) %> +<%= link_to "Delete", post_path(@project), method: :delete, data: { confirm: "Are you sure you want to delete this post?"} %> diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index b4d43c3..652ed38 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -19,12 +19,9 @@

Stuff I've built


-

Begginers Code

-

Friday May 13th

-

Movie Reviews

-

Friday May 13th

-

ToDo Lists

-

Friday May 13th

- + <% @projects.each do |project| %> +

<%= link_to project.title, project %>

+

<%= project.created_at.strftime("%A, %b %d")%>

+ <% end %> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index a7d6e72..e23c609 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,6 @@ Rails.application.routes.draw do resources :posts + resources :projects get 'welcome/index' root 'welcome#index' end diff --git a/db/migrate/20160520210635_create_projects.rb b/db/migrate/20160520210635_create_projects.rb new file mode 100644 index 0000000..24d99fc --- /dev/null +++ b/db/migrate/20160520210635_create_projects.rb @@ -0,0 +1,11 @@ +class CreateProjects < ActiveRecord::Migration + def change + create_table :projects do |t| + t.string :title + t.text :description + t.string :link + + t.timestamps null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index e7942d7..36e3c5d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160520193541) do +ActiveRecord::Schema.define(version: 20160520210635) do create_table "friendly_id_slugs", force: :cascade do |t| t.string "slug", null: false @@ -36,4 +36,12 @@ add_index "posts", ["slug"], name: "index_posts_on_slug", unique: true + create_table "projects", force: :cascade do |t| + t.string "title" + t.text "description" + t.string "link" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + end diff --git a/test/controllers/projects_controller_test.rb b/test/controllers/projects_controller_test.rb new file mode 100644 index 0000000..c098166 --- /dev/null +++ b/test/controllers/projects_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class ProjectsControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/fixtures/projects.yml b/test/fixtures/projects.yml new file mode 100644 index 0000000..466f342 --- /dev/null +++ b/test/fixtures/projects.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + title: MyString + description: MyText + link: MyString + +two: + title: MyString + description: MyText + link: MyString diff --git a/test/models/project_test.rb b/test/models/project_test.rb new file mode 100644 index 0000000..0821e1f --- /dev/null +++ b/test/models/project_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class ProjectTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end From 801bd17302cae975fe709b14ae1440ce5a48cee3 Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 17:24:06 -0500 Subject: [PATCH 09/17] Added friendly_id to projects --- app/controllers/projects_controller.rb | 4 ++-- app/models/project.rb | 2 ++ db/migrate/20160520221649_add_slug_to_projects.rb | 6 ++++++ db/schema.rb | 5 ++++- 4 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20160520221649_add_slug_to_projects.rb diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index cfe5e3c..161ef4a 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -25,10 +25,10 @@ def show private def find_project - @project = Project.find(params[:id]) + @project = Project.friendly.find(params[:id]) end def project_params - params.require(:project).permit(:title, :description, :link) + params.require(:project).permit(:title, :description, :link, :slug) end end diff --git a/app/models/project.rb b/app/models/project.rb index 5bc7957..bb4989b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,2 +1,4 @@ class Project < ActiveRecord::Base + extend FriendlyId + friendly_id :title, use: :slugged end diff --git a/db/migrate/20160520221649_add_slug_to_projects.rb b/db/migrate/20160520221649_add_slug_to_projects.rb new file mode 100644 index 0000000..62284f7 --- /dev/null +++ b/db/migrate/20160520221649_add_slug_to_projects.rb @@ -0,0 +1,6 @@ +class AddSlugToProjects < ActiveRecord::Migration + def change + add_column :projects, :slug, :string + add_index :projects, :slug, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 36e3c5d..6f8823a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160520210635) do +ActiveRecord::Schema.define(version: 20160520221649) do create_table "friendly_id_slugs", force: :cascade do |t| t.string "slug", null: false @@ -42,6 +42,9 @@ t.string "link" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "slug" end + add_index "projects", ["slug"], name: "index_projects_on_slug", unique: true + end From 54ab8d472479186823718168f076ee9692bbce64 Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 17:50:36 -0500 Subject: [PATCH 10/17] Add edit & destroy project abilities --- app/controllers/projects_controller.rb | 17 +++++++++++++++++ app/views/layouts/application.html.erb | 1 - app/views/projects/edit.html.erb | 4 ++++ app/views/projects/show.html.erb | 10 +++++----- 4 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 app/views/projects/edit.html.erb diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 161ef4a..c88e8b7 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -22,6 +22,23 @@ def show end + def edit + + end + + def update + if @project.update project_params + redirect_to @project, notice: "Nice Mohit! Project was successfully updated!!!" + else + render 'edit', notice: "Oops! Project couldn't be updated!!!" + end + end + + def destroy + @project.destroy + redirect_to projects_path + end + private def find_project diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index a2c66df..bc7309e 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -16,7 +16,6 @@ diff --git a/app/views/projects/edit.html.erb b/app/views/projects/edit.html.erb new file mode 100644 index 0000000..4fab67f --- /dev/null +++ b/app/views/projects/edit.html.erb @@ -0,0 +1,4 @@ +
+

Edit Project

+ <%= render 'form' %> +
\ No newline at end of file diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb index 8ba628f..3960a22 100644 --- a/app/views/projects/show.html.erb +++ b/app/views/projects/show.html.erb @@ -13,11 +13,11 @@ -
- +<%= link_to "Back", root_path %> +<%= link_to "Edit", edit_project_path(@project) %> +<%= link_to "Delete", project_path(@project), method: :delete, data: { confirm: "Are you sure you want to delete this post?"} %> -<%= link_to "Back", root_path %> -<%= link_to "Edit", edit_post_path(@project) %> -<%= link_to "Delete", post_path(@project), method: :delete, data: { confirm: "Are you sure you want to delete this post?"} %> +
+ From 50b73d71cd245ba3077ac32c5b1d49ee86bbae69 Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 18:45:43 -0500 Subject: [PATCH 11/17] Setup Contact us form --- Gemfile | 1 + Gemfile.lock | 4 +++ app/assets/javascripts/contacts.coffee | 3 +++ .../application.css.scssc | Bin 38799 -> 39335 bytes app/assets/stylesheets/application.css.scss | 3 +++ app/assets/stylesheets/contacts.scss | 3 +++ app/controllers/contacts_controller.rb | 18 +++++++++++++ app/helpers/contacts_helper.rb | 2 ++ app/models/contact.rb | 14 ++++++++++ app/views/contacts/create.html.erb | 6 +++++ app/views/contacts/new.html.erb | 25 ++++++++++++++++++ config/routes.rb | 2 ++ test/controllers/contacts_controller_test.rb | 7 +++++ 13 files changed, 88 insertions(+) create mode 100644 app/assets/javascripts/contacts.coffee create mode 100644 app/assets/stylesheets/contacts.scss create mode 100644 app/controllers/contacts_controller.rb create mode 100644 app/helpers/contacts_helper.rb create mode 100644 app/models/contact.rb create mode 100644 app/views/contacts/create.html.erb create mode 100644 app/views/contacts/new.html.erb create mode 100644 test/controllers/contacts_controller_test.rb diff --git a/Gemfile b/Gemfile index 81189c5..afca539 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,7 @@ gem 'pygments.rb', '~>0.6.0' gem 'redcarpet', '~>3.2.2' gem 'friendly_id', '~> 5.1' gem 'will_paginate', '~> 3.1' +gem 'mail_form', '~> 1.5', '>= 1.5.1' group :development, :test do gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index 73aa52f..1232889 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -71,6 +71,9 @@ GEM nokogiri (>= 1.5.9) mail (2.6.4) mime-types (>= 1.16, < 4) + mail_form (1.5.1) + actionmailer (>= 3.2, < 5) + activemodel (>= 3.2, < 5) mime-types (3.0) mime-types-data (~> 3.2015) mime-types-data (3.2016.0221) @@ -166,6 +169,7 @@ DEPENDENCIES friendly_id (~> 5.1) jbuilder (~> 2.0) jquery-rails + mail_form (~> 1.5, >= 1.5.1) pg pygments.rb (~> 0.6.0) rails (= 4.2.4) diff --git a/app/assets/javascripts/contacts.coffee b/app/assets/javascripts/contacts.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/contacts.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/.sass-cache/ab5c96180a20dcd6f1c0c702a2059ca1c5a69e5d/application.css.scssc b/app/assets/stylesheets/.sass-cache/ab5c96180a20dcd6f1c0c702a2059ca1c5a69e5d/application.css.scssc index 46173cd14800ba9a3afe527dd851bb348746ca58..cc5422db69b49732892ed5c3320e95f853932644 100644 GIT binary patch literal 39335 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 PaA`J}mDD+gEZ_e>v)x%3 literal 38799 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 true + attribute :email, :validate => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i + attribute :message, :validate => true + attribute :nickname, :captcha => true + + def headers + { + :subject => "Contact Form", + :to => "chandanamohit@gmail.com", + :from => %("#{name}" <#{email}>) + } + end +end \ No newline at end of file diff --git a/app/views/contacts/create.html.erb b/app/views/contacts/create.html.erb new file mode 100644 index 0000000..113a1c1 --- /dev/null +++ b/app/views/contacts/create.html.erb @@ -0,0 +1,6 @@ +

Say Hello!

+ +
+

Thank you for your message

+

I will get back to you soon!

+
\ No newline at end of file diff --git a/app/views/contacts/new.html.erb b/app/views/contacts/new.html.erb new file mode 100644 index 0000000..238c02e --- /dev/null +++ b/app/views/contacts/new.html.erb @@ -0,0 +1,25 @@ +

Say Hello!

+ +
+ + <%= form_for @contact do |f| %> + + <%= f.label :name %>
+ <%= f.text_field :name, required: true %> +
+ <%= f.label :email %>
+ <%= f.email_field :email, required: true %> +
+ <%= f.label :message %>
+ <%= f.text_area :message, as: :text %> + + + + <%= f.submit 'Send Message', class: "button"%> + + <% end %> + +
diff --git a/config/routes.rb b/config/routes.rb index e23c609..28c3cbb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,8 @@ Rails.application.routes.draw do resources :posts resources :projects + resources :contacts, only: [:new, :create] get 'welcome/index' root 'welcome#index' + end diff --git a/test/controllers/contacts_controller_test.rb b/test/controllers/contacts_controller_test.rb new file mode 100644 index 0000000..d711f08 --- /dev/null +++ b/test/controllers/contacts_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class ContactsControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end From bca727d15fad965f964f6a3fb809211b7a537fbe Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 18:53:11 -0500 Subject: [PATCH 12/17] Added sendgrid production configuration --- config/environments/production.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/config/environments/production.rb b/config/environments/production.rb index 5c1b32e..0c9a2a3 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -76,4 +76,18 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + config.action_mailer.default_url_options = { host: 'https://blooming-caverns-69343.herokuapp.com'} + config.action_mailer.delivery_method = :smtp + + ActionMailer::Base.smtp_settings = { + :address => 'smtp.sendgrid.net', + :port => '587', + :authentication => :plain, + :user_name => ENV['SENDGRID_USERNAME'], + :password => ENV['SENDGRID_PASSWORD'], + :domain => 'heroku.com', + :enable_starttls_auto => true + } + end From 18c2db8d3f4fb2966791f2333c46f83487289bff Mon Sep 17 00:00:00 2001 From: git4ruby Date: Fri, 20 May 2016 19:09:51 -0500 Subject: [PATCH 13/17] Added link to contact button on home screen --- app/views/layouts/application.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index bc7309e..72b8f52 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -16,7 +16,7 @@ From 391eb504f85822051576a251646595b08ba8eedd Mon Sep 17 00:00:00 2001 From: git4ruby Date: Sat, 21 May 2016 14:37:39 -0500 Subject: [PATCH 14/17] Setup devise gem for authentication --- Gemfile | 1 + Gemfile.lock | 14 + app/controllers/posts_controller.rb | 1 + app/controllers/projects_controller.rb | 2 + app/models/user.rb | 6 + app/views/devise/confirmations/new.html.erb | 16 ++ .../mailer/confirmation_instructions.html.erb | 5 + .../devise/mailer/password_change.html.erb | 3 + .../reset_password_instructions.html.erb | 8 + .../mailer/unlock_instructions.html.erb | 7 + app/views/devise/passwords/edit.html.erb | 25 ++ app/views/devise/passwords/new.html.erb | 16 ++ app/views/devise/registrations/edit.html.erb | 39 +++ app/views/devise/registrations/new.html.erb | 29 ++ app/views/devise/sessions/new.html.erb | 26 ++ app/views/devise/shared/_links.html.erb | 25 ++ app/views/devise/unlocks/new.html.erb | 16 ++ app/views/layouts/application.html.erb | 6 + config/initializers/devise.rb | 265 ++++++++++++++++++ config/locales/devise.en.yml | 62 ++++ config/routes.rb | 1 + .../20160521193028_devise_create_users.rb | 42 +++ db/schema.rb | 20 +- test/fixtures/users.yml | 11 + test/models/user_test.rb | 7 + 25 files changed, 652 insertions(+), 1 deletion(-) create mode 100644 app/models/user.rb create mode 100644 app/views/devise/confirmations/new.html.erb create mode 100644 app/views/devise/mailer/confirmation_instructions.html.erb create mode 100644 app/views/devise/mailer/password_change.html.erb create mode 100644 app/views/devise/mailer/reset_password_instructions.html.erb create mode 100644 app/views/devise/mailer/unlock_instructions.html.erb create mode 100644 app/views/devise/passwords/edit.html.erb create mode 100644 app/views/devise/passwords/new.html.erb create mode 100644 app/views/devise/registrations/edit.html.erb create mode 100644 app/views/devise/registrations/new.html.erb create mode 100644 app/views/devise/sessions/new.html.erb create mode 100644 app/views/devise/shared/_links.html.erb create mode 100644 app/views/devise/unlocks/new.html.erb create mode 100644 config/initializers/devise.rb create mode 100644 config/locales/devise.en.yml create mode 100644 db/migrate/20160521193028_devise_create_users.rb create mode 100644 test/fixtures/users.yml create mode 100644 test/models/user_test.rb diff --git a/Gemfile b/Gemfile index afca539..0bc941f 100644 --- a/Gemfile +++ b/Gemfile @@ -16,6 +16,7 @@ gem 'redcarpet', '~>3.2.2' gem 'friendly_id', '~> 5.1' gem 'will_paginate', '~> 3.1' gem 'mail_form', '~> 1.5', '>= 1.5.1' +gem 'devise', '~> 3.5', '>= 3.5.6' group :development, :test do gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index 1232889..89e3b06 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -37,6 +37,7 @@ GEM thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) arel (6.0.3) + bcrypt (3.1.11) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) builder (3.2.2) @@ -50,6 +51,13 @@ GEM coffee-script-source (1.10.0) concurrent-ruby (1.0.2) debug_inspector (0.0.2) + devise (3.5.10) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 3.2.6, < 5) + responders + thread_safe (~> 0.1) + warden (~> 1.2.3) erubis (2.7.0) execjs (2.6.0) font-awesome-sass (4.6.2) @@ -82,6 +90,7 @@ GEM multi_json (1.12.0) nokogiri (1.6.7.2) mini_portile2 (~> 2.0.0.rc2) + orm_adapter (0.5.0) pg (0.18.4) posix-spawn (0.3.11) pygments.rb (0.6.3) @@ -123,6 +132,8 @@ GEM rdoc (4.2.2) json (~> 1.4) redcarpet (3.2.3) + responders (2.2.0) + railties (>= 4.2.0, < 5.1) sass (3.4.22) sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) @@ -151,6 +162,8 @@ GEM thread_safe (~> 0.1) uglifier (3.0.0) execjs (>= 0.3.0, < 3) + warden (1.2.6) + rack (>= 1.0) web-console (2.3.0) activemodel (>= 4.0) binding_of_caller (>= 0.7.2) @@ -165,6 +178,7 @@ PLATFORMS DEPENDENCIES byebug coffee-rails (~> 4.1.0) + devise (~> 3.5, >= 3.5.6) font-awesome-sass friendly_id (~> 5.1) jbuilder (~> 2.0) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index f5dcbe0..032a16e 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -1,6 +1,7 @@ class PostsController < ApplicationController before_action :find_post, only: [:show, :update, :destroy, :edit] + before_action :authenticate_user!, except: [:index, :show] def index @posts = Post.all.order("created_at desc").paginate(page: params[:page], per_page: 3) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index c88e8b7..ed667f3 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -1,5 +1,7 @@ class ProjectsController < ApplicationController before_action :find_project, only: [:show, :edit, :update, :destroy] + before_action :authenticate_user!, except: [:index, :show] + def index @projects = Project.all.order("created_at desc") end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..c822027 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,6 @@ +class User < ActiveRecord::Base + # Include default devise modules. Others available are: + # :confirmable, :lockable, :timeoutable and :omniauthable + devise :database_authenticatable, :registerable, + :recoverable, :rememberable, :trackable, :validatable +end diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb new file mode 100644 index 0000000..826672f --- /dev/null +++ b/app/views/devise/confirmations/new.html.erb @@ -0,0 +1,16 @@ +

Resend confirmation instructions

+ +<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> + <%= devise_error_messages! %> + +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true, value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %> +
+ +
+ <%= f.submit "Resend confirmation instructions" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb new file mode 100644 index 0000000..dc55f64 --- /dev/null +++ b/app/views/devise/mailer/confirmation_instructions.html.erb @@ -0,0 +1,5 @@ +

Welcome <%= @email %>!

+ +

You can confirm your account email through the link below:

+ +

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

diff --git a/app/views/devise/mailer/password_change.html.erb b/app/views/devise/mailer/password_change.html.erb new file mode 100644 index 0000000..b41daf4 --- /dev/null +++ b/app/views/devise/mailer/password_change.html.erb @@ -0,0 +1,3 @@ +

Hello <%= @resource.email %>!

+ +

We're contacting you to notify you that your password has been changed.

diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb new file mode 100644 index 0000000..f667dc1 --- /dev/null +++ b/app/views/devise/mailer/reset_password_instructions.html.erb @@ -0,0 +1,8 @@ +

Hello <%= @resource.email %>!

+ +

Someone has requested a link to change your password. You can do this through the link below.

+ +

<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>

+ +

If you didn't request this, please ignore this email.

+

Your password won't change until you access the link above and create a new one.

diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb new file mode 100644 index 0000000..41e148b --- /dev/null +++ b/app/views/devise/mailer/unlock_instructions.html.erb @@ -0,0 +1,7 @@ +

Hello <%= @resource.email %>!

+ +

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

+ +

Click the link below to unlock your account:

+ +

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb new file mode 100644 index 0000000..6a796b0 --- /dev/null +++ b/app/views/devise/passwords/edit.html.erb @@ -0,0 +1,25 @@ +

Change your password

+ +<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %> + <%= devise_error_messages! %> + <%= f.hidden_field :reset_password_token %> + +
+ <%= f.label :password, "New password" %>
+ <% if @minimum_password_length %> + (<%= @minimum_password_length %> characters minimum)
+ <% end %> + <%= f.password_field :password, autofocus: true, autocomplete: "off" %> +
+ +
+ <%= f.label :password_confirmation, "Confirm new password" %>
+ <%= f.password_field :password_confirmation, autocomplete: "off" %> +
+ +
+ <%= f.submit "Change my password" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb new file mode 100644 index 0000000..3d6d11a --- /dev/null +++ b/app/views/devise/passwords/new.html.erb @@ -0,0 +1,16 @@ +

Forgot your password?

+ +<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %> + <%= devise_error_messages! %> + +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true %> +
+ +
+ <%= f.submit "Send me reset password instructions" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb new file mode 100644 index 0000000..3ea40f0 --- /dev/null +++ b/app/views/devise/registrations/edit.html.erb @@ -0,0 +1,39 @@ +

Edit <%= resource_name.to_s.humanize %>

+ +<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> + <%= devise_error_messages! %> + +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true %> +
+ + <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> +
Currently waiting confirmation for: <%= resource.unconfirmed_email %>
+ <% end %> + +
+ <%= f.label :password %> (leave blank if you don't want to change it)
+ <%= f.password_field :password, autocomplete: "off" %> +
+ +
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "off" %> +
+ +
+ <%= f.label :current_password %> (we need your current password to confirm your changes)
+ <%= f.password_field :current_password, autocomplete: "off" %> +
+ +
+ <%= f.submit "Update" %> +
+<% end %> + +

Cancel my account

+ +

Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %>

+ +<%= link_to "Back", :back %> diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb new file mode 100644 index 0000000..5a238ce --- /dev/null +++ b/app/views/devise/registrations/new.html.erb @@ -0,0 +1,29 @@ +

Sign up

+ +<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> + <%= devise_error_messages! %> + +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true %> +
+ +
+ <%= f.label :password %> + <% if @minimum_password_length %> + (<%= @minimum_password_length %> characters minimum) + <% end %>
+ <%= f.password_field :password, autocomplete: "off" %> +
+ +
+ <%= f.label :password_confirmation %>
+ <%= f.password_field :password_confirmation, autocomplete: "off" %> +
+ +
+ <%= f.submit "Sign up" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb new file mode 100644 index 0000000..b261cfd --- /dev/null +++ b/app/views/devise/sessions/new.html.erb @@ -0,0 +1,26 @@ +

Log in

+ +<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %> +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true %> +
+ +
+ <%= f.label :password %>
+ <%= f.password_field :password, autocomplete: "off" %> +
+ + <% if devise_mapping.rememberable? -%> +
+ <%= f.check_box :remember_me %> + <%= f.label :remember_me %> +
+ <% end -%> + +
+ <%= f.submit "Log in" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/devise/shared/_links.html.erb b/app/views/devise/shared/_links.html.erb new file mode 100644 index 0000000..e6a3e41 --- /dev/null +++ b/app/views/devise/shared/_links.html.erb @@ -0,0 +1,25 @@ +<%- if controller_name != 'sessions' %> + <%= link_to "Log in", new_session_path(resource_name) %>
+<% end -%> + +<%- if devise_mapping.registerable? && controller_name != 'registrations' %> + <%= link_to "Sign up", new_registration_path(resource_name) %>
+<% end -%> + +<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %> + <%= link_to "Forgot your password?", new_password_path(resource_name) %>
+<% end -%> + +<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> + <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
+<% end -%> + +<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> + <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
+<% end -%> + +<%- if devise_mapping.omniauthable? %> + <%- resource_class.omniauth_providers.each do |provider| %> + <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %>
+ <% end -%> +<% end -%> diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb new file mode 100644 index 0000000..16586bc --- /dev/null +++ b/app/views/devise/unlocks/new.html.erb @@ -0,0 +1,16 @@ +

Resend unlock instructions

+ +<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> + <%= devise_error_messages! %> + +
+ <%= f.label :email %>
+ <%= f.email_field :email, autofocus: true %> +
+ +
+ <%= f.submit "Resend unlock instructions" %> +
+<% end %> + +<%= render "devise/shared/links" %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 72b8f52..084260b 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -20,6 +20,12 @@ + <% if notice %> +

<%= notice %>

+ <% elsif alert %> +

<%= alert %>

+ <% end %> + <%= yield %>