happy_seed 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/bin/happy_seed_plugin +14 -0
  3. data/happy_seed.rb +1 -1
  4. data/lib/generators/happy_seed/admin/admin_generator.rb +23 -1
  5. data/lib/generators/happy_seed/admin/templates/app/admin/campaigns.rb +36 -0
  6. data/lib/generators/happy_seed/admin/templates/app/admin/dashboard.rb +54 -0
  7. data/lib/generators/happy_seed/admin/templates/app/admin/newsletter.rb +48 -0
  8. data/lib/generators/happy_seed/admin/templates/app/controllers/admin/stats_controller.rb +15 -0
  9. data/lib/generators/happy_seed/admin/templates/app/views/admin/_chart.html.haml +5 -0
  10. data/lib/generators/happy_seed/admin/templates/docs/README.07.admin.rdoc +3 -0
  11. data/lib/generators/happy_seed/admin/templates/spec/controllers/admin/stats_controller_spec.rb +40 -0
  12. data/lib/generators/happy_seed/admin/templates/spec/factories/admin_users.rb +7 -0
  13. data/lib/generators/happy_seed/admin/templates/vendor/assets/javascripts/chartkick.js +830 -0
  14. data/lib/generators/happy_seed/{foreman/foreman_generator.rb → base/base_generator.rb} +15 -1
  15. data/lib/generators/happy_seed/{foreman → base}/templates/.env +0 -0
  16. data/lib/generators/happy_seed/{foreman → base}/templates/.foreman +0 -0
  17. data/lib/generators/happy_seed/{foreman → base}/templates/Procfile +0 -0
  18. data/lib/generators/happy_seed/{foreman → base}/templates/app/controllers/setup_controller.rb +0 -0
  19. data/lib/generators/happy_seed/{foreman → base}/templates/app/views/setup/index.html.haml +0 -0
  20. data/lib/generators/happy_seed/{foreman → base}/templates/application_controller.rb +0 -0
  21. data/lib/generators/happy_seed/{foreman → base}/templates/config/unicorn.rb +0 -0
  22. data/lib/generators/happy_seed/base/templates/docs/README.00.base.rdoc +43 -0
  23. data/lib/generators/happy_seed/{foreman → base}/templates/spec/controllers/application_controller_spec.rb +0 -0
  24. data/lib/generators/happy_seed/{foreman → base}/templates/spec/controllers/setup_controller_spec.rb +0 -0
  25. data/lib/generators/happy_seed/bootstrap/templates/app/views/application/_footer.html.haml +7 -6
  26. data/lib/generators/happy_seed/bootstrap/templates/docs/README.01.bootstrap.rdoc +6 -0
  27. data/lib/generators/happy_seed/devise/devise_generator.rb +3 -0
  28. data/lib/generators/happy_seed/devise/templates/docs/README.03.devise.rdoc +5 -3
  29. data/lib/generators/happy_seed/devise/templates/spec/factories/users.rb +15 -0
  30. data/lib/generators/happy_seed/facebook/templates/docs/README.06.facebook.rdoc +4 -0
  31. data/lib/generators/happy_seed/omniauth/omniauth_generator.rb +1 -0
  32. data/lib/generators/happy_seed/omniauth/templates/docs/README.04.omniauth.rdoc +9 -5
  33. data/lib/generators/happy_seed/plugin/plugin_generator.rb +32 -0
  34. data/lib/generators/happy_seed/plugin/templates/.autotest +7 -0
  35. data/lib/generators/happy_seed/plugin/templates/.rspec +3 -0
  36. data/lib/generators/happy_seed/plugin/templates/Rakefile +25 -0
  37. data/lib/generators/happy_seed/plugin/templates/gemspec +8 -0
  38. data/lib/generators/happy_seed/plugin/templates/spec/rails_helper.rb +43 -0
  39. data/lib/generators/happy_seed/plugin/templates/spec/spec_helper.rb +20 -0
  40. data/lib/generators/happy_seed/splash/templates/app/assets/stylesheets/splash.css.scss +4 -74
  41. data/lib/generators/happy_seed/splash/templates/app/views/layouts/splash.html.haml +6 -5
  42. data/lib/generators/happy_seed/splash/templates/app/views/splash/index.html.haml +66 -178
  43. data/lib/generators/happy_seed/splash/templates/docs/README.02.splash.rdoc +6 -4
  44. data/lib/generators/happy_seed/twitter/templates/docs/README.05.twitter.rdoc +3 -1
  45. data/lib/happy_seed/version.rb +1 -1
  46. data/test/dummy/db/test.sqlite3 +0 -0
  47. data/test/dummy/log/test.log +5 -0
  48. metadata +35 -13
  49. data/lib/generators/happy_seed/foreman/templates/docs/README.00.base.rdoc +0 -34
