in2code/ipandlanguageredirect

自动或通过建议链接将TYPO3访客重定向到另一种语言和/或根页面。

安装数: 22,156

依赖项: 0

建议者: 0

安全: 1

星标: 14

关注者: 8

分支: 14

开放问题: 10

类型:typo3-cms-extension


README

TYPO3 FE访客自动或手动重定向到另一个语言或另一个根页面。

简介

本扩展允许通过重定向到最适合的页面(基于访客的浏览器语言和地区(IP地址))来实现多语言和多域名处理。

AJAX请求(仅VanillaJS - 无需JavaScript框架)将处理服务器端域名逻辑以重定向或建议新的网页或新的语言。

在您的PHP配置中定义哪些国家属于哪个页面树以及哪些浏览器语言属于哪个前端语言

简而言之

自动重定向或显示注释,为访客提供最适合其需求的网站版本。

屏幕截图

前端示例建议消息:建议语言

如何获取用户的地区代码?

这完全取决于您。您可以选择不同的ip2country服务类。一方面,有一个本地表包含IP范围和国家,另一方面,您还可以使用外部服务将访客的IP转换为countryCode。第一种方法尊重所有隐私,而第二种方法当然更为现代。

或者:您可以组合不同的方法:因为IpApi的服务每月免费1000次请求,您可以使用这个服务,并附加离线表变体。

默认可用的类

  • In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\IpApi - 这使用外部服务ipapi.co将IP地址转换为国家代码。注意:如果您想每月使用超过1000次请求,可以通过TypoScript设置API密钥。
  • In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\LocalDatabase - 这使用本地数据库表tx_ipandlanguageredirect_domain_model_iptocountry将IP地址转换为国家 - 无外部服务,最大隐私。
  • In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\IpApiCom - 这使用外部服务ip-api.com将IP地址转换为国家代码。注意:因为此服务无法使用HTTPS,所有请求都通过端口80处理。

转到扩展管理器设置并选择要使用的类,或者简单添加您自己的服务。例如,扩展管理器设置中的ipToCountryService字符串可以是In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\IpApi,In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\LocalDatabase,以使用IpApi的服务,只要它是免费的,然后回退到本地数据库。

与其他扩展(如rmpl_language_detect)相比有什么区别?

在概念上存在一个基本区别。虽然大多数语言重定向扩展通过USER_INT钩入页面渲染过程,但我们选择了JavaScript和PHP(AJAX)的异步方式。这种解决方案需要JavaScript,但另一方面对于高可用性和更复杂的网站来说要快得多。这意味着:您可以使用例如 staticfilecache 或其他静态解决方案来提高网页性能。虽然不能在包含在每个页面的USER_INT中使用staticfilecache。

测试!

此扩展允许您测试如果来自不同国家的访客检查您的网站时,您的网站将如何反应。下面提供了许多测试选项。

安装

  • 安装此扩展
  • 添加一个静态模板(页面.5将用于建议容器,页面.1555用于脚本)
  • 将ipandlanguageredirect/Configuration/Redirect/Redirect.php中的原始配置复制到任何其他位置
  • 根据需要修改配置
  • 在扩展管理器中设置新路径到您的配置文件
  • 祝您玩得开心!

示例配置

