tuttle 0.0.6 → 0.0.8
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +17 -0
- data/Rakefile +0 -1
- data/app/controllers/tuttle/active_job_controller.rb +1 -0
- data/app/controllers/tuttle/active_model_serializers_controller.rb +1 -0
- data/app/controllers/tuttle/active_support_controller.rb +1 -0
- data/app/controllers/tuttle/application_controller.rb +19 -2
- data/app/controllers/tuttle/cancancan_controller.rb +2 -0
- data/app/controllers/tuttle/devise_controller.rb +1 -0
- data/app/controllers/tuttle/execjs_controller.rb +12 -0
- data/app/controllers/tuttle/gems_controller.rb +3 -2
- data/app/controllers/tuttle/home_controller.rb +1 -0
- data/app/controllers/tuttle/i18n_controller.rb +27 -0
- data/app/controllers/tuttle/paperclip_controller.rb +1 -0
- data/app/controllers/tuttle/rack_attack_controller.rb +26 -0
- data/app/controllers/tuttle/rack_mini_profiler_controller.rb +1 -0
- data/app/controllers/tuttle/rails_controller.rb +19 -5
- data/app/controllers/tuttle/request_controller.rb +1 -0
- data/app/controllers/tuttle/ruby_controller.rb +15 -2
- data/app/helpers/tuttle/application_helper.rb +64 -2
- data/app/models/tuttle/configuration_registry.rb +1 -0
- data/app/models/tuttle/version_detector.rb +1 -0
- data/app/views/layouts/tuttle/application.html.erb +22 -6
- data/app/views/tuttle/active_support/dependencies.html.erb +7 -7
- data/app/views/tuttle/active_support/inflectors.html.erb +1 -1
- data/app/views/tuttle/cancancan/index.html.erb +1 -1
- data/app/views/tuttle/cancancan/rule_tester.html.erb +3 -3
- data/app/views/tuttle/execjs/index.html.erb +87 -0
- data/app/views/tuttle/gems/http_clients.html.erb +13 -12
- data/app/views/tuttle/gems/index.html.erb +4 -4
- data/app/views/tuttle/gems/json.html.erb +10 -10
- data/app/views/tuttle/home/index.html.erb +6 -6
- data/app/views/tuttle/i18n/_translation_entry.html.erb +10 -0
- data/app/views/tuttle/i18n/index.html.erb +111 -0
- data/app/views/tuttle/i18n/localize.html.erb +53 -0
- data/app/views/tuttle/i18n/translations.html.erb +12 -0
- data/app/views/tuttle/rack_attack/index.html.erb +227 -0
- data/app/views/tuttle/rails/assets.html.erb +4 -4
- data/app/views/tuttle/rails/cache.html.erb +4 -8
- data/app/views/tuttle/rails/controllers.html.erb +54 -7
- data/app/views/tuttle/rails/database.html.erb +14 -1
- data/app/views/tuttle/rails/engines.html.erb +1 -1
- data/app/views/tuttle/rails/helpers.html.erb +1 -1
- data/app/views/tuttle/rails/index.html.erb +72 -19
- data/app/views/tuttle/rails/models.html.erb +150 -73
- data/app/views/tuttle/rails/routes.html.erb +10 -8
- data/app/views/tuttle/rails/schema_cache.html.erb +2 -2
- data/app/views/tuttle/ruby/constants.html.erb +29 -0
- data/app/views/tuttle/ruby/extensions.html.erb +24 -0
- data/app/views/tuttle/ruby/index.html.erb +21 -15
- data/app/views/tuttle/ruby/tuning.html.erb +6 -9
- data/config/routes.rb +15 -1
- data/lib/tuttle.rb +1 -0
- data/lib/tuttle/engine.rb +3 -4
- data/lib/tuttle/instrumenter.rb +3 -1
- data/lib/tuttle/middleware/request_profiler.rb +11 -11
- data/lib/tuttle/presenters/action_dispatch/routing/route_wrapper.rb +34 -2
- data/lib/tuttle/presenters/active_record/reflection_presenter.rb +54 -0
- data/lib/tuttle/presenters/active_support/callbacks.rb +26 -0
- data/lib/tuttle/presenters/base_presenter.rb +19 -0
- data/lib/tuttle/presenters/rack_mini_profiler/client_settings.rb +1 -0
- data/lib/tuttle/ruby_prof/fast_call_stack_printer.rb +2 -1
- data/lib/tuttle/version.rb +2 -1
- metadata +27 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9a62a3da7ea3c2565f1f91d6b9a446b95a951dbc2b3ac140102f27fc7f49c1bb
|
4
|
+
data.tar.gz: bcad3944fdbf4fc00790142e0de00318a8bbc52fae9bf3e8ad1811cfdace59e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e0f1e91acf1a8775c379136e09b84749b6e29af8a1728209236867764ed78c07c606ab059d6781137961070771b6ec343df5e8fbb6de513e8d1d9876b846961
|
7
|
+
data.tar.gz: 56aa10ea1db3241284ca712a867c8752554fcfeb34e1a23c15f664fedfed1d9e796cf2b79010a5004a31b4479a10f4109008bff9be708a4cd02d10c0b71b8ff2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
### 0.0.8
|
2
|
+
|
3
|
+
* Features
|
4
|
+
* New ExecJS inspector
|
5
|
+
* New Rack::Attack inspector
|
6
|
+
* Improved ActiveRecord models inspector with associations and validations
|
7
|
+
* Improved Rails Controllers link to matched routes (excluding wildcards and implicit renders)
|
8
|
+
|
9
|
+
### 0.0.7
|
10
|
+
|
11
|
+
* Features
|
12
|
+
* Rails 5.1 support (drops Rails 4.0)
|
13
|
+
* New I18n inspector
|
14
|
+
* New Constants and Object extensions inspector
|
15
|
+
* Improved Rails routes inspector to show route validity
|
16
|
+
* Improved listing display formatting
|
17
|
+
|
1
18
|
### 0.0.6
|
2
19
|
|
3
20
|
* Features
|
data/Rakefile
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Tuttle
|
2
3
|
class ApplicationController < ActionController::Base
|
3
4
|
abstract!
|
4
5
|
protect_from_forgery with: :exception
|
5
6
|
|
6
7
|
before_action :check_reload_status
|
8
|
+
around_action :set_locale
|
7
9
|
|
8
10
|
private
|
9
11
|
|
@@ -11,8 +13,23 @@ module Tuttle
|
|
11
13
|
return unless Tuttle::Engine.reload_needed && !Rails.configuration.eager_load
|
12
14
|
Tuttle::Engine.logger.warn('Eager-loading application')
|
13
15
|
ActiveSupport::Notifications.instrument 'tuttle.perform_eager_load' do
|
14
|
-
|
15
|
-
|
16
|
+
begin
|
17
|
+
Rails.application.eager_load!
|
18
|
+
rescue
|
19
|
+
Tuttle::Engine.logger.warn('Failed to eager-load application')
|
20
|
+
ensure
|
21
|
+
Tuttle::Engine.reload_needed = false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_locale
|
27
|
+
if params[:hl] && I18n.locale_available?(params[:hl])
|
28
|
+
I18n.with_locale(params[:hl]) do
|
29
|
+
yield
|
30
|
+
end
|
31
|
+
else
|
32
|
+
yield
|
16
33
|
end
|
17
34
|
end
|
18
35
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require_dependency 'tuttle/application_controller'
|
2
3
|
|
3
4
|
module Tuttle
|
@@ -6,6 +7,7 @@ module Tuttle
|
|
6
7
|
def index
|
7
8
|
@cancan_user = current_user || User.new
|
8
9
|
@ability = Ability.new(@cancan_user)
|
10
|
+
@rules = @ability.instance_variable_get('@rules')
|
9
11
|
end
|
10
12
|
|
11
13
|
def rule_tester
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require_dependency 'tuttle/application_controller'
|
2
3
|
|
3
4
|
module Tuttle
|
4
5
|
class GemsController < ApplicationController
|
5
6
|
|
6
7
|
def index
|
8
|
+
@gemspecs = Bundler.rubygems.all_specs.sort_by(&:name)
|
7
9
|
end
|
8
10
|
|
9
11
|
def http_clients
|
@@ -12,8 +14,7 @@ module Tuttle
|
|
12
14
|
def json
|
13
15
|
end
|
14
16
|
|
15
|
-
# rubocop:disable
|
16
|
-
def get_process_mem
|
17
|
+
def get_process_mem # rubocop:disable Naming/AccessorMethodName
|
17
18
|
require 'get_process_mem'
|
18
19
|
require 'get_process_mem/version'
|
19
20
|
@memory_self = GetProcessMem.new
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_dependency 'tuttle/application_controller'
|
3
|
+
|
4
|
+
module Tuttle
|
5
|
+
class I18nController < ApplicationController
|
6
|
+
|
7
|
+
before_action :set_sorted_locales
|
8
|
+
|
9
|
+
def index
|
10
|
+
end
|
11
|
+
|
12
|
+
def localize
|
13
|
+
end
|
14
|
+
|
15
|
+
def translations
|
16
|
+
@translations = I18n.backend.send(:translations)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def set_sorted_locales
|
22
|
+
@sorted_locales = [I18n.default_locale] +
|
23
|
+
(I18n.available_locales.map(&:to_s).sort.map(&:to_sym) - [I18n.default_locale])
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_dependency 'tuttle/application_controller'
|
3
|
+
|
4
|
+
module Tuttle
|
5
|
+
class RackAttackController < ApplicationController
|
6
|
+
|
7
|
+
def index
|
8
|
+
require 'rack/attack/version'
|
9
|
+
if ::Rack::Attack::VERSION < '5'
|
10
|
+
render plain: 'Tuttle Rack::Attack support requires version 5.x' && return
|
11
|
+
end
|
12
|
+
|
13
|
+
default_keys = %w[rack.attack.matched rack.attack.match_discriminator rack.attack.match_type rack.attack.match_data]
|
14
|
+
rack_attack_env_vars = request.env.select { |k, _v| k.to_s.start_with?('rack.attack') }
|
15
|
+
@rack_attack_env_settings = (rack_attack_env_vars.keys + default_keys).uniq
|
16
|
+
|
17
|
+
@throttles = Rack::Attack.throttles
|
18
|
+
@safelists = Rack::Attack.safelists
|
19
|
+
@blocklists = Rack::Attack.blocklists
|
20
|
+
@tracks = Rack::Attack.tracks
|
21
|
+
|
22
|
+
@asn_listeners = ActiveSupport::Notifications.notifier.listeners_for("rack.attack")
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'rails/generators'
|
2
3
|
require_dependency 'tuttle/application_controller'
|
3
4
|
require_dependency 'tuttle/presenters/action_dispatch/routing/route_wrapper'
|
5
|
+
require_dependency 'tuttle/presenters/active_support/callbacks'
|
6
|
+
require_dependency 'tuttle/presenters/active_record/reflection_presenter'
|
4
7
|
|
5
8
|
module Tuttle
|
6
9
|
class RailsController < ApplicationController
|
@@ -10,12 +13,23 @@ module Tuttle
|
|
10
13
|
end
|
11
14
|
|
12
15
|
def controllers
|
13
|
-
|
16
|
+
@routes = Rails.application.routes.routes.collect do |route|
|
17
|
+
Tuttle::Presenters::ActionDispatch::Routing::RouteWrapper.new(route)
|
18
|
+
end
|
19
|
+
|
14
20
|
# It seems likely that .descendants will work best when Tuttle and Rails classes are not modified
|
15
21
|
# but both approaches also require eager_load to be true
|
16
22
|
# @controllers = ObjectSpace.each_object(::Class).select {|klass| klass < ActionController::Base }
|
17
23
|
@controllers = ActionController::Base.descendants
|
18
|
-
@controllers.reject!
|
24
|
+
@controllers.reject! do |controller|
|
25
|
+
controller.abstract? || controller <= Tuttle::ApplicationController
|
26
|
+
end
|
27
|
+
|
28
|
+
# Rails 5.1 introduced Rails::ApplicationController which really should be abstract
|
29
|
+
if defined?(Rails::ApplicationController)
|
30
|
+
@controllers.reject! { |controller| controller == Rails::ApplicationController }
|
31
|
+
end
|
32
|
+
|
19
33
|
@controllers.sort_by!(&:name)
|
20
34
|
end
|
21
35
|
|
@@ -24,12 +38,12 @@ module Tuttle
|
|
24
38
|
end
|
25
39
|
|
26
40
|
def generators
|
27
|
-
Rails::Generators.lookup! if
|
41
|
+
Rails::Generators.lookup! if params[:load_all_generators] == 'true'
|
28
42
|
@generators = Rails::Generators.subclasses.group_by(&:base_name)
|
29
43
|
end
|
30
44
|
|
31
45
|
def models
|
32
|
-
@models = ActiveRecord::Base.descendants
|
46
|
+
@models = ActiveRecord::Base.descendants.reject { |model| model.abstract_class? || !model.table_exists? }
|
33
47
|
@models.sort_by!(&:name)
|
34
48
|
end
|
35
49
|
|
@@ -101,7 +115,7 @@ module Tuttle
|
|
101
115
|
|
102
116
|
def recognize_paths(path)
|
103
117
|
results = {}
|
104
|
-
[
|
118
|
+
%i[get post put delete patch].each {|method| results[method] = recognize_path(path, method: method)}
|
105
119
|
results
|
106
120
|
end
|
107
121
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_dependency 'tuttle/application_controller'
|
4
4
|
|
@@ -18,7 +18,6 @@ module Tuttle
|
|
18
18
|
@gc_enabled = (GC.disable ? false : GC.enable)
|
19
19
|
|
20
20
|
# taken verbatim from the ruby 2.2 man page
|
21
|
-
# rubocop:disable Metrics/LineLength
|
22
21
|
@gc_params = {
|
23
22
|
'RUBY_GC_HEAP_INIT_SLOTS' => 'Initial allocation slots. Introduced in Ruby 2.1, default: 10000.',
|
24
23
|
'RUBY_GC_HEAP_FREE_SLOTS' => 'Prepare at least this amount of slots after GC. Allocate this number slots if there are not enough slots. Introduced in Ruby 2.1, default: 4096',
|
@@ -37,5 +36,19 @@ module Tuttle
|
|
37
36
|
def miscellaneous
|
38
37
|
end
|
39
38
|
|
39
|
+
def constants
|
40
|
+
# Global constants minus a few deprecated constants (to prevent warnings)
|
41
|
+
@constants = (Object.constants - %i[Bignum Fixnum NIL TRUE FALSE TimeoutError Data]).
|
42
|
+
sort.
|
43
|
+
map { |sym| [sym, Object.const_get(sym).class, Object.const_get(sym)] }.
|
44
|
+
reject { |_sym, klass, _val| klass == Class || klass == Module }
|
45
|
+
end
|
46
|
+
|
47
|
+
def extensions
|
48
|
+
@obj_extensions = Object.methods.select { |meth| Object.method(meth).source_location }.
|
49
|
+
sort.
|
50
|
+
map { |meth| [meth, *Object.method(meth).source_location] }
|
51
|
+
end
|
52
|
+
|
40
53
|
end
|
41
54
|
end
|
@@ -1,12 +1,19 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
3
2
|
module Tuttle
|
4
3
|
module ApplicationHelper
|
4
|
+
BUNDLER_GEM_PATHS_REGEX = %r{(#{Bundler.rubygems.gem_dir}|#{File.realpath(Bundler.rubygems.gem_dir)})+(/bundler)*/gems}
|
5
|
+
|
6
|
+
# Display true/false label with text overrides
|
5
7
|
def truth_label(is_true, true_label = 'true', false_label = 'false')
|
6
8
|
content_tag(:span, is_true ? true_label : false_label,
|
7
9
|
class: ['label', is_true ? 'label-success' : 'label-danger'])
|
8
10
|
end
|
9
11
|
|
12
|
+
# Display label if condition is true
|
13
|
+
def true_label(is_true, true_label = 'true')
|
14
|
+
content_tag(:span, true_label, class: %w[label label-success]) if is_true
|
15
|
+
end
|
16
|
+
|
10
17
|
def tuttle_redacted(enumarator)
|
11
18
|
enumarator.collect do |key, value|
|
12
19
|
yield key, redact_by_key(key, value)
|
@@ -21,10 +28,65 @@ module Tuttle
|
|
21
28
|
main_app.respond_to?(:root_url) ? main_app.root_url : '/'
|
22
29
|
end
|
23
30
|
|
31
|
+
def link_to_rails_guide(file, title)
|
32
|
+
content_tag(:a, title, :href => rails_guides_versioned_url(file + '.html'))
|
33
|
+
end
|
34
|
+
|
24
35
|
def rails_guides_versioned_url(path)
|
25
36
|
"http://guides.rubyonrails.org/v#{Tuttle::VersionDetector.rails_major_minor}/#{path}"
|
26
37
|
end
|
27
38
|
|
39
|
+
def display_path(path)
|
40
|
+
return if path.blank?
|
41
|
+
display_location =
|
42
|
+
if path.start_with?(Rails.root.to_s)
|
43
|
+
path.sub(Rails.root.to_s, "$RAILS_ROOT")
|
44
|
+
elsif File.realpath(path).start_with?(File.realpath(Bundler.rubygems.gem_dir))
|
45
|
+
File.realpath(path).sub(BUNDLER_GEM_PATHS_REGEX, "$GEMS")
|
46
|
+
else
|
47
|
+
path
|
48
|
+
end
|
49
|
+
expanded_path = File.expand_path(path)
|
50
|
+
content_tag(:span, display_location, :class => 'tuttle-path', :data => { :initial => path, :expanded => expanded_path })
|
51
|
+
end
|
52
|
+
|
53
|
+
def display_source_locaction(path, line)
|
54
|
+
return content_tag(:span, "Unknown", :class => 'tuttle-path') if path.nil?
|
55
|
+
|
56
|
+
display_location = file_location(path)
|
57
|
+
expanded_path = File.expand_path(path)
|
58
|
+
content_tag(:span, :class => 'tuttle-path', :data => { :initial => path, :expanded => expanded_path }) do
|
59
|
+
"#{display_location}##{line}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def file_location(path)
|
64
|
+
if path.start_with?(Rails.root.to_s)
|
65
|
+
path.gsub(Rails.root.to_s, "$RAILS_ROOT")
|
66
|
+
elsif path.start_with?(RbConfig::CONFIG['rubylibdir'])
|
67
|
+
path.gsub(RbConfig::CONFIG['rubylibdir'], "$RUBY_LIB_DIR")
|
68
|
+
elsif path == "<internal:prelude>"
|
69
|
+
path
|
70
|
+
elsif File.realpath(path).start_with?(File.realpath(Bundler.rubygems.gem_dir))
|
71
|
+
File.realpath(path).gsub(BUNDLER_GEM_PATHS_REGEX, "$GEMS")
|
72
|
+
else
|
73
|
+
path
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def value_inspect(val, hide_nil: false)
|
78
|
+
case val
|
79
|
+
when NilClass
|
80
|
+
content_tag(:code, val.inspect) unless hide_nil
|
81
|
+
when String
|
82
|
+
content_tag(:code, val.inspect)
|
83
|
+
when Symbol
|
84
|
+
content_tag(:code, val.inspect)
|
85
|
+
else
|
86
|
+
val.inspect
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
28
90
|
private
|
29
91
|
|
30
92
|
def redact_by_key(key, value)
|
@@ -2,28 +2,30 @@
|
|
2
2
|
<html lang="en">
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8">
|
5
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
6
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
7
6
|
<title>Tuttle</title>
|
8
7
|
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
9
8
|
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
|
10
|
-
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.
|
11
|
-
|
9
|
+
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
|
10
|
+
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" integrity="sha256-3YM6A3pH4QFCl9WbSU8oXF5N6W/2ylvW0o2g+Z6TmLQ=" crossorigin="anonymous" />
|
12
11
|
<%= content_for(:stylesheets) -%>
|
13
12
|
<link rel="icon" href="//s3.amazonaws.com/tuttle-assets/images/favicon.ico">
|
14
13
|
<style>
|
15
14
|
html { overflow: -moz-scrollbars-vertical; overflow-y: scroll; }
|
16
15
|
body { padding-top: 50px; }
|
17
16
|
table.not-wide { width: auto; }
|
18
|
-
|
17
|
+
table code { color: black; background-color: inherit; padding: 0; }
|
18
|
+
table.table-condensed tbody tr td:first-child { padding-left: 0; }
|
19
|
+
table .nowrap { white-space: nowrap; }
|
19
20
|
a[href*="github.com"] { white-space: nowrap; }
|
20
21
|
a[href*="github.com"]:after { font-family: FontAwesome; content: "\f09b"; display: inline-block; color: initial; padding-left: 3px; }
|
22
|
+
details :focus { outline: none; }
|
21
23
|
</style>
|
22
24
|
<%= csrf_meta_tags %>
|
23
25
|
</head>
|
24
26
|
<body>
|
25
27
|
|
26
|
-
<nav class="navbar
|
28
|
+
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
27
29
|
<div class="container">
|
28
30
|
<div class="navbar-header">
|
29
31
|
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
|
@@ -50,6 +52,12 @@
|
|
50
52
|
<li><%= link_to 'Asset Pipeline', rails_assets_path %></li>
|
51
53
|
<li><%= link_to 'Caching', rails_cache_path %></li>
|
52
54
|
<li role="separator" class="divider"></li>
|
55
|
+
<%- if defined?(::I18n) %>
|
56
|
+
<li><%= link_to 'Internationalization', i18n_path %></li>
|
57
|
+
<li><%= link_to 'Localization', i18n_localize_path %></li>
|
58
|
+
<li><%= link_to 'Translations', i18n_translations_path %></li>
|
59
|
+
<li role="separator" class="divider"></li>
|
60
|
+
<% end %>
|
53
61
|
<li><%= link_to 'Database', rails_database_path %></li>
|
54
62
|
<li><%= link_to 'Schema Cache', rails_schema_cache_path %></li>
|
55
63
|
<li role="separator" class="divider"></li>
|
@@ -88,6 +96,12 @@
|
|
88
96
|
<%- if defined?(::GetProcessMem) %>
|
89
97
|
<li><%= link_to 'GetProcessMem', gems_get_process_mem_path %></li>
|
90
98
|
<%- end %>
|
99
|
+
<%- if defined?(::ExecJS) %>
|
100
|
+
<li><%= link_to 'ExecJS', execjs_path %></li>
|
101
|
+
<%- end %>
|
102
|
+
<%- if defined?(::Rack::Attack) %>
|
103
|
+
<li><%= link_to 'Rack::Attack', rack_attack_path %></li>
|
104
|
+
<%- end %>
|
91
105
|
<li><%= link_to 'HTTP Clients', gems_http_clients_path %></li>
|
92
106
|
<li><%= link_to 'JSON', gems_json_path %></li>
|
93
107
|
<li><%= link_to 'Other', gems_other_path %></li>
|
@@ -99,6 +113,8 @@
|
|
99
113
|
<li><%= link_to 'Overview', ruby_path %></li>
|
100
114
|
<li class="divider"></li>
|
101
115
|
<li><%= link_to 'Tuning', ruby_tuning_path %></li>
|
116
|
+
<li><%= link_to 'Extensions', ruby_extensions_path %></li>
|
117
|
+
<li><%= link_to 'Constants', ruby_constants_path %></li>
|
102
118
|
<li><%= link_to 'Miscellaneous', ruby_miscellaneous_path %></li>
|
103
119
|
</ul>
|
104
120
|
</li>
|
@@ -115,7 +131,7 @@
|
|
115
131
|
|
116
132
|
<script src="//code.jquery.com/jquery-2.2.4.min.js" integrity="sha384-rY/jv8mMhqDabXSo+UCggqKtdmBfd3qC2/KvyTDNQ6PcUJXaxK1tMepoQda4g5vB" crossorigin="anonymous"></script>
|
117
133
|
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
118
|
-
|
134
|
+
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js" integrity="sha256-/BfiIkHlHoVihZdc6TFuj7MmJ0TWcWsMXkeDFwhi0zw=" crossorigin="anonymous"></script>
|
119
135
|
<%= content_for(:javascripts) -%>
|
120
136
|
<script>hljs.initHighlightingOnLoad();</script>
|
121
137
|
</body>
|