Skip to content

Commit b549ec9

Browse files
committed
Create a contributors jQuery plugin and apply to the home page
1 parent 2e928da commit b549ec9

File tree

8 files changed

+348
-102
lines changed

8 files changed

+348
-102
lines changed

Diff for: _includes/home/contributors.html

+7-35
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,16 @@
11
<section class="home-contributors">
22
<div class="container">
3-
<h2>Top Recent Contributors</h2>
4-
<p class="intro">Our documentation is open-source on GitHub. Even the smallest of edits are appreciated, as are enhancements and clarifications to our existing content. We love when we get complete new topics from our community members! Below are our top quarterly contributors. See all <a href="{{page.baseurl}}/contributor-guide/quarterly-contributors.html">quarterly contributors</a>.</p>
53

6-
<div class="contributor">
7-
<a href="https://github.com/RakeshJesadiya" class="avatar" target="_blank">
8-
<img src="{{site.baseurl}}/i/contributors/rakesh-jesadiya.png" alt="Rakesh Jesadiya" />
9-
</a>
10-
<h5 class="name"><a href="https://github.com/RakeshJesadiya" target="_blank">Rakesh Jesadiya</a></h5>
11-
<p class="role">Magento Developer</p>
12-
</div>
13-
14-
<div class="contributor">
15-
<a href="https://github.com/lbajsarowicz" class="avatar" target="_blank">
16-
<img src="{{site.baseurl}}/i/contributors/lukasz-bajsarowicz.jpeg" alt="Lukasz Bajsarowicz" />
17-
</a>
18-
<h5 class="name"><a href="https://github.com/lbajsarowicz" target="_blank">Lukasz Bajsarowicz</a></h5>
19-
<p class="role">Magento Developer</p>
20-
</div>
4+
<h2>Top Monthly Contributors</h2>
215

6+
<p class="intro">
7+
Our documentation is open-source on GitHub. Even the smallest of edits are appreciated, as are enhancements and clarifications to our existing content. We love when we get complete new topics from our community members! See <a href="{{ page.baseurl }}/contributor-guide/quarterly-contributors.html">all contributors</a>
8+
</p>
229

23-
<div class="contributor">
24-
<a href="https://github.com/asrar7787" class="avatar" target="_blank">
25-
<img src="{{site.baseurl}}/i/contributors/asrar-alam.jpeg" alt="Asrar Alam" />
26-
</a>
27-
<h5 class="name"><a href="https://github.com/asrar7787" target="_blank">Asrar Alam</a></h5>
28-
<p class="role">Magento Developer</p>
29-
</div>
30-
31-
32-
<div class="contributor">
33-
<a href="https://github.com/ryantfowler" class="avatar" target="_blank">
34-
<img src="{{site.baseurl}}/i/contributors/ryan-fowler.png" alt="Ryan Fowler" />
35-
</a>
36-
<h5 class="name"><a href="https://github.com/ryantfowler" target="_blank">Ryan Fowler</a></h5>
37-
<p class="role">Software Engineer</p>
38-
</div>
10+
<div class="devdocs-contributors" data-contributors-limit="5" data-period-types="monthly"></div>
3911

40-
<div>
41-
<a href="{{ site.baseurl}}/guides/v2.1/contributor-guide/contributing_docs.html" class="btn btn-large btn-primary">Become a Contributor</a>
12+
<div class="home-contributors-buttons">
13+
<a href="{{ page.baseurl }}/contributor-guide/contributing_docs.html" class="btn btn-large btn-primary">Become a Contributor</a>
4214
</div>
4315

4416
</div>

Diff for: common/js/app.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: css/app.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: js/_includes/contributors.js