<?php
return [
    // Example action
    'actions' => [
        [
            // Automatic redirect to best fitting uri if visitor comes from a search engine
            'referrers' => [
                'google.',
                'bing.',
                'yahoo.',
                't-online.',
                'yandex.',
                'baidu.'
            ],
            'events' => [
                'redirect'
            ]
        ],
        [
            // For all other cases: Suggest a better fitting page
            'referrers' => [
                '*'
            ],
            'events' => [
                'suggest'
            ]
        ],
        [
            // Disable redirect for pages inside the given pid
            'pidInRootline' => [
                '129',
                '11',
            ],
            'events' => [
                'none',
            ],
        ],
        [
            // Prevent redirect for google pagespeed access
            'userAgent' => [
                'Chrome-Lighthouse'
            ],
            'events' => [
                'none'
            ]
        ],
    ],
    'globalConfiguration' => [
        // don't show suggest or redirect on a subpage
        'actionOnHomeOnly' => false,

        // always redirect to the home-page, don not try to stay on the same page while changing the language
        'stayOnCurrentPage' => false
    ],
    // configuration if nothing matches
    'noMatchingConfiguration' => [
        'identifierUsage' => 'worldwide_english',
        'matchMinQuantifier' => 15
    ],
    // main redirect configuration
    'redirectConfiguration' => [

        // Build URI to page 1 if visitors came from anywhere in the world
        1 => [

            // Build URI to language 0 if browser language is not defined here
            0 => [
                'identifier' => 'worldwide_english',
                'domain' => [
                    'www.domain.com',
                    'test.domain.org'
                ],
                'browserLanguage' => [
                    '*'
                ],
                'countryBasedOnIp' => [
                    '*'
                ]
            ],

            // Build URI to language 1 if browser language is german "de"
            1 => [
                'identifier' => 'worldwide_german',
                'domain' => [
                    'www.domain.com',
                    'test.domain.org'
                ],
                'browserLanguage' => [
                    'de'
                ],
                'countryBasedOnIp' => [
                    '*'
                ]
            ],

            // Build URI to language 2 if browser language is chinese "zh"
            2 => [
                'identifier' => 'worldwide_chinese',
                'domain' => [
                    'www.domain.com',
                    'test.domain.org'
                ],
                'browserLanguage' => [
                    'zh'
                ],
                'countryBasedOnIp' => [
                    '*'
                ]
            ],
        ],

        // Build URI to page 2 if visitors came from USA, Canada or Argentina
        2 => [

            // Build URI to language 0 if browser language is not defined here
            0 => [
                'identifier' => 'america_english',
                'domain' => [
                    'www.seconddomain.org',
                    'test.seconddomain.org'
                ],
                'browserLanguage' => [
                    '*'
                ],
                'countryBasedOnIp' => [
                    'ca',
                    'us',
                    'ar',
                ]
            ],

            // Build URI to language 1 if browser language is german "de"
            1 => [
                'identifier' => 'worldwide_german',
                'domain' => [
                    'www.seconddomain.org',
                    'test.seconddomain.org'
                ],
                'browserLanguage' => [
                    'de'
                ],
                'countryBasedOnIp' => [
                    '*'
                ]
            ],
        ],
    ],
    // Quantifiers for the matches (shouldn't be touched)
    'quantifier' => [
        'browserLanguage' => [
            'totalMatch' => 7,
            'wildCardMatch' => 3
        ],
        'countryBasedOnIp' => [
            'totalMatch' => 13,
            'wildCardMatch' => 5
        ],
        'domain' => [
            'totalMatch' => 10,
            'wildCardMatch' => 4
        ],
        'actions' => [
            'referrers' => [
                'totalMatch' => 7,
                'wildCardMatch' => 3,
            ],
            'userAgents' => [
                'totalMatch' => 7,
                'wildCardMatch' => 3,
            ],
            'pidInRootline' => 9999
        ]
    ]
];

TypoScript

如果您添加了静态TypoScript,则这些行具有影响

plugin.tx_ipandlanguageredirect {
	view {
		templateRootPaths {
			0 = EXT:ipandlanguageredirect/Resources/Private/Templates/
			1 = {$plugin.tx_ipandlanguageredirect.view.templateRootPath}
		}
	}
	features.requireCHashArgumentForActionArguments = 0

	settings {
		# Add configuration to your IpToCountry service classes
		ipToCountry {
			In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\IpApi {
				# IpApi Key: Please enter your key for ipapi.co (optional), otherwise extension will have limited access to the service (less then 1000 visitors a day). See ipapi.co for details.
				ipApiKey =
			}
		}
	}
}