@@ -1,6 +1,6 @@
1
1
  module HappySeed
2
2
  module Generators
3
- class ForemanGenerator < Rails::Generators::Base
3
+ class BaseGenerator < Rails::Generators::Base
4
4
  source_root File.expand_path('../templates', __FILE__)
5
5
 
6
6
  def install_foreman
@@ -26,6 +26,20 @@ module HappySeed
26
26
  say_status :spec, "Unable to add webmock to rails_helper.rb", :red
27
27
  end
28
28
 
29
+ begin
30
+ inject_into_file 'spec/rails_helper.rb', "\n config.include FactoryGirl::Syntax::Methods\n", :before => "\nend\n"
31
+ rescue
32
+ say_status :spec, "Unable to add factory girl to rails_helper.rb", :red
33
+ end
34
+
35
+ begin
36
+ prepend_to_file 'spec/spec_helper.rb', "require 'devise'\n"
37
+ inject_into_file 'spec/spec_helper.rb', "\n config.include Devise::TestHelpers, type: :controller\n", :before => "\nend\n"
38
+ rescue
39
+ say_status :spec, "Unable to add devise helpers to spec_helper.rb", :red
40
+ end
41
+
42
+
29
43
  route "get '/setup' => 'setup#index'"
30
44
  route "root 'setup#index'"
31
45
  end
@@ -0,0 +1,43 @@
1
+ HappySeed Base Install
2
+ =================
3
+
4
+ ### What does this do?
5
+
6
+ The happy_seed application template sets up haml, meta-tags, disables turbolinks, and installs the happy_seed generators into your application.
7
+
8
+ The happy_seed:base generator installs dotenv-rails, unicorn, http site authentication, and the setup_controller.
9
+
10
+ /setup is used to see the happy_seed documentation for each of the installed generators, and copies things into the rails doc directory. The setup_controller is only visible locally.
11
+
12
+ ### Why do you want this?
13
+
14
+ Haml is great and we like it better than balancing out closing tags. meta-tags makes it easy to flesh out SEO.
15
+
16
+ Turbolinks tend to be more trouble than they are worth. Outside of making web site analytics slightly more cumbersome, we end up having trouble with debugging and testing. Turbolinks work by having all of the javascript of the page loaded and resident and only replacing the body of the page when the user loads up a new page. When everything works correctly this makes things faster; when it doesn't work correctly, you end up tracking down issues where DOM event handlers aren't correctly attached.
17
+
18
+ dotenv-rails mimics the way that heroku starts up the application even when using "rails s", rather than foreman. This pulls in data from the .env file. In the case where you only have the web application in the Procfile, its easier to read through the log file when you use rails s rather than foreman. .env is also a good way to make sure that none of your configuration stuff is stuck away in code somewhere.
19
+
20
+ Assuming that you aren't hemmoraging memory, using unicorn is a great way to get more out of your dynos. This setup gives you 3 workers for every dyno. (We have nothing against Puma.)
21
+
22
+ Finally we setup some basic HTTP auth and a simple setup controller to help navigate what seed has generated for you. By default the HTTP auth stuff is off (i.e. no user/pass set) but the basic idea is that before you open things up to the world you can share your app to a limited group of people.
23
+
24
+
25
+ ### Environment Variables
26
+
27
+ The AWS env variables are there for reference
28
+
29
+ If the HTTP_AUTH_* variables are set, application_controller will force them to be used for authentication to let people into the site. (The happy_seed:splash generator will not use this.)
30
+
31
+ AWS_ACCESS_KEY stuff isn't used, but is here for reference.
32
+
33
+ ```
34
+ AWS_ACCESS_KEY_ID=
35
+ AWS_SECRET_ACCESS_KEY=
36
+ S3_BUCKET_NAME=
37
+ HTTP_AUTH_USERNAME=
38
+ HTTP_AUTH_PASSWORD=
39
+ ```
40
+
41
+ ### What needs to be done?
42
+
43
+ Even though the setup controller only works locally, you should plan on removing the setup_controller since it shows the configuration variables.
@@ -1,7 +1,8 @@
1
1
  %footer#footer
