Skip to content

Commit 02cc08f

Browse files
davidfischeragjohnson
authored andcommitted
Allow promos to be placed in the docs footer (#3267)
- this is in addition to the normal left navigation - works on the RTD and Alabaster themes
1 parent e737d78 commit 02cc08f

File tree

5 files changed

+146
-82
lines changed

5 files changed

+146
-82
lines changed

media/css/readthedocs-doc-embed.css

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,21 @@
88
}
99

1010
.rst-other-versions {
11-
text-align: left;
11+
text-align: left;
1212
}
1313

1414
.rst-other-versions a {
15-
border: 0;
15+
border: 0;
1616
}
1717

1818
.rst-other-versions dl {
19-
margin: 0;
19+
margin: 0;
2020
}
2121

2222

2323
/* Fix RTD theme bottom margin */
2424
.rst-content .line-block {
25-
margin-bottom: 24px
25+
margin-bottom: 24px
2626
}
2727

2828
/* Fix for nav bottom padding with flyout */
@@ -134,11 +134,39 @@ div.rtd-pro.alabaster div.rtd-pro-about a {
134134
border-bottom: 0px;
135135
}
136136

137-
div.rtd-pro.alabaster div.rtd-pro-about i.fa-info-circle:before {
137+
div.rtd-pro.alabaster div.rtd-pro-about i.fa-info-circle:before,
138+
div.rtd-pro.rtd-pro-footer div.rtd-pro-about i.fa-info-circle:before {
138139
content: "";
139140
color: #a3a3a3;
140141
}
141142

143+
/* Hide the "sponsored" note in the left navigation */
144+
div.rtd-pro-about span {
145+
display: none;
146+
}
147+
148+
/* Footer promos */
149+
div.rtd-pro.rtd-pro-footer div.rtd-pro-about span {
150+
display: inline;
151+
}
152+
div.rtd-pro.rtd-pro-footer div.rtd-pro-about {
153+
float: none;
154+
}
155+
div.rtd-pro.rtd-pro-footer div.rtd-pro-about a {
156+
text-decoration: none;
157+
}
158+
div.rtd-pro.rtd-pro-footer {
159+
text-align: left;
160+
}
161+
div.rtd-pro.rtd-pro-footer a.rtd-pro-image-wrapper {
162+
float: right;
163+
margin-left: 25px;
164+
}
165+
166+
div.rtd-pro-wrapper {
167+
clear: both;
168+
}
169+
142170
@media (max-width: 768px) {
143171
div.rst-pro.wy-menu {
144172
display: none;

readthedocs/core/static-src/core/js/doc-embed/constants.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,9 @@ exports.PROMO_SUPPORTED_THEMES = [
1010
exports.THEME_ALABASTER
1111
]
1212

13+
exports.PROMO_TYPES = {
14+
LEFTNAV: 'doc', // Left navigation on documentation pages
15+
FOOTER: 'site-footer' // Footer of documentation pages
16+
};
17+
1318
module.exports = exports;

readthedocs/core/static-src/core/js/doc-embed/footer.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ function injectFooter(data) {
7373
data.promo_data.text,
7474
data.promo_data.link,
7575
data.promo_data.image,
76-
config.theme
76+
config.theme,
77+
data.promo_data.display_type
7778
)
7879
if (promo) {
7980
promo.display();

readthedocs/core/static-src/core/js/sponsorship.js

Lines changed: 105 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -6,107 +6,137 @@ module.exports = {
66
Promo: Promo
77
};
88

9-
function Promo (id, text, link, image, theme) {
9+
function Promo (id, text, link, image, theme, display_type) {
1010
this.id = id;
1111
this.text = text;
1212
this.link = link;
1313
this.image = image;
1414
this.theme = theme || constants.THEME_RTD;
15+
this.display_type = display_type || constants.PROMO_TYPES.LEFTNAV;
1516
this.promo = null;
17+
18+
// Handler when a promo receives a click
19+
this.click_handler = function () {
20+
if (_gaq) {
21+
_gaq.push(
22+
['rtfd._setAccount', 'UA-17997319-1'],
23+
['rtfd._trackEvent', 'Promo', 'Click', self.id]
24+
);
25+
}
26+
};
1627
}
1728

1829
Promo.prototype.create = function () {
1930
var self = this,
2031
menu,
2132
promo_class;
2233
if (this.theme == constants.THEME_RTD) {
23-
menu = this.get_sphinx_rtd_theme_menu();
24-
promo_class = 'wy-menu';
34+
menu = this.get_sphinx_rtd_theme_promo_selector();
35+
promo_class = this.display_type === constants.PROMO_TYPES.FOOTER ? 'rtd-pro-footer' : 'wy-menu';
2536
}
2637
else if (this.theme == constants.THEME_ALABASTER) {
27-
menu = this.get_alabaster_menu();
28-
promo_class = 'alabaster';
38+
menu = this.get_alabaster_promo_selector();
39+
promo_class = this.display_type === constants.PROMO_TYPES.FOOTER ? 'rtd-pro-footer' : 'alabaster';
2940
}
30-
if (typeof(menu) != 'undefined') {
31-
// Add elements
32-
promo = $('<div />')
33-
.attr('class', 'rtd-pro ' + promo_class);
34-
35-
// Promo info
36-
var promo_about = $('<div />')
37-
.attr('class', 'rtd-pro-about');
38-
var promo_about_link = $('<a />')
39-
.attr('href', 'https://readthedocs.org/sustainability/advertising/')
40-
.appendTo(promo_about);
41-
var promo_about_icon = $('<i />')
42-
.attr('class', 'fa fa-info-circle')
43-
.appendTo(promo_about_link);
44-
promo_about.appendTo(promo);
45-
46-
// On Click handler
47-
function promo_click() {
48-
if (_gaq) {
49-
_gaq.push(
50-
['rtfd._setAccount', 'UA-17997319-1'],
51-
['rtfd._trackEvent', 'Promo', 'Click', self.id]
52-
);
53-
}
54-
}
55-
56-
// Promo image
57-
if (self.image) {
58-
var promo_image_link = $('<a />')
59-
.attr('class', 'rtd-pro-image-wrapper')
60-
.attr('href', self.link)
61-
.attr('target', '_blank')
62-
.on('click', promo_click);
63-
var promo_image = $('<img />')
64-
.attr('class', 'rtd-pro-image')
65-
.attr('src', self.image)
66-
.appendTo(promo_image_link);
67-
promo.append(promo_image_link);
68-
}
6941

70-
// Create link with callback
71-
var promo_text = $('<span />')
72-
.html(self.text);
73-
$(promo_text).find('a').each(function () {
74-
$(this)
75-
.attr('class', 'rtd-pro-link')
76-
.attr('href', self.link)
77-
.attr('target', '_blank')
78-
.on('click', promo_click);
79-
});
80-
promo.append(promo_text);
81-
82-
promo.appendTo(menu);
83-
84-
promo.wrapper = $('<div />')
85-
.attr('class', 'rtd-pro-wrapper')
86-
.appendTo(menu);
87-
88-
return promo;
42+
if (typeof(menu) != 'undefined') {
43+
this.place_promo(menu, promo_class);
8944
}
9045
}
9146

92-
Promo.prototype.get_alabaster_menu = function () {
47+
Promo.prototype.place_promo = function (selector, promo_class) {
48+
var self = this;
49+
50+
// Add elements
51+
var promo = $('<div />')
52+
.attr('class', 'rtd-pro ' + promo_class);
53+
54+
// Promo info
55+
var promo_about = $('<div />')
56+
.attr('class', 'rtd-pro-about');
57+
var promo_about_link = $('<a />')
58+
.attr('href', 'https://readthedocs.org/sustainability/advertising/')
59+
.appendTo(promo_about);
60+
$('<span />').text('Sponsored ').appendTo(promo_about_link);
61+
var promo_about_icon = $('<i />')
62+
.attr('class', 'fa fa-info-circle')
63+
.appendTo(promo_about_link);
64+
promo_about.appendTo(promo);
65+
66+
// Promo image
67+
if (self.image) {
68+
var promo_image_link = $('<a />')
69+
.attr('class', 'rtd-pro-image-wrapper')
70+
.attr('href', self.link)
71+
.attr('target', '_blank')
72+
.on('click', this.click_handler);
73+
var promo_image = $('<img />')
74+
.attr('class', 'rtd-pro-image')
75+
.attr('src', self.image)
76+
.appendTo(promo_image_link);
77+
promo.append(promo_image_link);
78+
}
79+
80+
// Create link with callback
81+
var promo_text = $('<span />')
82+
.html(self.text);
83+
$(promo_text).find('a').each(function () {
84+
$(this)
85+
.attr('class', 'rtd-pro-link')
86+
.attr('href', self.link)
87+
.attr('target', '_blank')
88+
.on('click', this.click_handler);
89+
});
90+
promo.append(promo_text);
91+
92+
promo.appendTo(selector);
93+
94+
promo.wrapper = $('<div />')
95+
.attr('class', 'rtd-pro-wrapper')
96+
.appendTo(selector);
97+
98+
return promo;
99+
};
100+
101+
Promo.prototype.get_alabaster_promo_selector = function () {
102+
// Return a jQuery selector where the promo goes on the Alabaster theme
93103
var self = this,
94-
nav_side = $('div.sphinxsidebar > div.sphinxsidebarwrapper');
104+
selector;
105+
106+
if (self.display_type === constants.PROMO_TYPES.FOOTER) {
107+
selector = $('<div />')
108+
.attr('class', 'rtd-pro-footer-wrapper body')
109+
.appendTo('div.bodywrapper');
110+
$('<hr />').insertBefore(selector);
111+
$('<hr />').insertAfter(selector);
112+
} else {
113+
selector = $('div.sphinxsidebar > div.sphinxsidebarwrapper');
114+
}
95115

96-
if (nav_side.length) {
97-
return nav_side;
116+
if (selector.length) {
117+
return selector;
98118
}
99-
}
119+
};
100120

101121

102-
Promo.prototype.get_sphinx_rtd_theme_menu = function () {
122+
Promo.prototype.get_sphinx_rtd_theme_promo_selector = function () {
123+
// Return a jQuery selector where the promo goes on the RTD theme
103124
var self = this,
104-
nav_side = $('nav.wy-nav-side > div.wy-side-scroll');
125+
selector;
126+
127+
if (self.display_type === constants.PROMO_TYPES.FOOTER) {
128+
selector = $('<div />')
129+
.attr('class', 'rtd-pro-footer-wrapper')
130+
.insertBefore('footer hr');
131+
$('<hr />').insertBefore(selector);
132+
} else {
133+
selector = $('nav.wy-nav-side > div.wy-side-scroll');
134+
}
105135

106-
if (nav_side.length) {
107-
return nav_side;
136+
if (selector.length) {
137+
return selector;
108138
}
109-
}
139+
};
110140

111141
// Position promo
112142
Promo.prototype.display = function () {
@@ -121,10 +151,10 @@ Promo.prototype.display = function () {
121151
if (promo) {
122152
promo.show();
123153
}
124-
}
154+
};
125155

126156
Promo.prototype.disable = function () {
127-
}
157+
};
128158

129159
// Variant factory method
130160
Promo.from_variants = function (variants) {

readthedocs/core/static/core/js/readthedocs-doc-embed.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)