page {
	includeJSFooter.ipandlanguageredirect = EXT:ipandlanguageredirect/Resources/Public/JavaScripts/Frontend.min.js
	includeCSS.ipandlanguageredirect = EXT:ipandlanguageredirect/Resources/Public/Css/Frontend.min.css

	# Suggest container that can be slided down
	5 = USER
	5 {
		userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
		extensionName = Ipandlanguageredirect
		pluginName = Pi1
		vendorName = In2code
		controller = Redirect
		action = suggest
		switchableControllerActions.Redirect.1 = suggest
	}

	# Container for informations that will be send to an AJAX service
	1555 = COA
	1555 {
		wrap = <script id="ipandlanguageredirect_container"|></script>

		# Uri to send AJAX request to
		10 = TEXT
		10 {
			noTrimWrap = | data-ipandlanguageredirect-ajaxuri="|"|
			typolink {
				parameter.data = TSFE:id
				additionalParams = &type=1555
				returnLast = url
				forceAbsoluteUrl = 1
			}
		}

		# FE language
		20 = TEXT
		20 {
			noTrimWrap = | data-ipandlanguageredirect-languageuid="|"|
			data = sitelanguage:languageId
			ifEmpty.data = GP:L
			intval = 1
		}

		# Root page uid
		30 = TEXT
		30 {
			noTrimWrap = | data-ipandlanguageredirect-rootpageuid="|"|
			data = leveluid:0
		}

		# Fake browser language for testing - e.g. &tx_ipandlanguageredirect_pi1[browserLanguage]=en
		40 = TEXT
		40 {
			noTrimWrap = | data-ipandlanguageredirect-browserlanguage="|"|
			data = GP:tx_ipandlanguageredirect_pi1|browserLanguage
			htmlSpecialChars = 1
			required = 1
		}

		# Fake ip-address for testing - e.g. &tx_ipandlanguageredirect_pi1[ipAddress]=66.85.131.18 (USA)
		50 = TEXT
		50 {
			noTrimWrap = | data-ipandlanguageredirect-ipaddress="|"|
			data = GP:tx_ipandlanguageredirect_pi1|ipAddress
			htmlSpecialChars = 1
			required = 1
		}

		# Fake country for testing (overlays ip-address) - e.g. &tx_ipandlanguageredirect_pi1[countryCode]=us (USA)
		60 = TEXT
		60 {
			noTrimWrap = | data-ipandlanguageredirect-countrycode="|"|
			data = GP:tx_ipandlanguageredirect_pi1|countryCode
			htmlSpecialChars = 1
			required = 1
		}

		# Fake referrer for testing - e.g. &tx_ipandlanguageredirect_pi1[referrer]=www.google.de
		70 = TEXT
		70 {
			noTrimWrap = | data-ipandlanguageredirect-referrer="|"|
			data = GP:tx_ipandlanguageredirect_pi1|referrer
			htmlSpecialChars = 1
			required = 1
		}

		# Fake domain for testing - e.g. &tx_ipandlanguageredirect_pi1[domain]=www.production.org
		80 = TEXT
		80 {
			noTrimWrap = | data-ipandlanguageredirect-domain="|"|
			data = GP:tx_ipandlanguageredirect_pi1|domain
			htmlSpecialChars = 1
			required = 1
		}
	}
}

# AJAX types
redirectAjax = PAGE
redirectAjax {
	typeNum = 1555
	config {
		additionalHeaders = Content-Type: application/json
		additionalHeaders.10.header = Content-Type: application/json
		no_cache = 1
		disableAllHeaderCode = 1
		disablePrefixComment = 1
		xhtml_cleaning = 0
		admPanel = 0
		debug = 0
	}

	10  = USER
	10 {
		userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
		extensionName = Ipandlanguageredirect
		pluginName = Pi1
		vendorName = In2code
		controller = Redirect
		action = redirect
		switchableControllerActions.Redirect.1 = redirect
	}
}
testAjax < redirectAjax
testAjax {
	typeNum = 1556
	10.action = test
	10.switchableControllerActions.Redirect.1 = test
}

测试

模拟浏览器语言、国家/地区和引用者