2
- .row
3
- .col-xs-6
4
- %h3 AppName
5
- .col-xs-6.text-right
6
- %small.copyright
7
- T, Copyright &copy; #{ Date.today.year }
2
+ .container
3
+ .row
4
+ .col-xs-6
5
+ %h3 AppName
6
+ .col-xs-6.text-right
7
+ %small.copyright
8
+ T, Copyright &copy; #{ Date.today.year }
@@ -18,6 +18,8 @@ The happy_seed bootstrap generator
18
18
 
19
19
  Bootstrap should be the base of all our projects going forward. This creates a variables.css.scss where you can configure bootstrap to your needs, and you can put the custom css stuff after that.
20
20
 
21
+ The splash generator builds on this, but doesn't use the main "application.css" stylesheets or javascripts. The layout here should be used for the application proper.
22
+
21
23
  Better scaffolding means that it's easier to just whip up things to get started. While you will obviously eventually rewrite all of this code, it's good to have working stuff to start with that doesn't look painful.
22
24
 
23
25
  ### Environment Variables
@@ -29,3 +31,7 @@ Better scaffolding means that it's easier to just whip up things to get started.
29
31
  ### What needs to be done?
30
32
 
31
33
  Signup for google analytics and setup the site id.
34
+
35
+ http://www.google.com/analytics/
36
+
37
+
@@ -27,9 +27,12 @@ module HappySeed
27
27
  remove_file 'app/views/devise/passwords/new.html.erb'
28
28
  end
29
29
 
30
+ remove_file "spec/factories/users.rb"
31
+
30
32
  directory 'app'
31
33
  directory 'docs'
32
34
  directory 'test'
35
+ directory 'spec'
33
36
 
34
37
  application(nil, env: "development") do
35
38
  "config.action_mailer.default_url_options = { host: 'localhost:3000' }"
@@ -10,11 +10,11 @@ The happy_seed:devise generator
10
10
  * Copies over devise views
11
11
  * Gives them bootstrap views
12
12
  * Adds use signin/signup stuff to the navbar
13
- * Installs MailView for the device mailer.
13
+ * Installs MailPreview for the device mailer.
14
14
 
15
15
  ### Why do you want this?
16
16
 
17
- User auth is boring.
17
+ Devise is a well tested and fully featured way to get user authentication. The generate sets things up with the defaults, but there are a lot more things to tweak if you are interested.
18
18
 
19
19
  ### Environment Variables
20
20
 
@@ -22,4 +22,6 @@ na
22
22
 
23
23
  ### What needs to be done?
24
24
 
25
- Flesh out the user model and run rake db:migrate.
25
+ Take a look at the user model to see if you want to configure any other features in devise. Look at the migration to see if there are any other fields you wish the users to have.
26
+
27
+ Once you feel good about it run "rake db:migrate" and you should be good to go.
@@ -0,0 +1,15 @@
1
+ # Read about factories at https://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ sequence :email do |n|
5
+ "person#{n}@example.com"
6
+ end
7
+ end
8
+
9
+ FactoryGirl.define do
10
+ factory :user, :class => 'User' do
11
+ email
12
+ password '12345678'
13
+ password_confirmation '12345678'
14
+ end
15
+ end
@@ -22,3 +22,7 @@ If you want to have the user connect via facebook, this is the one line command
22
22
  ### What needs to be done?
