User:Polygnotus/Scripts/FavouriteTemplates.js

Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// Add Favorite Templates to WikiEditor 2010 toolbar
// Place this code in your common.js file

// Check if we're editing a page
if ( [ 'edit', 'submit' ].indexOf( mw.config.get( 'wgAction' ) ) !== -1 ) {
    // Add a hook handler
    mw.hook( 'wikiEditor.toolbarReady' ).add( function ( $textarea ) {
        
        // Function to get favorite templates from user preferences
        async function getFavoriteTemplates() {
            try {
                const apiUrl = mw.config.get('wgScriptPath') + '/api.php';
                
                const params = {
                    action: 'query',
                    meta: 'userinfo',
                    uiprop: 'options',
                    format: 'json'
                };
                
                const response = await $.get(apiUrl, params);
                
                if (response.query && response.query.userinfo && response.query.userinfo.options) {
                    const options = response.query.userinfo.options;
                    
                    // Get the favorite templates
                    const favoriteTemplates = options['templatedata-favorite-templates'];
                    
                    if (favoriteTemplates) {
                        console.log('Favorite Templates (Page IDs):', favoriteTemplates);
                        
                        // Parse as JSON array
                        let templateIds = [];
                        if (typeof favoriteTemplates === 'string') {
                            try {
                                templateIds = JSON.parse(favoriteTemplates);
                            } catch (e) {
                                console.log('Could not parse favorites as JSON');
                                return [];
                            }
                        } else {
                            templateIds = favoriteTemplates;
                        }
                        
                        console.log('Template IDs:', templateIds);
                        
                        // Convert IDs to template names
                        if (templateIds.length > 0) {
                            const templateNames = await getTemplateNames(templateIds);
                            console.log('Template Names:', templateNames);
                            return templateNames;
                        }
                        
                        return [];
                    } else {
                        console.log('No favorite templates found.');
                        return [];
                    }
                }
                
                return [];
                
            } catch (error) {
                console.error('Error retrieving favorite templates:', error);
                return [];
            }
        }

        // Function to convert Page IDs to template names
        async function getTemplateNames(pageIds) {
            try {
                const apiUrl = mw.config.get('wgScriptPath') + '/api.php';
                
                // Convert array to pipe-separated string for the API
                const pageIdsString = pageIds.join('|');
                
                const params = {
                    action: 'query',
                    pageids: pageIdsString,
                    format: 'json'
                };
                
                const response = await $.get(apiUrl, params);
                
                if (response.query && response.query.pages) {
                    const pages = response.query.pages;
                    const templateNames = [];
                    
                    console.log('\n=== Template Details ===');
                    
                    for (const pageId of pageIds) {
                        const page = pages[pageId];
                        if (page && page.title) {
                            console.log(`ID ${pageId}: ${page.title}`);
                            templateNames.push({
                                id: pageId,
                                title: page.title,
                                namespace: page.ns
                            });
                        } else {
                            console.log(`ID ${pageId}: Template not found`);
                            templateNames.push({
                                id: pageId,
                                title: 'Unknown',
                                namespace: null
                            });
                        }
                    }
                    
                    return templateNames;
                }
                
                return [];
                
            } catch (error) {
                console.error('Error retrieving template names:', error);
                return [];
            }
        }

        // Function to create a safe button ID from template title
        function createButtonId(title) {
            // Remove Template: prefix if present
            const cleanTitle = title.replace(/^Template:/, '');
            // Replace spaces and special characters with hyphens
            return cleanTitle.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase();
        }

        // Function to create template syntax
        function createTemplateSyntax(title) {
            // Remove Template: prefix if present
            const cleanTitle = title.replace(/^Template:/, '');
            return `{{${cleanTitle}}}`;
        }

        // Function to add favorite template buttons
        async function addFavoriteTemplateButtons() {
            const favoriteTemplates = await getFavoriteTemplates();
            
            if (favoriteTemplates && favoriteTemplates.length > 0) {
                // First, add the section
                $textarea.wikiEditor( 'addToToolbar', {
                    sections: {
                        'favorite-templates': {
                            type: 'toolbar',
                            label: 'Favorite Templates'
                        }
                    }
                } );
                
                // Create the tools object for the buttons
                const templateTools = {};
                
                // Add each favorite template as a tool
                for (const template of favoriteTemplates) {
                    const buttonId = createButtonId(template.title);
                    const templateSyntax = createTemplateSyntax(template.title);
                    const displayTitle = template.title.replace(/^Template:/, '');
                    
                    templateTools[buttonId] = {
                        type: 'element',
                        element: $('<button>')
                            .addClass('tool tool-button')
                            .text(displayTitle)
                            .css({
                                'padding': '4px 8px',
                                'margin': '2px',
                                'border': '1px solid #a2a9b1',
                                'border-radius': '2px',
                                'background': '#f8f9fa',
                                'cursor': 'pointer',
                                'font-size': '11px',
                                'font-family': 'sans-serif'
                            })
                            .hover(
                                function() { $(this).css('background', '#eaecf0'); },
                                function() { $(this).css('background', '#f8f9fa'); }
                            )
                            .click((function(syntax) {
                                return function(e) {
                                    e.preventDefault();
                                    // Get the textarea
                                    const textarea = $('#wpTextbox1')[0];
                                    if (textarea) {
                                        // Insert the template syntax at cursor position
                                        const start = textarea.selectionStart;
                                        const end = textarea.selectionEnd;
                                        const text = textarea.value;
                                        textarea.value = text.substring(0, start) + syntax + text.substring(end);
                                        // Move cursor to end of inserted text
                                        textarea.selectionStart = textarea.selectionEnd = start + syntax.length;
                                        textarea.focus();
                                    }
                                };
                            })(templateSyntax))
                    };
                }
                
                // Then add the group with all tools
                $textarea.wikiEditor( 'addToToolbar', {
                    section: 'favorite-templates',
                    groups: {
                        'favorites': {
                            tools: templateTools
                        }
                    }
                } );
                
                console.log(`Added ${favoriteTemplates.length} favorite template buttons to toolbar`);
            } else {
                console.log('No favorite templates to add to toolbar');
            }
        }

        // Execute the function to add buttons
        addFavoriteTemplateButtons();
        
    } );
}