http://domain.org/index.php?id=1
&tx_ipandlanguageredirect_pi1[ipAddress]=66.85.131.18
&tx_ipandlanguageredirect_pi1[browserLanguage]=de
&tx_ipandlanguageredirect_pi1[referrer]=www.google.de
&tx_ipandlanguageredirect_pi1[countryCode]=af
&tx_ipandlanguageredirect_pi1[domain]=www.domain.org
&no_cache=1

注意:请注意,这些设置默认情况下会被缓存。因此,您必须始终添加一个 &no_cache=1

不进行重定向或建议,但在浏览器控制台显示重定向Uri

http://domain.org/index.php?id=1
&ipandlanguagedebug=1

来自您的服务器的示例回答

{
  "redirectUri": "https:\/\/local.domain.org\/de\/",
  "activated": true,
  "events": [
    "redirect"
  ],
  "activatedReasons": {
    "differentLanguages": true,
    "differentRootpages": false
  },
  "country": "jp",
  "givenParameters": {
    "browserLanguage": "de",
    "referrer": "www.google.de",
    "ipAddress": "27.121.255.4",
    "languageUid": 0,
    "rootpageUid": 209,
    "countryCodeOverlay": "",
    "domain": "local.domain.org"
  }
}

常见问题解答

  • 隐藏建议消息
    • Q1:如何禁用点击我自己的链接时出现的建议消息?
    • A1:您可以在页面上任何位置添加带有属性 data-ipandlanguageredirect-action="hideMessage" 的链接或其他DOM元素来禁用建议消息。用例:如果用户手动更改您的网站上的区域或语言,则消息应在将来消失。
    • Q2:如何使用GET参数禁用建议消息?
    • A2:如果给出GET参数 &h=1&h=3,则消息将被隐藏,并将设置用于隐藏它的cookie。
  • 禁用重定向
    • Q1:如何禁用点击我自己的链接时出现重定向?
    • A1:您可以在页面上任何位置添加带有属性 data-ipandlanguageredirect-action="disableRedirect" 的链接或其他DOM元素来禁用重定向。
    • Q2:如何使用GET参数禁用重定向?
    • A2:如果给出GET参数 &h=2&h=3,则通过设置cookie禁用重定向。
  • Cookie有效期
    • 默认cookie有效期是临时的——只要浏览器打开。目前无法调整。
  • 测试
    • Q1:我如何测试另一个IP地址、地区或浏览器语言?
    • A1:请参阅测试部分
    • Q2:我可以在哪里看到通过AJAX发送和接收的参数?
    • A2:打开您的浏览器控制台并检查到 ?type=1555 的post请求——检查参数或答案
  • Typenum不会工作
    • Q1:在TYPO3 9或更高版本中,我的请求不会工作——我该怎么办?
    • Q1:您必须定义在路由配置中使用的type参数(请参阅以下示例)

路由示例

routeEnhancers:
    PageTypeSuffix:
        type: PageType
        map:
            redirect.json: 1555

您的贡献

普遍欢迎 拉取请求!不过,请别忘了在您的拉取请求中添加描述。这非常有帮助,可以理解 PR 将要解决的问题。

  • 修复错误:请描述您的修复解决了哪种类型的错误,并给我反馈如何重现问题。我只会接受我可以重现的错误修复。
  • 特性:并非所有特性都适用于大部分扩展用户。请在讨论新特性之前进行讨论。

使用ddev进行贡献

需求

  1. 安装ddev,请参阅:https://ddev.readthedocs.io/en/stable/#installation
  2. 安装git-lfs,请参阅:https://git-lfs.github.com/

安装

  1. 克隆此仓库
  2. 运行 ddev start
  3. 运行 ddev initialize 来设置配置和测试数据库

目前(尚)不可能的功能

  • 在浏览器语言中启用通配符使用(例如,“en*”用于所有英语浏览器语言)
  • 支持所有浏览器语言,而不仅仅是第一个语言
  • 也支持大洲

变更日志