23
23
 
24
24
  In config/initializers/devise.rb make sure that the scope you are requesting is correct.
25
+
26
+ Since you need to set the callbacks as urls, you'll need to create one app for local development and another app for production. (Possibly one for staging as well.)
27
+
28
+ https://developers.facebook.com
@@ -27,6 +27,7 @@ module HappySeed
27
27
 
28
28
  generate 'model identity user:references provider:string accesstoken:string uid:string name:string email:string nickname:string image:string phone:string urls:string'
29
29
  remove_file 'app/models/identity.rb'
30
+ remove_file 'spec/models/identity_spec.rb'
30
31
  directory 'app'
31
32
  directory 'spec'
32
33
  route "match '/profile/:id/finish_signup' => 'users#finish_signup', via: [:get, :patch], :as => :finish_signup"
@@ -5,23 +5,27 @@ HappySeed Omniauth Install
5
5
 
6
6
  The happy_seed:omniauth generator depends upon happy_seed:devise and
7
7
 
8
-
9
8
  * Generates an Intentity model, linked to user
10
9
  * Installs omniauth
11
10
  * Installs an omniauth_controller
12
11
  * Updates devise configuration
13
12
  * Adds routes
14
- * Inserts code into User to do the lookup TODO
13
+ * Inserts code into User to do the lookup
15
14
  * Inserts fallback controller to handle the login
16
15
 
17
16
  ### Why do you want this?
18
17
 
19
- Once this is in place you can easily add other oauth providers
18
+ This lets you easily add oauth authentication for 3rd party sites to you application, the main ones being facebook and twitter. This sets up the infrastructure to make everything work with devise.
19
+
20
+ The Identity model is used to link up the user with the remote information. What information is given is stored, though you could go deeper with this. Additionally, the access token for the user is store in the Identity model for interacting with the remote service on behalf of the user.
21
+
22
+ It also creates the omniauth_callback controller. Devise as it's setup out of the box has the user's email address as the login, but not all services will give you the user's email address. (Twitter for example.) The controller in this case will check to see if the email address is returned, and if not, it will prompt the user for one. This may not be the functionality that you desire.
23
+
20
24
 
21
25
  ### Environment Variables
22
26
 
23
- na
27
+ na (done in the providers)
24
28
 
25
29
  ### What needs to be done?
26
30
 
