Extension:MobileFrontend/Configuring browser auto-detection/ru

This page is a translated version of the page Extension:MobileFrontend/Configuring browser auto-detection and the translation is 26% complete.

В этом документе объясняется, как администратор сайта может включить мобильный сайт для расширения своей mediawiki, так что, когда пользователь посещает сайт с мобильного устройства, он автоматически перенаправляется на мобильную версию, а не на десктопную.

Встроенное автоопределение

Начиная с 5a1867e, MobileFrontend поддерживает автоматическое обнаружение устройства с минимальной конфигурацией. Всё, что вам нужно сделать, это установить $wgMFAutodetectMobileView = true; в свой LocalSettings.php. Хотя это самый простой способ, он почти наверняка будет наименее результативным. Это решение НЕ совместимо с фронт-энд кэшированием, так как он не позволяет вашему кешу знать разницу между мобильной и десктопной версий.

Apache Mobile Filter (AMF)

Начиная с 0fb2c72d, MobileFrontend поддерживает Apache Mobile Filter (AMF) для обнаружения устройства. Вы должны использовать веб-сервер Apache. Следуйте инструкциям по настройке AMF, и он должен "просто работать". Это очень похоже на встроенное автоматическое обнаружение и не будет совместимо с кэшированием фронт-энд без специальной настройки.

Webserver/proxy-cache device detection

Some reverse proxies (like Varnish ) can inform MediaWiki whether mobile version is needed or not, thus creating a cache-friendly autodetection.

For Varnish 4.0 or later, replace the keyword remove with unset.

Detection using Varnish: mobile site on another domain

Suppose we use Varnish, and we want wiki.example.com to show desktop version, and m.wiki.example.com to show mobile version. Here is how to do that.

sub vcl_recv {
	remove req.http.x-subdomain; # Requester shouldn't be allowed to supply arbitrary X-Subdomain header
	if (req.http.host == "m.wiki.example.com") { # mobile domain
		set req.http.host = "wiki.example.com"; # desktop domain
		set req.http.x-subdomain = "m";
	}
}
sub vcl_hash {
	# Cache the mobile version of pages separately.
	#
	# NOTE: x-subdomain header should only have one value (if it exists), therefore vcl_recv() should remove user-supplied X-Subdomain header.
	hash_data(req.http.x-subdomain);
}

LocalSettings.php should contain the following:

$wgMFAutodetectMobileView = false;
$wgMobileUrlCallback = fn ( $domain ) => "m.$domain"; // domain for mobile site
$wgCookieDomain = ".wiki.example.com";

Where "%h<#>" maps to a segment of the hostname of $wgServer. So, if $wgServer = 'en.wikipedia.org';, %h0 is "en", %h1 is "wikipedia", %h2 is "org". Given this, the above $wgMobileUrlTemplate will automatically interpolate your mobile URL as "en.m.wikipedia.org". This is particularly useful for the WMF and projects like Wikipedia, which follow a template of <lang code>.wikipedia.org, so the mobile domain will always look like <lang code>.m.wikipedia.org.

In this solution, built-in autodetection should be disabled ($wgMFAutodetectMobileView = false;), so that MediaWiki wouldn't question the decisions of Varnish.

Detection using Varnish: same domain for desktop/mobile site

Suppose we use Varnish, and we want wiki.example.com to show desktop/mobile version on the very same URLs (without creating additional domains like "m.wiki.example.com", etc.). Here is how to do that.

sub vcl_recv {
	remove req.http.x-subdomain; # Requester shouldn't be allowed to supply arbitrary X-Subdomain header
	if(req.http.User-Agent ~ "(?i)^(lg-|sie-|nec-|lge-|sgh-|pg-)|(mobi|240x240|240x320|320x320|alcatel|android|audiovox|bada|benq|blackberry|cdm-|compal-|docomo|ericsson|hiptop|htc[-_]|huawei|ipod|kddi-|kindle|meego|midp|mitsu|mmp\/|mot-|motor|ngm_|nintendo|opera.m|palm|panasonic|philips|phone|playstation|portalmmm|sagem-|samsung|sanyo|sec-|sendo|sharp|softbank|symbian|teleca|up.browser|webos)") {
		set req.http.x-subdomain = "m";
	}

	if(req.http.Cookie ~ "mf_useformat=") {
		# This means user clicked on Toggle link "Mobile view" in the footer.
		# Inform vcl_hash() that this should be cached as mobile page.
		set req.http.x-subdomain = "m";
	}
}
sub vcl_hash {
	# Cache the mobile version of pages separately.
	#
	# NOTE: x-subdomain header should only have one value (if it exists), therefore vcl_recv() should remove user-supplied X-Subdomain header.
	hash_data(req.http.x-subdomain);
}

