소스 검색

added gender function to translations

close #61
Markus-Rost 4 년 전
부모
커밋
ff904ffec6
6개의 변경된 파일136개의 추가작업 그리고 109개의 파일을 삭제
  1. 22 22
      cmds/verify.js
  2. 4 4
      cmds/wiki/fandom/user.js
  3. 6 6
      cmds/wiki/gamepedia/user.js
  4. 11 10
      functions/global_block.js
  5. 65 65
      i18n/en.json
  6. 28 2
      util/i18n.js

+ 22 - 22
cmds/verify.js

@@ -95,8 +95,8 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 			var pagelink = wiki.toLink('User:' + username, '', '', body.query.general, true);
 			var pagelink = wiki.toLink('User:' + username, '', '', body.query.general, true);
 			embed.setTitle( username.escapeFormatting() ).setURL( pagelink );
 			embed.setTitle( username.escapeFormatting() ).setURL( pagelink );
 			if ( queryuser.blockexpiry ) {
 			if ( queryuser.blockexpiry ) {
-				embed.setColor('#FF0000').setDescription( lang.get('verify.user_blocked', '[' + username.escapeFormatting() + '](' + pagelink + ')') );
-				msg.replyMsg( lang.get('verify.user_blocked_reply', username.escapeFormatting()), {embed}, false, false );
+				embed.setColor('#FF0000').setDescription( lang.get('verify.user_blocked', '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
+				msg.replyMsg( lang.get('verify.user_blocked_reply', username.escapeFormatting(), queryuser.gender), {embed}, false, false );
 				
 				
 				if ( reaction ) reaction.removeEmoji();
 				if ( reaction ) reaction.removeEmoji();
 				return;
 				return;
@@ -122,22 +122,22 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 					if ( wiki.endsWith( '.gamepedia.com/' ) ) {
 					if ( wiki.endsWith( '.gamepedia.com/' ) ) {
 						if ( $('.mw-blocklist').length ) {
 						if ( $('.mw-blocklist').length ) {
 							return Promise.reject({
 							return Promise.reject({
-								desc: lang.get('verify.user_gblocked', '[' + username.escapeFormatting() + '](' + pagelink + ')'),
-								reply: lang.get('verify.user_gblocked_reply', username.escapeFormatting())
+								desc: lang.get('verify.user_gblocked', '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender),
+								reply: lang.get('verify.user_gblocked_reply', username.escapeFormatting(), queryuser.gender)
 							});
 							});
 						}
 						}
 					}
 					}
 					else if ( wiki.isFandom() ) {
 					else if ( wiki.isFandom() ) {
 						if ( $('#mw-content-text .errorbox').length ) {
 						if ( $('#mw-content-text .errorbox').length ) {
 							return Promise.reject({
 							return Promise.reject({
-								desc: lang.get('verify.user_disabled', '[' + username.escapeFormatting() + '](' + pagelink + ')'),
-								reply: lang.get('verify.user_disabled_reply', username.escapeFormatting())
+								desc: lang.get('verify.user_disabled', '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender),
+								reply: lang.get('verify.user_disabled_reply', username.escapeFormatting(), queryuser.gender)
 							});
 							});
 						}
 						}
 						else if ( $('.mw-warning-with-logexcerpt').length && !$(".mw-warning-with-logexcerpt .mw-logline-block").length ) {
 						else if ( $('.mw-warning-with-logexcerpt').length && !$(".mw-warning-with-logexcerpt .mw-logline-block").length ) {
 							return Promise.reject({
 							return Promise.reject({
-								desc: lang.get('verify.user_gblocked', '[' + username.escapeFormatting() + '](' + pagelink + ')'),
-								reply: lang.get('verify.user_gblocked_reply', username.escapeFormatting())
+								desc: lang.get('verify.user_gblocked', '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender),
+								reply: lang.get('verify.user_gblocked_reply', username.escapeFormatting(), queryuser.gender)
 							});
 							});
 						}
 						}
 					}
 					}
@@ -183,12 +183,12 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 					if ( discordname.length > 50 ) discordname = discordname.substring(0, 50) + '\u2026';
 					if ( discordname.length > 50 ) discordname = discordname.substring(0, 50) + '\u2026';
 					embed.addField( lang.get('verify.discord'), msg.author.tag.escapeFormatting(), true ).addField( lang.get('verify.wiki'), ( discordname || lang.get('verify.empty') ), true );
 					embed.addField( lang.get('verify.discord'), msg.author.tag.escapeFormatting(), true ).addField( lang.get('verify.wiki'), ( discordname || lang.get('verify.empty') ), true );
 					if ( msg.author.tag.escapeFormatting() !== discordname ) {
 					if ( msg.author.tag.escapeFormatting() !== discordname ) {
-						embed.setColor('#FFFF00').setDescription( lang.get('verify.user_failed', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')') );
+						embed.setColor('#FFFF00').setDescription( lang.get('verify.user_failed', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
 						var help_link = '';
 						var help_link = '';
 						if ( wiki.endsWith( '.gamepedia.com/' ) ) help_link = lang.get('verify.help_gamepedia') + '?c=' + ( msg.guild.id in patreons && patreons[msg.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[msg.guild.id] + ' verify' ) : 'wb' ) + ( msg.channel.name !== 'verification' ? '&ch=' + encodeURIComponent( msg.channel.name ) : '' ) + '&user=' + username.toTitle(true, true) + '&discord=' + encodeURIComponent( msg.author.username ) + '&tag=' + msg.author.discriminator;
 						if ( wiki.endsWith( '.gamepedia.com/' ) ) help_link = lang.get('verify.help_gamepedia') + '?c=' + ( msg.guild.id in patreons && patreons[msg.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[msg.guild.id] + ' verify' ) : 'wb' ) + ( msg.channel.name !== 'verification' ? '&ch=' + encodeURIComponent( msg.channel.name ) : '' ) + '&user=' + username.toTitle(true, true) + '&discord=' + encodeURIComponent( msg.author.username ) + '&tag=' + msg.author.discriminator;
 						else if ( wiki.isFandom() ) help_link = lang.get('verify.help_fandom') + '/' + username.toTitle(true) + '?c=' + ( msg.guild.id in patreons && patreons[msg.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[msg.guild.id] + ' verify' ) : 'wb' ) + ( msg.channel.name !== 'verification' ? '&ch=' + encodeURIComponent( msg.channel.name ) : '' ) + '&user=' + encodeURIComponent( msg.author.username ) + '&tag=' + msg.author.discriminator;
 						else if ( wiki.isFandom() ) help_link = lang.get('verify.help_fandom') + '/' + username.toTitle(true) + '?c=' + ( msg.guild.id in patreons && patreons[msg.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[msg.guild.id] + ' verify' ) : 'wb' ) + ( msg.channel.name !== 'verification' ? '&ch=' + encodeURIComponent( msg.channel.name ) : '' ) + '&user=' + encodeURIComponent( msg.author.username ) + '&tag=' + msg.author.discriminator;
-						if ( help_link.length ) embed.addField( lang.get('verify.notice'), lang.get('verify.help_guide', help_link) + '\n' + help_link );
-						msg.replyMsg( lang.get('verify.user_failed_reply', username.escapeFormatting()), {embed}, false, false );
+						if ( help_link.length ) embed.addField( lang.get('verify.notice'), lang.get('verify.help_guide', help_link, queryuser.gender) + '\n' + help_link );
+						msg.replyMsg( lang.get('verify.user_failed_reply', username.escapeFormatting(), queryuser.gender), {embed}, false, false );
 						
 						
 						if ( reaction ) reaction.removeEmoji();
 						if ( reaction ) reaction.removeEmoji();
 						return;
 						return;
@@ -223,8 +223,8 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 						}
 						}
 					} );
 					} );
 					if ( verified ) {
 					if ( verified ) {
-						embed.setColor('#00FF00').setDescription( lang.get('verify.user_verified', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')') + ( rename ? '\n' + lang.get('verify.user_renamed') : '' ) );
-						var text = lang.get('verify.user_verified_reply', username.escapeFormatting());
+						embed.setColor('#00FF00').setDescription( lang.get('verify.user_verified', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) + ( rename ? '\n' + lang.get('verify.user_renamed', queryuser.gender) : '' ) );
+						var text = lang.get('verify.user_verified_reply', username.escapeFormatting(), queryuser.gender);
 						var verify_promise = [
 						var verify_promise = [
 							msg.member.roles.add( roles, lang.get('verify.audit_reason', username) ).catch( error => {
 							msg.member.roles.add( roles, lang.get('verify.audit_reason', username) ).catch( error => {
 								log_error(error);
 								log_error(error);
@@ -256,8 +256,8 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 						} );
 						} );
 					}
 					}
 					
 					
-					embed.setColor('#FFFF00').setDescription( lang.get('verify.user_matches', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')') );
-					msg.replyMsg( lang.get('verify.user_matches_reply', username.escapeFormatting()), {embed}, false, false );
+					embed.setColor('#FFFF00').setDescription( lang.get('verify.user_matches', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
+					msg.replyMsg( lang.get('verify.user_matches_reply', username.escapeFormatting(), queryuser.gender), {embed}, false, false );
 					
 					
 					if ( reaction ) reaction.removeEmoji();
 					if ( reaction ) reaction.removeEmoji();
 				}, error => {
 				}, error => {
@@ -292,9 +292,9 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 				if ( discordname.length > 50 ) discordname = discordname.substring(0, 50) + '\u2026';
 				if ( discordname.length > 50 ) discordname = discordname.substring(0, 50) + '\u2026';
 				embed.addField( lang.get('verify.discord'), msg.author.tag.escapeFormatting(), true ).addField( lang.get('verify.wiki'), ( discordname || lang.get('verify.empty') ), true );
 				embed.addField( lang.get('verify.discord'), msg.author.tag.escapeFormatting(), true ).addField( lang.get('verify.wiki'), ( discordname || lang.get('verify.empty') ), true );
 				if ( msg.author.tag.escapeFormatting() !== discordname ) {
 				if ( msg.author.tag.escapeFormatting() !== discordname ) {
-					embed.setColor('#FFFF00').setDescription( lang.get('verify.user_failed', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')') );
-					embed.addField( lang.get('verify.notice'), lang.get('verify.help_subpage', '**`' + msg.author.tag + '`**') + '\n' + wiki.toLink('Special:MyPage/Discord', 'action=edit', '', body.query.general) );
-					msg.replyMsg( lang.get('verify.user_failed_reply', username.escapeFormatting()), {embed}, false, false );
+					embed.setColor('#FFFF00').setDescription( lang.get('verify.user_failed', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
+					embed.addField( lang.get('verify.notice'), lang.get('verify.help_subpage', '**`' + msg.author.tag + '`**', queryuser.gender) + '\n' + wiki.toLink('Special:MyPage/Discord', 'action=edit', '', body.query.general) );
+					msg.replyMsg( lang.get('verify.user_failed_reply', username.escapeFormatting(), queryuser.gender), {embed}, false, false );
 					
 					
 					if ( reaction ) reaction.removeEmoji();
 					if ( reaction ) reaction.removeEmoji();
 					return;
 					return;
@@ -329,8 +329,8 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 					}
 					}
 				} );
 				} );
 				if ( verified ) {
 				if ( verified ) {
-					embed.setColor('#00FF00').setDescription( lang.get('verify.user_verified', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')') + ( rename ? '\n' + lang.get('verify.user_renamed') : '' ) );
-					var text = lang.get('verify.user_verified_reply', username.escapeFormatting());
+					embed.setColor('#00FF00').setDescription( lang.get('verify.user_verified', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) + ( rename ? '\n' + lang.get('verify.user_renamed', queryuser.gender) : '' ) );
+					var text = lang.get('verify.user_verified_reply', username.escapeFormatting(), queryuser.gender);
 					var verify_promise = [
 					var verify_promise = [
 						msg.member.roles.add( roles, lang.get('verify.audit_reason', username) ).catch( error => {
 						msg.member.roles.add( roles, lang.get('verify.audit_reason', username) ).catch( error => {
 							log_error(error);
 							log_error(error);
@@ -362,8 +362,8 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 					} );
 					} );
 				}
 				}
 				
 				
-				embed.setColor('#FFFF00').setDescription( lang.get('verify.user_matches', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')') );
-				msg.replyMsg( lang.get('verify.user_matches_reply', username.escapeFormatting()), {embed}, false, false );
+				embed.setColor('#FFFF00').setDescription( lang.get('verify.user_matches', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
+				msg.replyMsg( lang.get('verify.user_matches_reply', username.escapeFormatting(), queryuser.gender), {embed}, false, false );
 				
 				
 				if ( reaction ) reaction.removeEmoji();
 				if ( reaction ) reaction.removeEmoji();
 			}, error => {
 			}, error => {

+ 4 - 4
cmds/wiki/fandom/user.js

@@ -240,9 +240,9 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 					for ( var i = 0; i < usergroups.length; i++ ) {
 					for ( var i = 0; i < usergroups.length; i++ ) {
 						if ( groups.includes( usergroups[i] ) && ( group.length === 1 || !['autoconfirmed', 'user'].includes( usergroups[i] ) ) ) {
 						if ( groups.includes( usergroups[i] ) && ( group.length === 1 || !['autoconfirmed', 'user'].includes( usergroups[i] ) ) ) {
 							if ( usergroups[i] === 'wiki-manager' && body.query.allmessages[0]['*'] === username ) {
 							if ( usergroups[i] === 'wiki-manager' && body.query.allmessages[0]['*'] === username ) {
-								group.push('**' + lang.get('user.groups.' + usergroups[i]) + '**');
+								group.push('**' + lang.get('user.groups.' + usergroups[i], queryuser.gender) + '**');
 							}
 							}
-							else group.push(lang.get('user.groups.' + usergroups[i]));
+							else group.push(lang.get('user.groups.' + usergroups[i], queryuser.gender));
 						}
 						}
 					}
 					}
 					var isBlocked = false;
 					var isBlocked = false;
@@ -258,7 +258,7 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 					var blockedby = '[[User:' + queryuser.blockedby + '|' + queryuser.blockedby + ']]';
 					var blockedby = '[[User:' + queryuser.blockedby + '|' + queryuser.blockedby + ']]';
 					var blockreason = queryuser.blockreason;
 					var blockreason = queryuser.blockreason;
 					var block = {
 					var block = {
-						header: lang.get('user.block.header', username).escapeFormatting(),
+						header: lang.get('user.block.header', username, queryuser.gender).escapeFormatting(),
 						text: lang.get('user.block.nofrom' + ( blockreason ? 'text' : 'noreason' ), '', blockexpiry ),
 						text: lang.get('user.block.nofrom' + ( blockreason ? 'text' : 'noreason' ), '', blockexpiry ),
 						by: blockedby,
 						by: blockedby,
 						reason: blockreason
 						reason: blockreason
@@ -331,7 +331,7 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 						}
 						}
 						
 						
-						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler) );
+						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler, queryuser.gender) );
 						
 						
 						if ( reaction ) reaction.removeEmoji();
 						if ( reaction ) reaction.removeEmoji();
 					} );
 					} );

+ 6 - 6
cmds/wiki/gamepedia/user.js

@@ -231,10 +231,10 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 						if ( groups.includes( usergroups[i] ) && ( group.length === 1 || !['autoconfirmed', 'user'].includes( usergroups[i] ) ) ) {
 						if ( groups.includes( usergroups[i] ) && ( group.length === 1 || !['autoconfirmed', 'user'].includes( usergroups[i] ) ) ) {
 							var thisSite = allSites.find( site => site.wiki_domain === body.query.general.servername );
 							var thisSite = allSites.find( site => site.wiki_domain === body.query.general.servername );
 							if ( usergroups[i] === 'wiki_manager' && thisSite && thisSite.wiki_managers.includes( username ) ) {
 							if ( usergroups[i] === 'wiki_manager' && thisSite && thisSite.wiki_managers.includes( username ) ) {
-								group.push('**' + lang.get('user.groups.' + usergroups[i]) + '**');
+								group.push('**' + lang.get('user.groups.' + usergroups[i], queryuser.gender) + '**');
 							}
 							}
 							else if ( !groups.includes( 'global_' + usergroups[i] ) || queryuser.groupmemberships.some( member => member.group === usergroups[i] ) ) {
 							else if ( !groups.includes( 'global_' + usergroups[i] ) || queryuser.groupmemberships.some( member => member.group === usergroups[i] ) ) {
-								group.push(lang.get('user.groups.' + usergroups[i]));
+								group.push(lang.get('user.groups.' + usergroups[i], queryuser.gender));
 							}
 							}
 						}
 						}
 					}
 					}
@@ -252,7 +252,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 					var blockedby = queryuser.blockedby;
 					var blockedby = queryuser.blockedby;
 					var blockreason = queryuser.blockreason;
 					var blockreason = queryuser.blockreason;
 					var block = {
 					var block = {
-						header: lang.get('user.block.header', username).escapeFormatting(),
+						header: lang.get('user.block.header', username, queryuser.gender).escapeFormatting(),
 						text: lang.get('user.block.' + ( blockreason ? 'text' : 'noreason' ), blockedtimestamp, blockexpiry),
 						text: lang.get('user.block.' + ( blockreason ? 'text' : 'noreason' ), blockedtimestamp, blockexpiry),
 						by: blockedby,
 						by: blockedby,
 						reason: blockreason
 						reason: blockreason
@@ -322,7 +322,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 						}
 						}
 						
 						
-						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler) );
+						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler, queryuser.gender) );
 						
 						
 						if ( reaction ) reaction.removeEmoji();
 						if ( reaction ) reaction.removeEmoji();
 					} );
 					} );