27
- na
31
+ This is a base module which is used by happy_seed:twitter, happy_seed:facebook and happy_seed:instagram.
@@ -0,0 +1,32 @@
1
+ require 'thor'
2
+
3
+ module HappySeed
4
+ module Generators
5
+ class PluginGenerator < Thor::Group
6
+ include Thor::Actions
7
+ source_root File.expand_path('../templates', __FILE__)
8
+ def generate_rails_plugin
9
+ source_root = File.expand_path('../templates', __FILE__)
10
+ app_name = ARGV.shift
11
+ system "rails plugin new #{app_name} -T --dummy-path=spec/dummy #{ARGV.join( " ")}"
12
+
13
+ insert_into_file "#{app_name}/#{app_name}.gemspec", File.read( "#{source_root}/gemspec" ), :before => "\nend\n"
14
+
15
+ system( "cd #{app_name} && bundle" )
16
+
17
+ system( "cd #{app_name}/spec/dummy && rails g rspec:install")
18
+
19
+ gsub_file "#{app_name}/spec/dummy/.rspec", "--warnings\n", ""
20
+ append_to_file "#{app_name}/spec/dummy/.rspec", "--format documentation\n"
21
+
22
+ self.destination_root = app_name
23
+
24
+ remove_file "Rakefile"
25
+ copy_file "Rakefile"
26
+ copy_file ".rspec"
27
+ copy_file ".autotest"
28
+ directory "spec"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ require "autotest/rails_rspec"
2
+
3
+ Autotest.add_hook :initialize do |autotest|
4
+ %w{.git .svn .hg .DS_Store ._* vendor tmp log doc}.each do |exception|
5
+ autotest.add_exception(exception)
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+
8
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
9
+ load 'rails/tasks/engine.rake'
10
+
11
+ Bundler::GemHelper.install_tasks
12
+
13
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
14
+
15
+ require 'rspec/core'
16
+ require 'rspec/core/rake_task'
17
+
18
+ desc "Run all specs in spec directory (excluding plugin specs)"
19
+
20
+ # This is for moutable engines
21
+ # RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
22
+
23
+ # This is for plugins that don't have models
24
+ RSpec::Core::RakeTask.new(:spec)
25
+ task :default => :spec
@@ -0,0 +1,8 @@
1
+
2
+ s.test_files = Dir["spec/**/*"]
3
+
4
+ s.add_development_dependency "rspec"
5
+ s.add_development_dependency "rspec-rails"
6
+ s.add_development_dependency "rspec-autotest"
7
+ s.add_development_dependency "autotest-rails"
8
+ s.add_development_dependency 'factory_girl_rails'
@@ -0,0 +1,43 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+ require 'spec_helper'
4
+ require File.expand_path("../dummy/config/environment", __FILE__)
5
+ require 'rspec/rails'
6
+
7
+ # Requires supporting ruby files with custom matchers and macros, etc, in
8
+ # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
9
+ # run as spec files by default. This means that files in spec/support that end
10
+ # in _spec.rb will both be required and run as specs, causing the specs to be
11
+ # run twice. It is recommended that you do not name files matching this glob to
12
+ # end with _spec.rb. You can configure this pattern with the --pattern
13
+ # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
14
+ Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
15
+
16
+ # Checks for pending migrations before tests are run.
17
+ # If you are not using ActiveRecord, you can remove this line.
18
+ ActiveRecord::Migration.maintain_test_schema!
19
+
20
+ RSpec.configure do |config|
21
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
22
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
23
+
24
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
25
+ # examples within a transaction, remove the following line or assign false
26
+ # instead of true.
27
+ config.use_transactional_fixtures = true
28
+
29
+ # RSpec Rails can automatically mix in different behaviours to your tests
30
+ # based on their file location, for example enabling you to call `get` and
31
+ # `post` in specs under `spec/controllers`.
32
+ #
33
+ # You can disable this behaviour by removing the line below, and instead
34
+ # explicitly tag your specs with their type, e.g.:
35
+ #
36
+ # RSpec.describe UsersController, :type => :controller do
37
+ # # ...
38
+ # end
39
+ #
40
+ # The different available types are documented in the features, such as in
41
+ # https://relishapp.com/rspec/rspec-rails/docs
42
+ config.infer_spec_type_from_file_location!
43
+ end
@@ -0,0 +1,20 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+
3
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
4
+ require 'rspec/rails'
5
+ # require 'rspec/autorun'
6
+ require 'factory_girl_rails'
7
+
8
+ Rails.backtrace_cleaner.remove_silencers!
9
+
10
+ # Load support files
11
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
12
+ Dir["#{File.dirname(__FILE__)}/dummy/spec/factories/**/*.rb"].each { |f| require f }
13
+
14
+ RSpec.configure do |config|
15
+ config.mock_with :rspec
16
+ config.use_transactional_fixtures = true
17
+ config.infer_base_class_for_anonymous_controllers = false
18
+ config.order = "random"
19
+ config.include FactoryGirl::Syntax::Methods
20
+ end
@@ -7,38 +7,11 @@ $headings-font-family: 'Open Sans';
7
7
  $navbar-height: 75px;
8
8
 
9
9
  $navbar-default-bg: rgba(255,255,255,.5);
