mirror of https://github.com/zulip/zulip.git
portico: Add setting to put Google Analytics on selected portico pages.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
8fb1f2af58
commit
4362cceffb
|
@ -31,6 +31,7 @@
|
|||
"file-loader": "^6.0.0",
|
||||
"flatpickr": "^4.5.7",
|
||||
"font-awesome": "^4.7.0",
|
||||
"ga-gtag": "^1.0.1",
|
||||
"handlebars": "^4.7.2",
|
||||
"handlebars-loader": "^1.7.1",
|
||||
"html-webpack-plugin": "^4.0.0-beta.8",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import "./common.js";
|
||||
import "../i18n.js";
|
||||
import "../portico/header.js";
|
||||
import "../portico/google-analytics.js";
|
||||
import "../../styles/portico/portico-styles.scss";
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
import { gtag, install } from "ga-gtag";
|
||||
|
||||
export let config;
|
||||
|
||||
if (page_params.google_analytics_id !== undefined) {
|
||||
install(page_params.google_analytics_id);
|
||||
config = (info) => gtag("config", page_params.google_analytics_id, info);
|
||||
} else {
|
||||
config = () => {};
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import * as google_analytics from './google-analytics.js';
|
||||
import SimpleBar from 'simplebar';
|
||||
import {activate_correct_tab} from './tabbed-instructions.js';
|
||||
|
||||
|
@ -93,6 +94,7 @@ const update_page = function (html_map, path) {
|
|||
scrollToHash(markdownSB);
|
||||
});
|
||||
}
|
||||
google_analytics.config({page_path: path});
|
||||
};
|
||||
|
||||
new SimpleBar($(".sidebar")[0]);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import * as google_analytics from './google-analytics.js';
|
||||
import blueslip from './../blueslip';
|
||||
|
||||
import { path_parts } from './landing-page';
|
||||
|
@ -72,6 +73,7 @@ function update_path() {
|
|||
}
|
||||
|
||||
window.history.pushState(state, '', next_path);
|
||||
google_analytics.config({page_path: next_path});
|
||||
}
|
||||
|
||||
function update_categories() {
|
||||
|
@ -306,6 +308,7 @@ function dispatch(action, payload) {
|
|||
|
||||
case 'LOAD_PATH':
|
||||
render(get_state_from_path());
|
||||
google_analytics.config({page_path: window.location.pathname});
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import * as google_analytics from './google-analytics.js';
|
||||
import { detect_user_os } from './tabbed-instructions.js';
|
||||
import render_tabs from './team.js';
|
||||
|
||||
|
@ -126,6 +127,7 @@ const apps_events = function () {
|
|||
version = get_version_from_path();
|
||||
update_page();
|
||||
$("body").animate({ scrollTop: 0 }, 200);
|
||||
google_analytics.config({page_path: window.location.pathname});
|
||||
});
|
||||
|
||||
$(".apps a .icon").click(function (e) {
|
||||
|
@ -137,6 +139,7 @@ const apps_events = function () {
|
|||
update_path();
|
||||
update_page();
|
||||
$("body").animate({ scrollTop: 0 }, 200);
|
||||
google_analytics.config({page_path: window.location.pathname});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
|
|
@ -44,4 +44,4 @@ API_FEATURE_LEVEL = 4
|
|||
# historical commits sharing the same major version, in which case a
|
||||
# minor version bump suffices.
|
||||
|
||||
PROVISION_VERSION = '82.1'
|
||||
PROVISION_VERSION = '82.2'
|
||||
|
|
|
@ -5006,6 +5006,11 @@ functional-red-black-tree@^1.0.0, functional-red-black-tree@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
||||
|
||||
ga-gtag@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ga-gtag/-/ga-gtag-1.0.1.tgz#c23d9b0619cee1eec7670f6db26dd071d614a6f4"
|
||||
integrity sha512-wWPLuVwmfMfiK5KI7w59fN5kTONRnsSmnejoDo7+6tOulxxKgTSkB4kJcgBa3VfKAunvjopAOGp/5L/BTYZftw==
|
||||
|
||||
gamma@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/gamma/-/gamma-0.1.0.tgz#3315643403bf27906ca80ab37c36ece9440ef330"
|
||||
|
|
|
@ -16,6 +16,7 @@ from django.shortcuts import resolve_url
|
|||
from django.utils.decorators import available_attrs
|
||||
from django.utils.timezone import now as timezone_now
|
||||
from django.conf import settings
|
||||
from django.template.response import SimpleTemplateResponse
|
||||
|
||||
from zerver.lib.exceptions import UnexpectedWebhookEventType
|
||||
from zerver.lib.queue import queue_json_publish
|
||||
|
@ -825,3 +826,20 @@ def zulip_otp_required(view: Any=None,
|
|||
redirect_field_name=redirect_field_name)
|
||||
|
||||
return decorator if (view is None) else decorator(view)
|
||||
|
||||
def add_google_analytics_context(context: Dict[str, Any]) -> None:
|
||||
if settings.GOOGLE_ANALYTICS_ID is not None: # nocoverage
|
||||
context.setdefault("page_params", {})["google_analytics_id"] = settings.GOOGLE_ANALYTICS_ID
|
||||
|
||||
def add_google_analytics(view_func: ViewFuncT) -> ViewFuncT:
|
||||
@wraps(view_func)
|
||||
def _wrapped_view_func(request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
|
||||
response = view_func(request, *args, **kwargs)
|
||||
if isinstance(response, SimpleTemplateResponse):
|
||||
if response.context_data is None:
|
||||
response.context_data = {}
|
||||
add_google_analytics_context(response.context_data)
|
||||
elif response.status_code == 200: # nocoverage
|
||||
raise TypeError("add_google_analytics requires a TemplateResponse")
|
||||
return response
|
||||
return _wrapped_view_func # type: ignore[return-value] # https://github.com/python/mypy/issues/1927
|
||||
|
|
|
@ -9,6 +9,7 @@ import os
|
|||
import random
|
||||
import re
|
||||
|
||||
from zerver.decorator import add_google_analytics_context
|
||||
from zerver.lib.integrations import CATEGORIES, INTEGRATIONS, HubotIntegration, \
|
||||
WebhookIntegration
|
||||
from zerver.lib.request import has_request_variables, REQ
|
||||
|
@ -123,6 +124,7 @@ class MarkdownDirectoryView(ApiURLView):
|
|||
add_api_uri_context(api_uri_context, self.request)
|
||||
api_uri_context["run_content_validators"] = True
|
||||
context["api_uri_context"] = api_uri_context
|
||||
add_google_analytics_context(context)
|
||||
return context
|
||||
|
||||
def get(self, request: HttpRequest, article: str="") -> HttpResponse:
|
||||
|
@ -170,6 +172,7 @@ class IntegrationView(ApiURLView):
|
|||
context: Dict[str, Any] = super().get_context_data(**kwargs)
|
||||
add_integrations_context(context)
|
||||
add_integrations_open_graph_context(context, self.request)
|
||||
add_google_analytics_context(context)
|
||||
return context
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ from django.shortcuts import redirect, render
|
|||
from django.utils import translation
|
||||
from django.utils.cache import patch_cache_control
|
||||
|
||||
from zerver.context_processors import latest_info_context
|
||||
from zerver.decorator import zulip_login_required
|
||||
from zerver.forms import ToSForm
|
||||
from zerver.models import Message, Stream, UserProfile, \
|
||||
|
@ -25,6 +24,7 @@ from zerver.lib.utils import statsd, generate_random_token
|
|||
from zerver.views.compatibility import is_outdated_desktop_app, \
|
||||
is_unsupported_browser
|
||||
from zerver.views.messages import get_latest_update_message_flag_activity
|
||||
from zerver.views.portico import hello_view
|
||||
from two_factor.utils import default_device
|
||||
|
||||
import calendar
|
||||
|
@ -145,7 +145,7 @@ def home(request: HttpRequest) -> HttpResponse:
|
|||
if subdomain != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN:
|
||||
return home_real(request)
|
||||
|
||||
return render(request, 'zerver/hello.html', latest_info_context())
|
||||
return hello_view(request)
|
||||
|
||||
@zulip_login_required
|
||||
def home_real(request: HttpRequest) -> HttpResponse:
|
||||
|
|
|
@ -1,23 +1,28 @@
|
|||
from django.conf import settings
|
||||
from django.http import HttpRequest, HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import render
|
||||
from django.template.response import TemplateResponse
|
||||
import ujson
|
||||
|
||||
from zerver.context_processors import get_realm_from_request
|
||||
from zerver.decorator import redirect_to_login
|
||||
from zerver.context_processors import get_realm_from_request, latest_info_context
|
||||
from zerver.decorator import add_google_analytics, redirect_to_login
|
||||
from zerver.models import Realm
|
||||
from version import LATEST_DESKTOP_VERSION
|
||||
|
||||
@add_google_analytics
|
||||
def apps_view(request: HttpRequest, _: str) -> HttpResponse:
|
||||
if settings.ZILENCER_ENABLED:
|
||||
return render(request, 'zerver/apps.html',
|
||||
context={
|
||||
"page_params": {
|
||||
'electron_app_version': LATEST_DESKTOP_VERSION,
|
||||
}
|
||||
})
|
||||
return TemplateResponse(
|
||||
request,
|
||||
'zerver/apps.html',
|
||||
context={
|
||||
"page_params": {
|
||||
'electron_app_version': LATEST_DESKTOP_VERSION,
|
||||
}
|
||||
}
|
||||
)
|
||||
return HttpResponseRedirect('https://zulipchat.com/apps/', status=301)
|
||||
|
||||
@add_google_analytics
|
||||
def plans_view(request: HttpRequest) -> HttpResponse:
|
||||
realm = get_realm_from_request(request)
|
||||
realm_plan_type = 0
|
||||
|
@ -28,9 +33,13 @@ def plans_view(request: HttpRequest) -> HttpResponse:
|
|||
return HttpResponseRedirect('https://zulipchat.com/plans')
|
||||
if not request.user.is_authenticated:
|
||||
return redirect_to_login(next="plans")
|
||||
return render(request, "zerver/plans.html",
|
||||
context={"realm_plan_type": realm_plan_type, 'free_trial_months': free_trial_months})
|
||||
return TemplateResponse(
|
||||
request,
|
||||
"zerver/plans.html",
|
||||
context={"realm_plan_type": realm_plan_type, 'free_trial_months': free_trial_months},
|
||||
)
|
||||
|
||||
@add_google_analytics
|
||||
def team_view(request: HttpRequest) -> HttpResponse:
|
||||
if not settings.ZILENCER_ENABLED:
|
||||
return HttpResponseRedirect('https://zulipchat.com/team/', status=301)
|
||||
|
@ -41,7 +50,7 @@ def team_view(request: HttpRequest) -> HttpResponse:
|
|||
except FileNotFoundError:
|
||||
data = {'contrib': {}, 'date': "Never ran."}
|
||||
|
||||
return render(
|
||||
return TemplateResponse(
|
||||
request,
|
||||
'zerver/team.html',
|
||||
context={
|
||||
|
@ -56,10 +65,24 @@ def get_isolated_page(request: HttpRequest) -> bool:
|
|||
'''Accept a GET param `?nav=no` to render an isolated, navless page.'''
|
||||
return request.GET.get('nav') == 'no'
|
||||
|
||||
def terms_view(request: HttpRequest) -> HttpResponse:
|
||||
return render(request, 'zerver/terms.html',
|
||||
context={'isolated_page': get_isolated_page(request)})
|
||||
@add_google_analytics
|
||||
def landing_view(request: HttpRequest, template_name: str) -> HttpResponse:
|
||||
return TemplateResponse(request, template_name)
|
||||
|
||||
@add_google_analytics
|
||||
def hello_view(request: HttpRequest) -> HttpResponse:
|
||||
return TemplateResponse(request, 'zerver/hello.html', latest_info_context())
|
||||
|
||||
@add_google_analytics
|
||||
def terms_view(request: HttpRequest) -> HttpResponse:
|
||||
return TemplateResponse(
|
||||
request, 'zerver/terms.html',
|
||||
context={'isolated_page': get_isolated_page(request)},
|
||||
)
|
||||
|
||||
@add_google_analytics
|
||||
def privacy_view(request: HttpRequest) -> HttpResponse:
|
||||
return render(request, 'zerver/privacy.html',
|
||||
context={'isolated_page': get_isolated_page(request)})
|
||||
return TemplateResponse(
|
||||
request, 'zerver/privacy.html',
|
||||
context={'isolated_page': get_isolated_page(request)},
|
||||
)
|
||||
|
|
|
@ -370,3 +370,6 @@ FREE_TRIAL_MONTHS = None
|
|||
# users, and you would like to save some disk space. Soft-deactivated
|
||||
# returning users would still be caught-up normally.
|
||||
AUTO_CATCH_UP_SOFT_DEACTIVATED_USERS = True
|
||||
|
||||
# Enables Google Analytics on selected portico pages.
|
||||
GOOGLE_ANALYTICS_ID: Optional[str] = None
|
||||
|
|
|
@ -35,7 +35,6 @@ import zerver.views.streams
|
|||
import zerver.views.realm
|
||||
import zerver.views.digest
|
||||
import zerver.views.messages
|
||||
from zerver.context_processors import latest_info_context
|
||||
import zerver.views.realm_export
|
||||
import zerver.views.upload
|
||||
|
||||
|
@ -548,23 +547,24 @@ i18n_urls = [
|
|||
url(r'^integrations/(.*)$', IntegrationView.as_view()),
|
||||
|
||||
# Landing page, features pages, signup form, etc.
|
||||
url(r'^hello/$', TemplateView.as_view(template_name='zerver/hello.html',
|
||||
get_context_data=latest_info_context),
|
||||
name='landing-page'),
|
||||
url(r'^hello/$', zerver.views.portico.hello_view, name='landing-page'),
|
||||
url(r'^new-user/$', RedirectView.as_view(url='/hello', permanent=True)),
|
||||
url(r'^features/$', TemplateView.as_view(template_name='zerver/features.html')),
|
||||
url(r'^features/$', zerver.views.portico.landing_view, {'template_name': 'zerver/features.html'}),
|
||||
url(r'^plans/$', zerver.views.portico.plans_view, name='plans'),
|
||||
url(r'^apps/(.*)$', zerver.views.portico.apps_view, name='zerver.views.home.apps_view'),
|
||||
url(r'^team/$', zerver.views.portico.team_view),
|
||||
url(r'^history/$', TemplateView.as_view(template_name='zerver/history.html')),
|
||||
url(r'^why-zulip/$', TemplateView.as_view(template_name='zerver/why-zulip.html')),
|
||||
url(r'^for/open-source/$', TemplateView.as_view(template_name='zerver/for-open-source.html')),
|
||||
url(r'^for/companies/$', TemplateView.as_view(template_name='zerver/for-companies.html')),
|
||||
url(r'^for/working-groups-and-communities/$',
|
||||
TemplateView.as_view(template_name='zerver/for-working-groups-and-communities.html')),
|
||||
url(r'^for/mystery-hunt/$', TemplateView.as_view(template_name='zerver/for-mystery-hunt.html')),
|
||||
url(r'^security/$', TemplateView.as_view(template_name='zerver/security.html')),
|
||||
url(r'^atlassian/$', TemplateView.as_view(template_name='zerver/atlassian.html')),
|
||||
url(r'^history/$', zerver.views.portico.landing_view, {'template_name': 'zerver/history.html'}),
|
||||
url(r'^why-zulip/$', zerver.views.portico.landing_view, {'template_name': 'zerver/why-zulip.html'}),
|
||||
url(r'^for/open-source/$', zerver.views.portico.landing_view,
|
||||
{'template_name': 'zerver/for-open-source.html'}),
|
||||
url(r'^for/companies/$', zerver.views.portico.landing_view,
|
||||
{'template_name': 'zerver/for-companies.html'}),
|
||||
url(r'^for/working-groups-and-communities/$', zerver.views.portico.landing_view,
|
||||
{'template_name': 'zerver/for-working-groups-and-communities.html'}),
|
||||
url(r'^for/mystery-hunt/$', zerver.views.portico.landing_view,
|
||||
{'template_name': 'zerver/for-mystery-hunt.html'}),
|
||||
url(r'^security/$', zerver.views.portico.landing_view, {'template_name': 'zerver/security.html'}),
|
||||
url(r'^atlassian/$', zerver.views.portico.landing_view, {'template_name': 'zerver/atlassian.html'}),
|
||||
|
||||
# Terms of Service and privacy pages.
|
||||
url(r'^terms/$', zerver.views.portico.terms_view, name='terms'),
|
||||
|
|
Loading…
Reference in New Issue