@@ -383,7 +383,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 						}
 						}
 						
 						
-						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler) );
+						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler, queryuser.gender) );
 						
 						
 						if ( reaction ) reaction.removeEmoji();
 						if ( reaction ) reaction.removeEmoji();
 					} );
 					} );
@@ -401,7 +401,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 							}
 							}
 						}
 						}
 						
 						
-						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler) );
+						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler, queryuser.gender) );
 						
 						
 						if ( reaction ) reaction.removeEmoji();
 						if ( reaction ) reaction.removeEmoji();
 					}
 					}

+ 11 - 10
functions/global_block.js

@@ -10,8 +10,9 @@ const {timeoptions} = require('../util/default.json');
  * @param {import('discord.js').MessageEmbed} embed - The embed for the page.
  * @param {import('discord.js').MessageEmbed} embed - The embed for the page.
  * @param {String} wiki - The wiki for the page.
  * @param {String} wiki - The wiki for the page.
  * @param {String} spoiler - If the response is in a spoiler.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {String} [gender] - The gender of the user.
  */
  */
-function global_block(lang, msg, username, text, embed, wiki, spoiler) {
+function global_block(lang, msg, username, text, embed, wiki, spoiler, gender = 'unknown') {
 	if ( !msg || msg.channel.type !== 'text' || !( msg.guild.id in patreons ) ) return;
 	if ( !msg || msg.channel.type !== 'text' || !( msg.guild.id in patreons ) ) return;
 	
 	
 	if ( msg.showEmbed() ) embed.fields.pop();
 	if ( msg.showEmbed() ) embed.fields.pop();
@@ -31,12 +32,12 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler) {
 		else {
 		else {
 			let $ = cheerio.load(body);
 			let $ = cheerio.load(body);
 			if ( $('#mw-content-text .errorbox').length ) {
 			if ( $('#mw-content-text .errorbox').length ) {
-				if ( msg.showEmbed() ) embed.addField( lang.get('user.gblock.disabled'), '\u200b' );
-				else text += '\n\n**' + lang.get('user.gblock.disabled') + '**';
+				if ( msg.showEmbed() ) embed.addField( lang.get('user.gblock.disabled', gender), '\u200b' );
+				else text += '\n\n**' + lang.get('user.gblock.disabled', gender) + '**';
 			}
 			}
 			else if ( $('.mw-warning-with-logexcerpt').length && !$(".mw-warning-with-logexcerpt .mw-logline-block").length ) {
 			else if ( $('.mw-warning-with-logexcerpt').length && !$(".mw-warning-with-logexcerpt .mw-logline-block").length ) {
-				if ( msg.showEmbed() ) embed.addField( lang.get('user.gblock.header', username).escapeFormatting(), '\u200b' );
-				else text += '\n\n**' + lang.get('user.gblock.header', username).escapeFormatting() + '**';
+				if ( msg.showEmbed() ) embed.addField( lang.get('user.gblock.header', username, gender).escapeFormatting(), '\u200b' );
+				else text += '\n\n**' + lang.get('user.gblock.header', username, gender).escapeFormatting() + '**';
 			}
 			}
 		}
 		}
 	}, error => {
 	}, error => {
@@ -89,8 +90,8 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler) {
 				if ( expiry.startsWith( '(infiniteblock)' ) ) expiry = lang.get('user.block.until_infinity');
 				if ( expiry.startsWith( '(infiniteblock)' ) ) expiry = lang.get('user.block.until_infinity');
 				else expiry = new Date(expiry.replace( /(\d{2}:\d{2}), (\d{1,2}) \((\w+)\) (\d{4})/, '$3 $2, $4 $1 UTC' )).toLocaleString(lang.get('dateformat'), timeoptions);
 				else expiry = new Date(expiry.replace( /(\d{2}:\d{2}), (\d{1,2}) \((\w+)\) (\d{4})/, '$3 $2, $4 $1 UTC' )).toLocaleString(lang.get('dateformat'), timeoptions);
 				if ( msg.showEmbed() ) {
 				if ( msg.showEmbed() ) {
-					var gblocktitle = lang.get('user.gblock.header', username).escapeFormatting();
-					var globalblock = embed.fields.find( field => field.inline === false && field.name === lang.get('user.block.header', username).escapeFormatting() && field.value.replace( /\[([^\]]*)\]\([^\)]*\)/g, '$1' ) === lang.get('user.block.' + ( reason.length > 4 ? 'text' : 'noreason' ), timestamp, expiry, reason[1].escapeFormatting(), reason.slice(4).join(', ').escapeFormatting()) );
+					var gblocktitle = lang.get('user.gblock.header', username, gender).escapeFormatting();
+					var globalblock = embed.fields.find( field => field.inline === false && field.name === lang.get('user.block.header', username, gender).escapeFormatting() && field.value.replace( /\[([^\]]*)\]\([^\)]*\)/g, '$1' ) === lang.get('user.block.' + ( reason.length > 4 ? 'text' : 'noreason' ), timestamp, expiry, reason[1].escapeFormatting(), reason.slice(4).join(', ').escapeFormatting()) );
 					if ( globalblock ) globalblock.name = gblocktitle;
 					if ( globalblock ) globalblock.name = gblocktitle;
 					else {
 					else {
 						var block_wiki = reason[3].replace( /Special:BlockList$/, '' );
 						var block_wiki = reason[3].replace( /Special:BlockList$/, '' );
@@ -99,9 +100,9 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler) {
 					}
 					}
 				}
 				}
 				else {
 				else {
-					var globalblock = splittext.indexOf('**' + lang.get('user.block.header', username).escapeFormatting() + '**\n' + lang.get('user.block.' + ( reason.length > 4 ? 'text' : 'noreason' ), timestamp, expiry, reason[1].escapeFormatting(), reason.slice(4).join(', ').escapeFormatting()));
-					if ( globalblock !== -1 ) splittext[globalblock] = '**' + lang.get('user.gblock.header', username).escapeFormatting() + '**\n' + lang.get('user.block.' + ( reason.length > 4 ? 'text' : 'noreason' ), timestamp, expiry, reason[1].escapeFormatting(), reason.slice(4).join(', ').escapeFormatting());
-					else splittext.push('**' + lang.get('user.gblock.header', username).escapeFormatting() + '**\n' + lang.get('user.gblock.' + ( reason.length > 4 ? 'text' : 'noreason' ), timestamp, expiry, reason[1].escapeFormatting(), reason[2], reason.slice(4).join(', ').escapeFormatting()));
+					var globalblock = splittext.indexOf('**' + lang.get('user.block.header', username, gender).escapeFormatting() + '**\n' + lang.get('user.block.' + ( reason.length > 4 ? 'text' : 'noreason' ), timestamp, expiry, reason[1].escapeFormatting(), reason.slice(4).join(', ').escapeFormatting()));
+					if ( globalblock !== -1 ) splittext[globalblock] = '**' + lang.get('user.gblock.header', username, gender).escapeFormatting() + '**\n' + lang.get('user.block.' + ( reason.length > 4 ? 'text' : 'noreason' ), timestamp, expiry, reason[1].escapeFormatting(), reason.slice(4).join(', ').escapeFormatting());
+					else splittext.push('**' + lang.get('user.gblock.header', username, gender).escapeFormatting() + '**\n' + lang.get('user.gblock.' + ( reason.length > 4 ? 'text' : 'noreason' ), timestamp, expiry, reason[1].escapeFormatting(), reason[2], reason.slice(4).join(', ').escapeFormatting()));
 				}
 				}
 			} );
 			} );
 			text = splittext.join('\n\n');
 			text = splittext.join('\n\n');

