hancock_cms_seo 1.0.2

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 (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +4 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +86 -0
  9. data/Rakefile +1 -0
  10. data/app/assets/javascripts/hancock/rails_admin/plugins/seo.coffee +4 -0
  11. data/app/assets/javascripts/hancock/rails_admin/plugins/seo/custom/ui.coffee +0 -0
  12. data/app/assets/stylesheets/hancock/rails_admin/plugins/seo.sass +3 -0
  13. data/app/assets/stylesheets/hancock/rails_admin/plugins/seo/custom/theming.sass +0 -0
  14. data/app/assets/stylesheets/hancock/rails_admin/plugins/seo/footer_nav_links.sass +16 -0
  15. data/app/controllers/concerns/hancock/seo/x_frame_options.rb +42 -0
  16. data/app/helpers/hancock/seo/seo_helper.rb +60 -0
  17. data/app/models/concerns/hancock/seo/decorators/seo.rb +60 -0
  18. data/app/models/concerns/hancock/seo/decorators/sitemap_data.rb +35 -0
  19. data/app/models/concerns/hancock/seo/seoable.rb +71 -0
  20. data/app/models/concerns/hancock/seo/sitemap_data_field.rb +37 -0
  21. data/app/models/concerns/hancock/seo/sitemapable.rb +7 -0
  22. data/app/models/hancock/seo/seo.rb +16 -0
  23. data/app/models/hancock/seo/sitemap_data.rb +16 -0
  24. data/app/views/blocks/_seo_block.html.slim +25 -0
  25. data/app/views/blocks/_seo_block_with_obj.html.slim +18 -0
  26. data/app/views/hancock/seo/blocks/_ga.html.slim +8 -0
  27. data/app/views/hancock/seo/blocks/_ym.html.slim +31 -0
  28. data/app/views/shared/_meta.html.slim +28 -0
  29. data/app/views/shared/_obj_with_seo.html.slim +38 -0
  30. data/app/views/shared/_og.html.slim +4 -0
  31. data/bin/console +14 -0
  32. data/bin/setup +7 -0
  33. data/config/initializers/hancock_seo.rb +7 -0
  34. data/config/locales/ru.hancock.seo.yml +37 -0
  35. data/hancock_cms_seo.gemspec +40 -0
  36. data/lib/generators/hancock/seo/config/config_generator.rb +13 -0
  37. data/lib/generators/hancock/seo/config/templates/hancock_seo.erb +10 -0
  38. data/lib/generators/hancock/seo/migrations/migrations_generator.rb +18 -0
  39. data/lib/generators/hancock/seo/migrations/templates/migration_seos.rb +48 -0
  40. data/lib/generators/hancock/seo/models/decorators_generator.rb +24 -0
  41. data/lib/generators/hancock/seo/models/seo_generator.rb +39 -0
  42. data/lib/generators/hancock/seo/models/sitemap_data_generator.rb +39 -0
  43. data/lib/generators/hancock/seo/models/templates/seo.erb +57 -0
  44. data/lib/generators/hancock/seo/models/templates/sitemap_data.erb +31 -0
  45. data/lib/generators/hancock/seo/sitemap/sitemap_generator.rb +27 -0
  46. data/lib/generators/hancock/seo/sitemap/templates/sitemap.erb +31 -0
  47. data/lib/hancock/seo/admin.rb +24 -0
  48. data/lib/hancock/seo/admin/seo.rb +69 -0
  49. data/lib/hancock/seo/admin/sitemap_data.rb +47 -0
  50. data/lib/hancock/seo/configuration.rb +29 -0
  51. data/lib/hancock/seo/engine.rb +44 -0
  52. data/lib/hancock/seo/models/active_record/seo.rb +14 -0
  53. data/lib/hancock/seo/models/active_record/sitemap_data.rb +11 -0
  54. data/lib/hancock/seo/models/mongoid/seo.rb +25 -0
  55. data/lib/hancock/seo/models/mongoid/sitemap_data.rb +24 -0
  56. data/lib/hancock/seo/models/seo.rb +114 -0
  57. data/lib/hancock/seo/models/sitemap_data.rb +79 -0
  58. data/lib/hancock/seo/version.rb +5 -0
  59. data/lib/hancock_cms_seo.rb +43 -0
  60. data/release.sh +6 -0
  61. metadata +193 -0
@@ -0,0 +1,37 @@
1
+ module Hancock::Seo::SitemapDataField
2
+ extend ActiveSupport::Concern
3
+ FIELDS = [:sitemap_show, :sitemap_lastmod, :sitemap_changefreq, :sitemap_priority]
4
+
5
+ included do
6
+ has_one :sitemap_data, as: :sitemap_data_field, autosave: true, class_name: "Hancock::Seo::SitemapData"
7
+ accepts_nested_attributes_for :sitemap_data
8
+
9
+ delegate *FIELDS, to: :sitemap_data
10
+ delegate *(FIELDS.map {|f| "#{f}=".to_sym }), to: :sitemap_data
11
+
12
+ alias sitemap_data_without_build sitemap_data
13
+ def sitemap_data
14
+ sitemap_data_without_build || build_sitemap_data
15
+ end
16
+
17
+ def default_sitemap_changefreq
18
+ 'weekly'
19
+ end
20
+ def default_sitemap_priority
21
+ 0.8
22
+ end
23
+
24
+ def to_sitemap(sitemap)
25
+ _sitemap_data = self.sitemap_data
26
+ _lastmod = _sitemap_data.sitemap_lastmod.to_date unless _sitemap_data.sitemap_lastmod.nil?
27
+ _lastmod = self.updated_at.to_date unless self.updated_at.nil? if _lastmod.nil?
28
+ _lastmod = self.created_at.to_date unless self.created_at.nil? if _lastmod.nil?
29
+
30
+ sitemap.add sitemap.url_for(i),
31
+ :lastmod => _lastmod,
32
+ :changefreq => "#{_sitemap_data.sitemap_changefreq.blank? ? self.default_sitemap_changefreq : _sitemap_data.sitemap_changefreq}",
33
+ :priority => (_sitemap_data.sitemap_priority.nil? ? self.default_sitemap_priority : _sitemap_data.sitemap_priority)
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ module Hancock::Seo::Sitemapable
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ include Hancock::Seo::SitemapDataField
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ module Hancock::Seo
2
+ if Hancock.active_record?
3
+ class Seo < ActiveRecord::Base
4
+ end
5
+ end
6
+
7
+ class Seo
8
+ include Hancock::Seo::Models::Seo
9
+
10
+ include Hancock::Seo::Decorators::Seo
11
+
12
+ rails_admin(&Hancock::Seo::Admin::Seo.config(rails_admin_add_fields) { |config|
13
+ rails_admin_add_config(config)
14
+ })
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Hancock::Seo
2
+ if Hancock.active_record?
3
+ class SitemapData < ActiveRecord::Base
4
+ end
5
+ end
6
+
7
+ class SitemapData
8
+ include Hancock::Seo::Models::SitemapData
9
+
10
+ include Hancock::Seo::Decorators::SitemapData
11
+
12
+ rails_admin(&Hancock::Seo::Admin::SitemapData.config(rails_admin_add_fields) { |config|
13
+ rails_admin_add_config(config)
14
+ })
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ - if @seo_page
2
+ - content_for :meta do
3
+ - _cache_helper = (Hancock::Seo.config.cache_support ? :hancock_cache : :cache)
4
+ - send _cache_helper, [@seo_page, @seo_parent_page, 'meta'].compact.uniq do
5
+ = render 'shared/meta', obj: @seo_page, alt_obj: @seo_parent_page
6
+
7
+ - og_title = (@seo_page.get_og_title.blank? and @seo_parent_page ? @seo_parent_page.get_og_title : @seo_page.get_og_title)
8
+ - og_image = (@seo_page.og_image.blank? and @seo_parent_page ? @seo_parent_page.og_image : @seo_page.og_image)
9
+ = render 'shared/og', title: og_title, image: og_image
10
+
11
+ - unless @seo_page.title.blank?
12
+ - content_for :title do
13
+ = @seo_page.title
14
+
15
+
16
+ - elsif @seo_parent_page
17
+ - content_for :meta do
18
+ - _cache_helper = (Hancock::Seo.config.cache_support ? :hancock_cache : :cache)
19
+ - send _cache_helper, [@seo_parent_page, 'meta'] do
20
+ = render 'shared/meta', obj: @seo_parent_page
21
+ = render 'shared/og', title: @seo_parent_page.get_og_title, image: @seo_parent_page.og_image
22
+
23
+ - unless @seo_parent_page.title.blank?
24
+ - content_for :title do
25
+ = @seo_parent_page.title
@@ -0,0 +1,18 @@
1
+ - obj ||= nil
2
+ - if obj
3
+ - seo_page = @seo_page || @seo_parent_page
4
+ - content_for :meta do
5
+ - _cache_helper = (Hancock::Seo.config.cache_support ? :hancock_cache : :cache)
6
+ - send _cache_helper, [obj, seo_page, 'meta'].uniq.compact do
7
+ = render 'shared/meta', obj: obj
8
+
9
+ - og_title = (obj.get_og_title.blank? and seo_page ? seo_page.get_og_title : obj.get_og_title)
10
+ - og_image = (obj.og_image.blank? and seo_page ? seo_page.og_image : obj.og_image)
11
+ = render 'shared/og', title: og_title, image: og_image
12
+
13
+ - unless obj.title.blank?
14
+ - content_for :title do
15
+ = obj.title
16
+
17
+ - else
18
+ = render 'blocks/seo_block'
@@ -0,0 +1,8 @@
1
+ javascript:
2
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
3
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
4
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
5
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
6
+
7
+ ga('create', '#{counter_id}', 'auto');
8
+ ga('send', 'pageview');
@@ -0,0 +1,31 @@
1
+ /! Yandex.Metrika counter
2
+ javascript:
3
+ (function (d, w, c) {
4
+ (w[c] = w[c] || []).push(function() {
5
+ try {
6
+ w.yaCounter#{counter_id} = new Ya.Metrika({
7
+ id:#{counter_id},
8
+ clickmap:true,
9
+ trackLinks:true,
10
+ accurateTrackBounce:true,
11
+ webvisor:true,
12
+ trackHash:true
13
+ });
14
+ } catch(e) { }
15
+ });
16
+
17
+ var n = d.getElementsByTagName("script")[0],
18
+ s = d.createElement("script"),
19
+ f = function () { n.parentNode.insertBefore(s, n); };
20
+ s.type = "text/javascript";
21
+ s.async = true;
22
+ s.src = "https://mc.yandex.ru/metrika/watch.js";
23
+
24
+ if (w.opera == "[object Opera]") {
25
+ d.addEventListener("DOMContentLoaded", f, false);
26
+ } else { f(); }
27
+ })(document, window, "yandex_metrika_callbacks");
28
+
29
+ noscript
30
+ div= image_tag "https://mc.yandex.ru/watch/#{counter_id}", style: "position:absolute; left:-9999px;", alt: ""
31
+ /! Yandex.Metrika counter
@@ -0,0 +1,28 @@
1
+ - alt_obj ||= nil
2
+
3
+ - if obj.respond_to?(:keywords) and !obj.keywords.blank?
4
+ meta{name="keywords" content=obj.keywords}/
5
+ - else
6
+ - if alt_obj and alt_obj.respond_to?(:keywords) and !alt_obj.keywords.blank?
7
+ meta{name="keywords" content=alt_obj.keywords}/
8
+
9
+
10
+ - if obj.respond_to?(:description) and !obj.description.blank?
11
+ meta{name="description" content=obj.description}/
12
+ - else
13
+ - if alt_obj and alt_obj.respond_to?(:description) and !alt_obj.description.blank?
14
+ meta{name="description" content=alt_obj.description}/
15
+
16
+
17
+ - if obj.respond_to?(:author) and !obj.author.blank?
18
+ meta{name="author" content=obj.author}/
19
+ - else
20
+ - if alt_obj and alt_obj.respond_to?(:author) and !alt_obj.author.blank?
21
+ meta{name="author" content=alt_obj.author}/
22
+
23
+
24
+ - if obj.respond_to?(:robots) and !obj.robots.blank?
25
+ meta{name="robots" content=obj.robots}/
26
+ - else
27
+ - if alt_obj and alt_obj.respond_to?(:robots) and !alt_obj.robots.blank?
28
+ meta{name="robots" content=alt_obj.robots}/
@@ -0,0 +1,38 @@
1
+ - obj ||= nil
2
+ - unless obj.nil?
3
+
4
+ - _cache_helper = (Hancock::Seo.config.cache_support ? :hancock_cache : :cache)
5
+ - send _cache_helper, [obj, @seo_page].uniq do
6
+ .text_content
7
+ - seo = obj.seo
8
+ - if (!defined?(h1) || h1) && seo and !seo.h1.blank?
9
+ h1= seo.h1
10
+
11
+ - if obj.content.blank?
12
+ - unless @seo_page.nil?
13
+ == @seo_page.page_content(self) rescue @seo_page.page_content
14
+ - else
15
+ - if defined?(Hancock::Pages::Page) and obj.is_a?(Hancock::Pages::Page)
16
+ == obj.page_content(self) rescue obj.page_content
17
+ - else
18
+ - if obj.respond_to?(:page_content)
19
+ == obj.page_content rescue obj.content
20
+ - else
21
+ == obj.content
22
+
23
+ = render 'blocks/seo_block_with_obj', obj: obj
24
+
25
+ / = render 'shared/admin_link', obj: obj
26
+ / - if !@seo_page.nil? && (@seo_page.id != obj.id || @seo_page.class.name != obj.class.name)
27
+ / = render 'shared/admin_link', obj: @seo_page
28
+
29
+ / - content_for :meta do
30
+ / - send _cache_helper, [obj, 'meta'] do
31
+ / = render 'shared/meta', obj: obj, alt_obj: @seo_page
32
+ / - og_title = (obj.get_og_title.blank? and @seo_page ? @seo_page.get_og_title : obj.get_og_title)
33
+ / - og_image = (obj.og_image.blank? and @seo_page ? @seo_page.og_image : obj.og_image)
34
+ / = render 'shared/og', title: _og_title, image: _og_image
35
+ /
36
+ / - content_for :title do
37
+ / - if obj.title
38
+ / = obj.title
@@ -0,0 +1,4 @@
1
+ - if defined?(title) && !title.blank?
2
+ meta{property='og:title' content=title}
3
+ - if defined?(image) && !image.blank?
4
+ meta{property='og:image' content="http://#{request.host_with_port}#{image}"}
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "hancock_cms_seo"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,7 @@
1
+ Hancock.rails_admin_configure do |config|
2
+ config.action_visible_for :sitemap, Proc.new { false }
3
+ config.action_visible_for :sitemap_for_model, 'Hancock::Seo::SitemapData'
4
+
5
+ config.action_visible_for :robots_txt, Proc.new { false }
6
+ config.action_visible_for :robots_txt_for_model, 'Hancock::Seo::Seo'
7
+ end
@@ -0,0 +1,37 @@
1
+ ru:
2
+ hancock:
3
+ seo_n_sitemap: SEO и карта сайта
4
+ seo:
5
+ seo: SEO
6
+ sitemap_data: Карта сайта
7
+
8
+
9
+ mongoid: &mongoid
10
+ models:
11
+ hancock/seo/seo: SEO
12
+ hancock/seo/sitemap_data: Карта сайта
13
+ activerecord:
14
+ <<: *mongoid
15
+
16
+ attributes:
17
+ hancock/seo/seo:
18
+ seoable: Родительский элемент/страница
19
+ title: Title
20
+ description: SEO Description
21
+ keywords: SEO Keywords
22
+ og_title: Og title
23
+ og_image: Og image
24
+ robots: Robots
25
+ hancock/seo/sitemap_data:
26
+ sitemap_data_field: Родительский элемент/страница
27
+ sitemap_show: Отображать в карте сайта
28
+ sitemap_lastmod: lastmod
29
+ sitemap_changefreq: changefreq
30
+ sitemap_priority: priority
31
+
32
+ admin:
33
+ actions:
34
+ hancock_sitemap_generate:
35
+ menu: "Сгенирить карту сайта"
36
+ breadcrumb: "Сгенирить карту сайта"
37
+ title: "Сгенирить карту сайта"
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hancock/seo/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hancock_cms_seo"
8
+ spec.version = Hancock::Seo::VERSION
9
+ spec.authors = ["Alexander Kiseliev"]
10
+ spec.email = ["dev@redrocks.pro"]
11
+
12
+ spec.description = %q{hancock_cms_seo }
13
+ spec.summary = %q{hancock_cms_seo}
14
+ spec.homepage = 'https://github.com/red-rocks/hancock_cms_seo'
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ # if spec.respond_to?(:metadata)
20
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
+ # else
22
+ # raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ # end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.10"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+
33
+ spec.add_dependency 'hancock_cms', [">=1.0.2", "<2.1.x"]
34
+ # spec.add_dependency 'hancock_cms', ["~> 1.0.2", "~> 2.0"]
35
+
36
+ spec.add_dependency "sitemap_generator", '~> 5.3.1' #5.2.0
37
+ spec.add_dependency "rails_admin_sitemap", '~> 0.3.0'
38
+
39
+ spec.add_dependency "rails_admin_robots_txt", '~> 0.1.0'
40
+ end
@@ -0,0 +1,13 @@
1
+ require 'rails/generators'
2
+
3
+ module Hancock::Seo
4
+ class ConfigGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ desc 'Hancock::Seo Config generator'
8
+ def config
9
+ template 'hancock_seo.erb', "config/initializers/hancock_seo.rb"
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ Hancock::Seo.configure do |config|
2
+ ##### defaults #####
3
+ # config.localize = Hancock.config.localize
4
+ #
5
+ # config.gallery_support = !!defined?(Hancock::Gallery)
6
+
7
+ # config.model_settings_support = !!defined?(RailsAdminModelSettings)
8
+ # config.user_abilities_support = !!defined?(RailsAdminUserAbilities)
9
+ # config.ra_comments_support = !!defined?(RailsAdminComments)
10
+ end
@@ -0,0 +1,18 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/active_record'
3
+
4
+ module Hancock::Seo
5
+ class MigrationsGenerator < Rails::Generators::Base
6
+ include ActiveRecord::Generators::Migration
7
+ source_root File.expand_path('../templates', __FILE__)
8
+
9
+ desc 'Hancock SEO migration generator'
10
+ def migrations
11
+ if Hancock.active_record?
12
+ %w(seos).each do |table_name|
13
+ migration_template "migration_#{table_name}.rb", "db/migrate/hancock_create_#{table_name}.rb"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,48 @@
1
+ class HancockCreateSeos < ActiveRecord::Migration
2
+ def change
3
+ ############## SEO ###################33
4
+ create_table :hancock_seo_seos do |t|
5
+ t.boolean :enabled, default: true, null: false
6
+ t.integer :seoable_id
7
+ t.string :seoable_type
8
+
9
+ if Hancock::Seo.config.localize
10
+ t.column :h1_translations, 'hstore', default: {}
11
+ t.column :title_translations, 'hstore', default: {}
12
+ t.column :keywords_translations, 'hstore', default: {}
13
+ t.column :description_translations, 'hstore', default: {}
14
+ t.column :og_title_translations, 'hstore', default: {}
15
+ else
16
+ t.string :h1
17
+ t.string :title
18
+ t.text :keywords
19
+ t.text :description
20
+ t.string :og_title
21
+ end
22
+ t.string :robots
23
+ t.attachment :og_image
24
+
25
+ t.timestamps
26
+ end
27
+
28
+ add_index :hancock_seo_seos, [:seoable_id, :seoable_type], unique: true
29
+
30
+
31
+
32
+ ################# SITEMAP #####################
33
+ create_table :hancock_seo_sitemap_data do |t|
34
+ t.boolean :enabled, default: true, null: false
35
+ t.integer :sitemap_data_field_id
36
+ t.string :sitemap_data_field_type
37
+
38
+ t.boolean :sitemap_show, default: true, null: false
39
+ t.timestamps :sitemap_lastmod
40
+ t.string :sitemap_changefreq
41
+ t.float :sitemap_priority
42
+
43
+ t.timestamps
44
+ end
45
+
46
+ add_index :hancock_seo_sitemap_data, [:sitemap_data_field_id, :sitemap_data_field_type], unique: true
47
+ end
48
+ end