10
- $navbar-inverse-bg: rgba(0,0,0,.5);
10
+ $navbar-inverse-bg: rgba(0,0,0,.9);
11
11
 
12
12
 
13
13
  // Color Palate
14
14
  $brand-primary: #9CCC00;
15
- $color-accent: #428bca;
16
- $color-background: #202a39;
17
- $color-background-light: darken( white, 10% ); // #DAE3BB; //#3D6299;
18
- $color-text: #ddd;
19
- $color-text-light: $color-background; //#3F005E;
20
-
21
- // $carousel-control-color: lighten( $color-text-light, 10% );
22
- // $carousel-indicator-border-color: $carousel-control-color;
23
-
24
- // $color-text-light: #D0F2EF;
25
- // $color-accent: #91A644;
26
- // $color-background: #445925;
27
- // $color-background-light: #735D34;
28
- // $color-text: #91A644;
29
-
30
- // Default bootstrap reference
31
- // $brand-primary: #428bca !default;
32
- // $brand-success: #5cb85c !default;
33
- // $brand-info: #5bc0de !default;
34
- // $brand-warning: #f0ad4e !default;
35
- // $brand-danger: #d9534f !default;
36
-
37
-
38
-
39
- $body-bg: $color-background;
40
- $text-color: $color-text;
41
- $navbar-inverse-brand-color: $text-color;
42
15
 
43
16
  @import 'bootstrap-sprockets';
44
17
  @import 'bootstrap';
@@ -52,49 +25,6 @@ body {
52
25
  border-bottom: 2px solid $brand-primary;
53
26
  }
54
27
 
55
- @media screen and (min-width: $screen-sm-min) {
56
- h1 { font-size: 72px }
57
- .navbar-brand {
58
- font-family: $headings-font-family;
59
- font-size: 24px;
60
- }
61
-
62
- // .navbar-nav {
63
- // margin: ($navbar-padding-vertical / 2) (-$navbar-padding-horizontal);
64
-
65
- // > li > a {
66
- // padding-top: 13px;
67
- // padding-bottom: 10px;
68
- // line-height: 13px;
69
- // font-size: 20px;
70
- // }
71
- // }
72
- }
73
-
74
- .navbar#top {
75
- border-bottom: 1px solid $brand-primary;
76
- }
77
-
78
- .navbar-collapse.in {
79
- background: white;
80
- }
81
-
82
- section {
83
- padding-top: 20vh;
84
- min-height: 90vh;
85
- padding-bottom: 20vh;
86
- }
87
-
88
- section #bottom {
89
- margin-top: 10vh;
90
- font-size: 24px;
91
- }
92
-
93
- section.light {
94
- background: $color-background-light;
95
- color: $color-text-light;
96
-
97
- a {
98
- color: darken( $brand-primary, 5% );
99
- }
100
- }
28
+ .navbar-inverse a.navbar-brand {
29
+ color: $brand-primary;
30
+ }
@@ -33,10 +33,11 @@
33
33
  Happy Seed
34
34
  %nav.collapse.navbar-collapse{:role=>:navigation}
35
35
  %ul.nav.navbar-nav
36
- %li= link_to 'What', '#what'
37
- %li= link_to 'Why', '#why'
38
- %li= link_to 'How', '#how'
39
- %li= link_to 'Who', '#who'
36
+ %li= link_to 'Top', '#'
37
+ %li= link_to 'Why', '#what'
38
+ %li= link_to 'Feature 1', '#feature1'
39
+ %li= link_to 'Feature 2', '#feature2'
40
+ %li= link_to 'Feature 3', '#feature3'
40
41
 
41
42
  = yield
42
43
 
@@ -56,7 +57,7 @@
56
57
 
57
58
  // animate
58
59
  $('html, body').animate({
59
- scrollTop: $(this.hash).offset().top
60
+ scrollTop: $(this.hash).offset().top - 95 // 75 is navbar height
60
61
  }, 300, function(){
61
62
  // when done, add hash to url
62
63
  // (default click behaviour)