# Automate Localization Key Extraction in your ABP Project

> No need to spend hours adding localization keys to your project. Automate Localization Key Extraction in Your ABP Project | Ekolsoft

**URL:** https://ekolsoft.com/en/b/automate-localization-key-extraction-in-your-abp-project

---

.code-block {
          position: relative;
          margin-bottom: 20px;
      }
      .copy-btn {
          position: absolute;
          top: 10px;
          right: 10px;
          background-color: #f6f8fa;
          border: 1px solid #e1e4e8;
          border-radius: 3px;
          padding: 5px 10px;
          cursor: pointer;
          transition: background-color 0.2s;
      }
      .copy-btn:hover {
          background-color: #e1e4e8;
      }
      pre[class*="language-"] {
          margin-top: 0;
          margin-bottom: 0;
          border-radius: 3px;
          padding: 40px 15px 15px;
      }
      .copied {
          background-color: #28a745;
          color: white;
      }
  
    Managing localization keys manually in a growing ABP project can be tedious and error-prone. This guide walks you through automating the extraction and management of localization keys using a Node.js script and a configuration file.



    ## Step 1: Create the Configuration File


    At the root of your project, create a file named localization-config.json with the following content:



    
        Copy
        {
  "patterns": [
    {
      "type": "csharp",
      "filePattern": "**/*.cs",
      "excludePatterns": [ "**/bin/**", "**/obj/**", "**/node_modules/**" ],
      "regexPatterns": [
        "L\\(\"([^\"]+)\"\\)",
        "L\\('([^']+)'\\)"
      ]
    },
    {
      "type": "razorView",
      "filePattern": "**/*.cshtml",
      "excludePatterns": [ "**/bin/**", "**/obj/**", "**/node_modules/**" ],
      "regexPatterns": [
        "@L\\(\"([^\"]+)\"\\)",
        "@L\\('([^']+)'\\)"
      ]
    }
  ],
  "localization": {
    "sourceFilesPath": "./src/YourProjectName.Core/Localization/YourProjectName/",
    "defaultFile": "YourProjectName.xml",
    "cultures": [
      {
        "code": "en",
        "file": "YourProjectName.xml"
      },
      {
        "code": "tr",
        "file": "YourProjectName-tr.xml"
      }
    ]
  }
}




    Replace YourProjectName with the actual name of your project or replace the whole path depending on your project's structure. The cultures array specifies the different localization files for each language. You can add more cultures by extending this array with additional objects, each containing a code and corresponding file.



    ## Step 2: Install Required Node.js Modules


    Ensure you have Node.js installed on your system. Then, install the necessary modules by running the following command in your project's root directory:



    
        Copy
        npm install glob xml2js




    This command installs the glob module for file pattern matching and the xml2js module for parsing and building XML files.



    ## Step 3: Add the Localization Script


    Place the provided Node.js script (e.g., extract-localization.js) at the root of your project:



    
        Copy
        const fs = require('fs');
const path = require('path');
const { glob } = require('glob');
const xml2js = require('xml2js');

// Load configuration
const configPath = process.env.CONFIG_PATH || './localization-config.json';
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));

// Initialize sets to store found localization keys
const foundKeys = new Set();

async function findFiles(pattern, excludePatterns) {
    try {
        const files = await glob(pattern, { ignore: excludePatterns });
        return files;
    } catch (err) {
        throw err;
    }
}

function extractLocalizationKeys(filePath, regexPatterns) {
    const content = fs.readFileSync(filePath, 'utf8');
    const keys = [];

    for (const pattern of regexPatterns) {
        const regex = new RegExp(pattern, 'g');
        let match;

        while ((match = regex.exec(content)) !== null) {
            keys.push(match[1]);
        }
    }

    return keys;
}

async function main() {
    try {
        // Process each pattern defined in config
        for (const patternConfig of config.patterns) {
            console.log(`Processing ${patternConfig.type} files...`);

            // Find all files matching the pattern
            const files = await findFiles(patternConfig.filePattern, patternConfig.excludePatterns);
            console.log(`Found ${files.length} ${patternConfig.type} files`);

            // Process each file
            for (const file of files) {
                const keys = extractLocalizationKeys(file, patternConfig.regexPatterns);

                for (const key of keys) {
                    foundKeys.add(key);
                }

                if (keys.length > 0) {
                    console.log(`Found ${keys.length} localization keys in ${file}`);
                }
            }
        }

        console.log(`Total unique localization keys found: ${foundKeys.size}`);
    } catch (error) {
        console.error(`Error: ${error.message}`);
        console.error(error.stack);
        process.exit(1);
    }
}

// Execute main function
main();




    ## Step 4: Run the Script


    Execute the script using the following command:



    
        Copy
        node extract-localization.js




    The script will process your source files, extract localization keys, and update the XML files specified in your configuration.


    The script will process your source files, extract localization keys, and update the XML files specified in your configuration.

## Bonus: Github Actions
Integrating this script into github actions is also a cool idea. You can automatically create a pr with new localization items after each push to your master branch. Not only that you can also translate your xml files using any translator or ai on the market.


    
    
    
    
        document.querySelectorAll('.copy-btn').forEach(btn => {
            btn.addEventListener('click', function() {
                const targetId = this.getAttribute('data-target');
                const codeBlock = document.getElementById(targetId);
                
                // Create a temporary textarea to copy text
                const tempTextArea = document.createElement('textarea');
                tempTextArea.value = codeBlock.textContent;
                document.body.appendChild(tempTextArea);
                
                // Select and copy the text
                tempTextArea.select();
                document.execCommand('copy');
                
                // Remove the temporary textarea
                document.body.removeChild(tempTextArea);
                
                // Provide visual feedback
                this.textContent = 'Copied!';
                this.classList.add('copied');
                
                // Revert back after 2 seconds
                setTimeout(() => {
                    this.textContent = 'Copy';
                    this.classList.remove('copied');
                }, 2000);
            });
        });