+219
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
2+
3+
/*!
4+
* contributorsList jQuery plugin
5+
* Author: ybannykh@magento.com
6+
* Gets the JSON file from EngCom database and creates a filterable list
7+
* of contributors.
8+
* Sample usage:
9+
* $('#elem').contributorsList({ contributorsLimit: '3'});
10+
* Options can be also passed from the html data attributes:
11+
* <div id="elem" data-plugin-options='{"contributorsLimit": 3}'>
12+
*/
13+
;(function( $, window, document, undefined ) {
14+
15+
var pluginName = 'contributorsList';
16+
var defaults = {
17+
dataUrl: 'https://s3.amazonaws.com/public.magento.com/devdocs-contributors.js',
18+
periodTypes: 'monthly,quoter,years',
19+
periodTypesSettings: {
20+
monthly: {
21+
label: 'Monthly',
22+
periodsLimit: 12,
23+
contributorsLimit: 5
24+
},
25+
quoter: {
26+
label: 'Quarterly',
27+
periodsLimit: 12,
28+
contributorsLimit: 5
29+
},
30+
years: {
31+
label: 'Yearly',
32+
periodsLimit: 5,
33+
contributorsLimit: 5
34+
}
35+
},
36+
periodsLimit: 12,
37+
contributorsLimit: 50,
38+
// Class names (recommended to not modify)
39+
periodSwitcherClass: 'periods',
40+
loadingClass: 'loading',
41+
loadedClass: 'loaded',
42+
hiddenClass: 'hide',
43+
periodClass: 'contributors-period',
44+
contributorsListClass: 'contributors-list',
45+
};
46+
47+
// The actual plugin constructor
48+
function Plugin( element, options ) {
49+
var plugin = this;
50+
this.element = element;
51+
this.$element = $(element);
52+
this._defaults = defaults;
53+
this._name = pluginName;
54+
// Get data from html (to extend the defaults with data attributes)
55+
this.metadata = this.$element.data();
56+
57+
// Extend defaults with options passed: data-attributes, options, defaults
58+
this.options = $.extend({}, defaults, options, this.metadata);
59+
60+
61+
// * Plugin methods *
62+
63+
// Handle failed load. Removes the loading class so the contributors block becomes invisible
64+
this.onDataFail = function (data) {
65+
plugin.$element.removeClass(plugin.options.loadingClass);
66+
}
67+
68+
// Handle dataload
69+
this.onDataLoaded = function (data) {
70+
// Change element classes
71+
plugin.$element
72+
.removeClass(plugin.options.loadingClass)
73+
.addClass(plugin.options.loadedClass);
74+
75+
// See what periods requested from options, and build UI for each one
76+
var periodContributors = '';
77+
var periodTypesSwitcherOptions = '',
78+
periodTypesSwitcher = '';
79+
80+
// Iterate over period types
81+
var periodTypes = plugin.options.periodTypes.split(',');
82+
$.each( periodTypes, function ( index, value ) {
83+
// Strip whitespaces and make lower case
84+
var periodType = value.replace(/\s/g, '').toLowerCase();
85+
// work only if data has needed periods
86+
if ( data[periodType] ) {
87+
var periodTypeSettings = {
88+
periodType: periodType,
89+
periodTypeLabel: plugin.options.periodTypesSettings[periodType].label,
90+
periodTypeClass: plugin.options.periodClass + (( index != 0 ) ? ' ' + plugin.options.hiddenClass : ''),
91+
periodsLimit: plugin.options.periodTypesSettings[periodType].periodsLimit,
92+
contributorsLimit: plugin.options.periodTypesSettings[periodType].contributorsLimit,
93+
}
94+
95+
periodTypesSwitcherOptions += '<a class="btn" href="#' + periodTypeSettings.periodType + '">' + periodTypeSettings.periodTypeLabel + '</a>';
96+
periodContributors += plugin.buildContributorsPeriod( data[periodType], periodTypeSettings );
97+
}
98+
});
99+
100+
// Only show period swither if more that one period type
101+
if ( periodTypes.length > 1 ) {
102+
periodTypesSwitcher = '<div class="period-type-switcher">' + periodTypesSwitcherOptions + '</div>';
103+
}
104+
105+
// Create a jQuery object out of raw html
106+
var $periodContributors = $( periodTypesSwitcher + periodContributors);
107+
// Assign events
108+
$periodContributors.find('select').on('change', plugin.handlePeriodChange );
109+
// Render the HTML
110+
plugin.$element.append( $periodContributors );
111+
}
112+
113+
114+
// Build contributors for the period type
115+
this.buildContributorsPeriod = function ( contributorsPeriod, periodTypeSettings ) {
116+
// Reverse and limit the array most recent comes first
117+
var periods = contributorsPeriod.periods.reverse().slice( 0, periodTypeSettings.periodsLimit );
118+
119+
var periodSwitcher = '',
120+
periodSwitcherOptions = '',
121+
periodContributors = '';
122+
123+
$.each(periods, function (index, value) {
124+
var period = value;
125+
var periodSettings = {
126+
periodValue: period.value,
127+
periodLabel: period.label,
128+
contributorsLimit: periodTypeSettings.contributorsLimit,
129+
contributorsListClass: plugin.options.contributorsListClass + ((index != 0) ? ' ' + plugin.options.hiddenClass : ''),
130+
}
131+
periodSwitcherOptions += '<option value="' + periodSettings.periodValue + '">' + periodSettings.periodLabel + '</option>';
132+
periodContributors += plugin.buildContributorsList( contributorsPeriod.contributors[ periodSettings.periodValue ], periodSettings );
133+
});
134+
135+
// Build the switcher if more than one period
136+
if ( periods.length > 1 ) {
137+
periodSwitcher = '<div class="' + plugin.options.periodSwitcherClass + '"><select data-period-type="' + periodTypeSettings.periodType + '">' + periodSwitcherOptions + '</select></div>';
138+
}
139+
140+
return '<div class="'+ periodTypeSettings.periodTypeClass + '" data-period-type="' + periodTypeSettings.periodType + '">' + periodSwitcher + periodContributors + '</div>';
141+
}
142+
143+
// Build an HTML list of contributors from data and settings object
144+
this.buildContributorsList = function ( contributors, settings ) {
145+
var output = '';
146+
contributors = contributors.slice( 0, settings.contributorsLimit );
147+
$.each(contributors, function (index, value) {
148+
output += plugin.buildContributor( value );
149+
});
150+
return '<div class="'+ settings.contributorsListClass + '" data-period="'+ settings.periodValue +'" data-period-type="'+ settings.periodType +'">' + output + '</div>';
151+
}
152+
153+
// Builds contributor html string (most performant way of inserting the html)
154+
this.buildContributor = function ( contributor ) {
155+
var name = contributor.name;
156+
var avatar = contributor.avatar;
157+
var url = contributor.user_link;
158+
// Stats
159+
var accepted = contributor.accepted;
160+
var accepted_url = contributor.accepted_url;
161+
var created = contributor.created;
162+
var created_url = contributor.created_url;
163+
var rejected = contributor.rejected;
164+
var rejected_url = contributor.rejected_url;
165+
166+
var stats = '<ul class="contributor-stats"><li class="accepted"><span class="title">Accepted</span> <a href="'+ accepted_url +'">' + accepted + '</a></li><li class="created"><span class="title">Created</span> <a href="'+ created_url +'">'+ created +'</a></li><li class="rejected"><span class="title">Rejected</span> <a href="'+ rejected_url +'">'+ rejected +'</a></li></ul>';
167+
168+
return '<div class="contributor"><a href="'+ url +'"><div class="avatar"><img src="'+ avatar + '" /></div><h5 class="name">' + name + '</h5></a>'+ stats +'</div>';
169+
};
170+
171+
// * Events *
172+
// Handles the change in the period switcher
173+
this.handlePeriodChange = function ( event ) {
174+
var value = event.target.value;
175+
var periodType = event.target.getAttribute('data-period-type');
176+
// Hide other lists of the same type, show the requested list
177+
plugin.$element.
178+
find( '.' + plugin.options.periodClass + '[data-period-type="' + periodType + '"] .' + plugin.options.contributorsListClass )
179+
.addClass( plugin.options.hiddenClass ).
180+
filter('[data-period="' + value + '"]')
181+
.removeClass( plugin.options.hiddenClass );
182+
}
183+
184+
// Handle the change in period type
185+
this.handlePeriodTypeChange = function ( event ) {
186+
var value = event.target.value;
187+
plugin.$element.
188+
find( '.' + plugin.options.periodClass)
189+
.addClass( plugin.options.hiddenClass ).
190+
filter('[data-period-type="' + value + '"]')
191+
.removeClass( plugin.options.hiddenClass );
192+
}
193+
194+
// Begin plugin init
195+
this.init();
196+
}
197+
198+
199+
// Initialize the plugin
200+
Plugin.prototype.init = function () {
201+
// Begin loading the data
202+
this.$element.addClass(this.options.loadingClass);
203+
$.getJSON( this.options.dataUrl, this.onDataLoaded )
204+
.fail( this.onDataFail );
205+
};
206+
207+
// Basic jQuery plugin wrapper
208+
// Prevents multiple instantiations
209+
$.fn[pluginName] = function ( options ) {
210+
return this.each(function () {
211+
if (!$.data(this, 'plugin_' + pluginName)) {
212+
$.data(this, 'plugin_' + pluginName,
213+
new Plugin( this, options ));
214+
}
215+
});
216+
}
217+
218+
219+
})(jQuery, window, document);// end contributors

Diff for: js/app.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//= include _vendor/jsCookie.js
1+
//= include _vendor/jsCookie.js
22
//= include _vendor/affix.js
33
//= include _vendor/scrollspy.js
44
//= include _vendor/clipboard.min.js
@@ -21,6 +21,9 @@ $(function() {
2121
//= include _includes/tutorial.js
2222
//= include _includes/videos.js
2323
//= include _includes/left-navigation.js
24+
//= include _includes/contributors.js
25+
26+
$('.devdocs-contributors').contributorsList();
2427

2528
});
2629
// END document ready

Diff for: scss/app.scss

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
@import 'partials/mrg';
4141
@import 'partials/workflow';
4242
@import 'partials/left-navigation';
43+
@import 'partials/contributors';
4344

4445

4546
.hide {

0 commit comments

Comments
 (0)