LocalSettings.php should contain the following:

$wgMFAutodetectMobileView = true;
$wgCookieDomain = ".wiki.example.com";
In this solution, built-in autodetection should be enabled (it won't impact the cache):
$wgMFAutodetectMobileView = true;

Otherwise MobileFrontend misbehaves (if we don't set $wgMobileUrlCallback, it ignores X-Subdomain header, if we do, it doesn't set "useformat" cookies for "toggle Mobile view" links in the footer").

Detection using nginx: mobile site on another domain

Suppose we use nginx, and we want wiki.example.com to show desktop version, and m.wiki.example.com to show mobile version. Here's how to do that. This configuration mimics the behavior of WMF sites.

# [...]

server_tokens off;
set_real_ip_from localhost;
real_ip_header X-Forwarded-For;

map $cookie_stopMobileRedirect $mobile_redirect {
	default ?01;
	"" ${http_sec_ch_ua_mobile}1;
}

ssl_certificate /path/to/ssl-certificate.pem;
ssl_certificate_key /path/to/ssl-certificate-key.pem;
ssl_dhparam /path/to/ssl-dhparams.pem;

server {
	listen 443 ssl;
	listen [::]:443 ssl;

	root /var/www/html/example;

	index index.php;

	server_name localhost;

	location ~ ^/w/(index|load|api|thumb|opensearch_desc|rest|img_auth)\.php$ {
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		fastcgi_pass unix:/run/php/php8.1-fpm.sock;
	}

	location /w/images {}

	location /w/images/deleted {
		deny all;
	}

	location ~ ^/w/resources/(assets|lib|src) {
		try_files $uri 404;
		add_header Cache-Control "public" always;
		expires 7d;
	}

	location ~ ^/w/(skins|extensions)/.+\.(css|js|gif|jpg|jpeg|png|svg|wasm|ttf|woff|woff2)$ {
		try_files $uri 404;
		add_header Cache-Control "public" always;
		expires 7d;
	}

	location = /w/images/favicon.svg {
		add_header Cache-Control "public" always;
		expires 7d;
	}

	location = /favicon.ico {
		rewrite ^ /w/images/favicon.ico;
	}

	location = /w/images/favicon.ico {
		add_header Cache-Control "public" always;
		expires 7d;
	}

	location /w/sitemap {}

	location = /sitemap.xml {
		rewrite ^ /w/sitemap/sitemap-index-wiki.xml;
	}

	location ~ ^/w/(COPYING|CREDITS)$ {
		default_type text/plain;
	}

	location /w/rest.php/ {
		try_files $uri $uri/ /w/rest.php?$query_string;
	}

	location /wiki/ {
		rewrite ^/wiki/(?<pagename>.*)$ /w/index.php;
	}

	location = / {
		return 301 /wiki/Main_Page;
	}

	location / {
		return 404;
	}

	error_page 404 /w/images/404.html;

	location /w/images/404.html {
		internal;
	}
}

server {
	listen 80 default_server;
	listen [::]:80 default_server;

	server_name wiki.example.com;

	return 301 https://$host$request_uri;

	return 404;
}

server {
	listen 443 default_server ssl;
	listen [::]:443 default_server ssl;

	server_name wiki.example.com;

	location / {
		if ($arg_mobileaction = toggle_view_desktop) {
			add_header Set-Cookie "stopMobileRedirect=true; Domain=.wiki.example.com; Path=/; Max-Age=2592000; HttpOnly; Secure";
			break;
		}

		if ($mobile_redirect != ?01) {
			return 302 https://m.wiki.example.com$request_uri;
		}

		if ($http_host != wiki.example.com) {
			return 301 https://wiki.example.com$request_uri;
		}

		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_pass https://localhost;
	}
}

server {
	listen 443 ssl;
	listen [::]:443 ssl;

	server_name m.wiki.example.com;

	location / {
		if ($arg_mobileaction = toggle_view_mobile) {
			add_header Set-Cookie "stopMobileRedirect=; Domain=.wiki.example.com; Path=/; Max-Age=0; HttpOnly; Secure";
		}

		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Subdomain m;
		proxy_pass https://localhost;
	}
}

LocalSettings.php should contain the following:

$wgMFAutodetectMobileView = false;
$wgMobileUrlCallback = fn ( $domain ) => "m.$domain";
$wgCookieDomain = ".wiki.example.com";