+ 65 - 65
i18n/en.json

@@ -584,7 +584,7 @@
     },
     },
     "user": {
     "user": {
         "block": {
         "block": {
-            "header": "$1 is currently blocked!",
+            "header": "$1 is currently {{GENDER:$2|blocked}}!",
             "nofromnoreason": "Blocked until $2 by $3.",
             "nofromnoreason": "Blocked until $2 by $3.",
             "nofromtext": "Blocked until $2 by $3 with reason \"$4\".",
             "nofromtext": "Blocked until $2 by $3 with reason \"$4\".",
             "noreason": "Blocked on $1 until $2 by $3.",
             "noreason": "Blocked on $1 until $2 by $3.",
@@ -592,8 +592,8 @@
             "until_infinity": "the end of all days"
             "until_infinity": "the end of all days"
         },
         },
         "gblock": {
         "gblock": {
-            "disabled": "This account is currently disabled!",
-            "header": "$1 is currently globally blocked!",
+            "disabled": "This account is currently {{GENDER:$1|disabled}}!",
+            "header": "$1 is currently globally {{GENDER:$2|blocked}}!",
             "noreason": "Blocked on $1 until $2 by $3 on $4.",
             "noreason": "Blocked on $1 until $2 by $3 on $4.",
             "text": "Blocked on $1 until $2 by $3 on $4 with reason \"$5\"."
             "text": "Blocked on $1 until $2 by $3 on $4 with reason \"$5\"."
         },
         },
@@ -603,53 +603,53 @@
             "unknown": "Unknown"
             "unknown": "Unknown"
         },
         },
         "groups": {
         "groups": {
-            "Elite_users": "Elite user",
-            "Patrol": "Inspector",
-            "assistant": "Assistant",
-            "authenticated": "authenticated",
-            "autoconfirmed": "Autoconfirmed user",
-            "autopatrol": "autopatrol",
-            "autopatroller": "Auto patroller",
-            "autoreview": "autoreview",
-            "blogpatrol": "Blog patroller",
-            "bot": "Bot",
-            "bot-global": "Global bot",
-            "bureaucrat": "Bureaucrat",
-            "chatmoderator": "Chat moderator",
-            "checkuser": "Check user",
-            "codeeditor": "Code editor",
-            "commentcontrol": "Comment controller",
-            "content-moderator": "Content moderator",
-            "content-team-member": "Content Team Member",
-            "content-volunteer": "Content volunteer",
-            "content_team_member": "Content Team Member",
-            "custodian": "Custodian",
-            "directors": "Director",
-            "doyen": "Dean",
-            "editor": "Editor",
-            "global-discussions-moderator": "Global discussions moderator",
-            "global_bot": "Global bot",
-            "grasp": "GRASP",
-            "helper": "Fandom helper",
-            "hydra_staff": "Gamepedia staff",
-            "imagecontrol": "Image controller",
-            "interface-admin": "Interface administrator",
-            "junioradmin": "Junior administrator",
-            "moderator": "Moderator",
-            "patroller": "Patroller",
-            "patrollers": "Patroller",
-            "rollback": "rollback",
-            "soap": "SOAP",
-            "staff": "Fandom staff",
-            "supmoderator": "Senior moderator",
-            "sysop": "Administrator",
-            "threadmoderator": "Discussions moderator",
-            "user": "User",
-            "vanguard": "Vanguard",
-            "voldev": "Volunteer Developer",
-            "widgeteditor": "Widget editor",
-            "wiki-manager": "Wiki manager",
-            "wiki_manager": "Wiki manager"
+            "Elite_users": "{{GENDER:$1|Elite user}}",
+            "Patrol": "{{GENDER:$1|{{GENDER:$1|Inspector}}}}",
+            "assistant": "{{GENDER:$1|Assistant}}",
+            "authenticated": "{{GENDER:$1|authenticated}}",
+            "autoconfirmed": "{{GENDER:$1|Autoconfirmed user}}",
+            "autopatrol": "{{GENDER:$1|autopatrol}}",
+            "autopatroller": "{{GENDER:$1|Auto patroller}}",
+            "autoreview": "{{GENDER:$1|autoreview}}",
+            "blogpatrol": "{{GENDER:$1|Blog patroller}}",
+            "bot": "{{GENDER:$1|Bot}}",
+            "bot-global": "{{GENDER:$1|Global bot}}",
+            "bureaucrat": "{{GENDER:$1|Bureaucrat}}",
+            "chatmoderator": "{{GENDER:$1|Chat moderator}}",
+            "checkuser": "{{GENDER:$1|Check user}}",
+            "codeeditor": "{{GENDER:$1|Code editor}}",
+            "commentcontrol": "{{GENDER:$1|Comment controller}}",
+            "content-moderator": "{{GENDER:$1|Content moderator}}",
+            "content-team-member": "{{GENDER:$1|Content Team Member}}",
+            "content-volunteer": "{{GENDER:$1|Content volunteer}}",
+            "content_team_member": "{{GENDER:$1|Content Team Member}}",
+            "custodian": "{{GENDER:$1|Custodian}}",
+            "directors": "{{GENDER:$1|Director}}",
+            "doyen": "{{GENDER:$1|Dean}}",
+            "editor": "{{GENDER:$1|Editor}}",
+            "global-discussions-moderator": "{{GENDER:$1|Global discussions moderator}}",
+            "global_bot": "{{GENDER:$1|Global bot}}",
+            "grasp": "{{GENDER:$1|GRASP}}",
+            "helper": "{{GENDER:$1|Fandom helper}}",
+            "hydra_staff": "{{GENDER:$1|Gamepedia staff}}",
+            "imagecontrol": "{{GENDER:$1|Image controller}}",
+            "interface-admin": "{{GENDER:$1|Interface administrator}}",
+            "junioradmin": "{{GENDER:$1|Junior administrator}}",
+            "moderator": "{{GENDER:$1|Moderator}}",
+            "patroller": "{{GENDER:$1|Patroller}}",
+            "patrollers": "{{GENDER:$1|Patroller}}",
+            "rollback": "{{GENDER:$1|rollback}}",
+            "soap": "{{GENDER:$1|SOAP}}",
+            "staff": "{{GENDER:$1|Fandom staff}}",
+            "supmoderator": "{{GENDER:$1|Senior moderator}}",
+            "sysop": "{{GENDER:$1|Administrator}}",
+            "threadmoderator": "{{GENDER:$1|Discussions moderator}}",
+            "user": "{{GENDER:$1|User}}",
+            "vanguard": "{{GENDER:$1|Vanguard}}",
+            "voldev": "{{GENDER:$1|Volunteer Developer}}",
+            "widgeteditor": "{{GENDER:$1|Widget editor}}",
+            "wiki-manager": "{{GENDER:$1|Wiki manager}}",
+            "wiki_manager": "{{GENDER:$1|Wiki manager}}"
         },
         },
         "info": {
         "info": {
             "discord": "Discord:",
             "discord": "Discord:",
@@ -715,27 +715,27 @@
         "footer": "Wiki Account Verification",
         "footer": "Wiki Account Verification",
         "help_fandom": "https://community.fandom.com/wiki/Special:VerifyUser",
         "help_fandom": "https://community.fandom.com/wiki/Special:VerifyUser",
         "help_gamepedia": "https://help.gamepedia.com/Gamepedia_Help_Wiki:Discord_verification",
         "help_gamepedia": "https://help.gamepedia.com/Gamepedia_Help_Wiki:Discord_verification",
-        "help_guide": "Follow [this guide]($1) to add your Discord tag to your wiki profile:",
-        "help_subpage": "Please add your Discord tag ($1) to your Discord subpage on the wiki:",
+        "help_guide": "Follow [this guide]($1) to {{GENDER:$2|add}} your Discord tag to your wiki profile:",
+        "help_subpage": "Please {{GENDER:$2|add}} your Discord tag ($1) to your Discord subpage on the wiki:",
         "missing": "there are no verifications set up for this channel.",
         "missing": "there are no verifications set up for this channel.",
         "notice": "Notice:",
         "notice": "Notice:",
         "qualified": "Qualified for:",
         "qualified": "Qualified for:",
         "qualified_error": "Qualified for, but can't add:",
         "qualified_error": "Qualified for, but can't add:",
-        "user_blocked": "**The wiki user $1 is blocked!**",
-        "user_blocked_reply": "your linked wiki user **\"$1\" is blocked!**",
-        "user_disabled": "**The wiki user $1 is disabled!**",
-        "user_disabled_reply": "your linked wiki user **\"$1\" is disabled!**",
-        "user_failed": "Discord user $1 doesn't match the wiki user $2.",
-        "user_failed_reply": "your Discord tag doesn't match the wiki user \"$1\".",
-        "user_gblocked": "**The wiki user $1 is globally blocked!**",
-        "user_gblocked_reply": "your linked wiki user **\"$1\" is globally blocked!**",
-        "user_matches": "Discord user $1 matches the wiki user $2, but doesn't meet the requirements for any roles.",
-        "user_matches_reply": "your Discord tag matches the wiki user \"$1\", but you don't meet the requirements for any roles.",
+        "user_blocked": "**The wiki user $1 is {{GENDER:$2|blocked}}!**",
+        "user_blocked_reply": "your linked wiki user **\"$1\" is {{GENDER:$2|blocked}}!**",
+        "user_disabled": "**The wiki user $1 is {{GENDER:$2|disabled}}!**",
+        "user_disabled_reply": "your linked wiki user **\"$1\" is {{GENDER:$2|disabled}}!**",
+        "user_failed": "Discord user $1 doesn't {{GENDER:$3|match}} the wiki user $2.",
+        "user_failed_reply": "your Discord tag doesn't {{GENDER:$3|match}} the wiki user \"$1\".",
+        "user_gblocked": "**The wiki user $1 is globally {{GENDER:$2|blocked}}!**",
+        "user_gblocked_reply": "your linked wiki user **\"$1\" is globally {{GENDER:$2|blocked}}!**",
+        "user_matches": "Discord user $1 {{GENDER:$3|matches}} the wiki user $2, but doesn't {{GENDER:$3|meet}} the requirements for any roles.",
+        "user_matches_reply": "your Discord tag {{GENDER:$2|matches}} the wiki user \"$1\", but you don't {{GENDER:$2|meet}} the requirements for any roles.",
         "user_missing": "The wiki user \"$1\" doesn't exist.",
         "user_missing": "The wiki user \"$1\" doesn't exist.",
         "user_missing_reply": "your linked wiki user \"$1\" doesn't exist.",
         "user_missing_reply": "your linked wiki user \"$1\" doesn't exist.",
-        "user_renamed": "Their Discord nickname has been changed to their wiki username.",
-        "user_verified": "Discord user $1 has been successfully verified as wiki user $2.",
-        "user_verified_reply": "you have been successfully verified as wiki user \"$1\".",
+        "user_renamed": "Their Discord nickname has been {{GENDER:$1|changed}} to their wiki username.",
+        "user_verified": "Discord user $1 has been successfully {{GENDER:$3|verified}} as wiki user $2.",
+        "user_verified_reply": "you have been successfully {{GENDER:$2|verified}} as wiki user \"$1\".",
         "wiki": "Wiki user:"
         "wiki": "Wiki user:"
     },
     },
     "voice": {
     "voice": {

+ 28 - 2
util/i18n.js

@@ -74,7 +74,9 @@ class Lang {
 			args.forEach( (arg, i) => {
 			args.forEach( (arg, i) => {
 				text = text.replaceSave( new RegExp( `\\$${i + 1}`, 'g' ), arg );
 				text = text.replaceSave( new RegExp( `\\$${i + 1}`, 'g' ), arg );
 			} );
 			} );
-			text = text.replace( /{{\s*PLURAL:\s*[+-]?(\d+)\s*\|\s*([^\{\}]*?)\s*}}/g, (m, number, cases) => {
+			text = text.replace( /{{\s*GENDER:\s*([a-z]+)\s*\|\s*([^\{\}]*?)\s*}}/g, (m, type, cases) => {
+				return gender(type, cases.split(/\s*\|\s*/));
+			} ).replace( /{{\s*PLURAL:\s*[+-]?(\d+)\s*\|\s*([^\{\}]*?)\s*}}/g, (m, number, cases) => {
 				return plural(lang, parseInt(number, 10), cases.split(/\s*\|\s*/));
 				return plural(lang, parseInt(number, 10), cases.split(/\s*\|\s*/));
 			} );
 			} );
 		}
 		}
@@ -104,7 +106,9 @@ class Lang {
 //			args.forEach( (arg, i) => {
 //			args.forEach( (arg, i) => {
 //				text = text.replaceSave( new RegExp( `\\$${i + 1}`, 'g' ), arg );
 //				text = text.replaceSave( new RegExp( `\\$${i + 1}`, 'g' ), arg );
 //			} );
 //			} );
-//			text = text.replace( /{{\s*PLURAL:\s*[+-]?(\d+)\s*\|\s*([^\{\}]*?)\s*}}/g, (m, number, cases) => {
+//			text = text.replace( /{{\s*GENDER:\s*([a-z]+)\s*\|\s*([^\{\}]*?)\s*}}/g, (m, type, cases) => {
+//				return gender(type, cases.split(/\s*\|\s*/));
+//			} ).replace( /{{\s*PLURAL:\s*[+-]?(\d+)\s*\|\s*([^\{\}]*?)\s*}}/g, (m, number, cases) => {
 //				return plural(lang, parseInt(number, 10), cases.split(/\s*\|\s*/));
 //				return plural(lang, parseInt(number, 10), cases.split(/\s*\|\s*/));
 //			} );
 //			} );
 //		}
 //		}
@@ -184,4 +188,26 @@ function getArg(args, index) {
 	return ( args.length > index ? args[index] : args[args.length - 1] );
 	return ( args.length > index ? args[index] : args[args.length - 1] );
 }
 }
 
 
+/**
+ * Parse gender text.
+ * @param {String} gender - The gender.
+ * @param {String[]} args - The possible text.
+ * @returns {String}
+ */
+function gender(gender, args) {
+	var text = args[0];
+	switch ( gender ) {
+		case 'male':
+			if ( args.length > 0 ) text = args[0];
+			break;
+		case 'female':
+			if ( args.length > 1 ) text = args[1];
+			break;
+		case 'unknown':
+		default:
+			if ( args.length > 2 ) text = args[2];
+	}
+	return text;
+}
+
 module.exports = Lang;
 module.exports = Lang;