{"action":"created","issue":{"url":"https://api.github.com/repos/timber/timber/issues/1465","repository_url":"https://api.github.com/repos/timber/timber","labels_url":"https://api.github.com/repos/timber/timber/issues/1465/labels{/name}","comments_url":"https://api.github.com/repos/timber/timber/issues/1465/comments","events_url":"https://api.github.com/repos/timber/timber/issues/1465/events","html_url":"https://github.com/timber/timber/issues/1465","id":238404548,"number":1465,"title":"Gulp task to generate POT file and .php clone files for WPML","user":{"login":"luism-s","id":15066801,"avatar_url":"https://avatars3.githubusercontent.com/u/15066801?v=4","gravatar_id":"","url":"https://api.github.com/users/luism-s","html_url":"https://github.com/luism-s","followers_url":"https://api.github.com/users/luism-s/followers","following_url":"https://api.github.com/users/luism-s/following{/other_user}","gists_url":"https://api.github.com/users/luism-s/gists{/gist_id}","starred_url":"https://api.github.com/users/luism-s/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/luism-s/subscriptions","organizations_url":"https://api.github.com/users/luism-s/orgs","repos_url":"https://api.github.com/users/luism-s/repos","events_url":"https://api.github.com/users/luism-s/events{/privacy}","received_events_url":"https://api.github.com/users/luism-s/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"gchtr","id":2084481,"avatar_url":"https://avatars2.githubusercontent.com/u/2084481?v=4","gravatar_id":"","url":"https://api.github.com/users/gchtr","html_url":"https://github.com/gchtr","followers_url":"https://api.github.com/users/gchtr/followers","following_url":"https://api.github.com/users/gchtr/following{/other_user}","gists_url":"https://api.github.com/users/gchtr/gists{/gist_id}","starred_url":"https://api.github.com/users/gchtr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gchtr/subscriptions","organizations_url":"https://api.github.com/users/gchtr/orgs","repos_url":"https://api.github.com/users/gchtr/repos","events_url":"https://api.github.com/users/gchtr/events{/privacy}","received_events_url":"https://api.github.com/users/gchtr/received_events","type":"User","site_admin":false},"assignees":[{"login":"gchtr","id":2084481,"avatar_url":"https://avatars2.githubusercontent.com/u/2084481?v=4","gravatar_id":"","url":"https://api.github.com/users/gchtr","html_url":"https://github.com/gchtr","followers_url":"https://api.github.com/users/gchtr/followers","following_url":"https://api.github.com/users/gchtr/following{/other_user}","gists_url":"https://api.github.com/users/gchtr/gists{/gist_id}","starred_url":"https://api.github.com/users/gchtr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gchtr/subscriptions","organizations_url":"https://api.github.com/users/gchtr/orgs","repos_url":"https://api.github.com/users/gchtr/repos","events_url":"https://api.github.com/users/gchtr/events{/privacy}","received_events_url":"https://api.github.com/users/gchtr/received_events","type":"User","site_admin":false}],"milestone":null,"comments":7,"created_at":"2017-06-25T20:37:05Z","updated_at":"2018-04-01T21:59:48Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"This isn't an issue, but more of a procedure suggestion. I don't know what would the best place for something like this  be, so I'll post this here.\r\n\r\nI was having an hard time adapting POEdit to scan .twig files, so I figured that I needed a different approach in order to register the strings from .twig files in WPML.\r\n\r\nSo I coded a gulp script with the following logic:\r\n- Iterates over all given .twig files\r\n- Search and Replace for gettext functions in .the twig files and wraps them around php tags\r\n- Outputs each file as .php\r\n- Send files to a  cache folder\r\n- Iterate over all .php files (cache included)\r\n- Generate .pot \r\n- ta  daaaa\r\n\r\n\r\nDependencies:\r\n````\r\nnpm install --save-dev del gulp gulp-if run-sequence gulp-rename gulp-replace gulp-wp-pot\r\n````\r\n\r\nCode (as if the script is in the theme's root):\r\n\r\n\r\n````\r\n\r\n/**\r\n * Gettext Scanner Script for Twig Projects\r\n * v1.0\r\n * \r\n * Developed by luism-s\r\n * https://github.com/luism-s\r\n */\r\n\r\n/**\r\n * Usage:\r\n * `gulp pot`\r\n *\r\n * Logic:\r\n *\r\n * - Iterates over all given .twig files\r\n * - Search and replace for gettext functions in Twig files and wraps them around PHP tags\r\n * - Outputs each file as .php into a cache folder\r\n * - Scan all .php files for gettext functions using 'gulp-wp-pot' (cache included)\r\n * - Generate .pot file\r\n */\r\n\r\n/**\r\n * Dependencies:\r\n *\r\n * `npm install --save-dev gulp gulp-wp-pot gulp-replace gulp-rename del gulp-if run-sequence`\r\n */\r\nvar gulp    = require('gulp');\r\nvar wpPot   = require('gulp-wp-pot');\r\nvar replace = require('gulp-replace');\r\nvar rename  = require('gulp-rename');\r\nvar del     = require('del');\r\nvar gulpif  = require('gulp-if');\r\nvar runSequence  = require('run-sequence');\r\n\r\n/**\r\n * Configuration Options\r\n * \r\n * All paths are as if this script is \r\n * located in the root of the theme and all the Twig\r\n * files are located under /views\r\n */\r\nvar config = {\r\n  \"text_domain\" : \"theme-test\",       // Replace with your domain\r\n  \"twig_files\"  : \"views/**/*.twig\",  // Twig Files\r\n  \"php_files\"   : \"**/*.php\",         // PHP Files\r\n  \"cacheFolder\" : \"views/cache\",      // Cache Folder\r\n  \"destFolder\"  : \"languages\",        // Folder where .pot file will be saved\r\n  \"keepCache\"   : true                // Delete cache files after script finishes\r\n};\r\n\r\n/**\r\n * Main Task\r\n */\r\ngulp.task('pot', function(callback) {\r\n  runSequence('compile-twigs', 'generate-pot', callback);\r\n});\r\n\r\n/**\r\n * Generate POT file from all .php files in the theme,\r\n * including cache folder.\r\n */\r\ngulp.task('generate-pot', function () {\r\n  return gulp.src(config.php_files)\r\n    .pipe(wpPot( {\r\n      domain: config.text_domain\r\n    } ))\r\n    .pipe(gulp.dest(config.dest_folder + '/' + config.text_domain + '.pot'))\r\n    .pipe(gulpif(!config.keep_cache, del.bind(null, [config.cache_folder], {force: true})));\r\n});\r\n\r\n/**\r\n * Fake Twig Gettext Compiler\r\n * \r\n * Searches and replaces all occurences of __('string', 'domain'), _e('string', 'domain') and so on,\r\n * with <?php __('string', 'domain'); ?> or <?php _e('string', 'domain'); ?> and saves the content\r\n * in a .php file with the same name in the cache folder.\r\n * \r\n * Functions supported:\r\n * \r\n * Simple: __(), _e(), translate()\r\n * Plural: _n()\r\n * Disambiguation: _x(), _ex(), _nx()\r\n * Noop: _n_loop(), _nx_noop()\r\n * \r\n * TODO:\r\n * - Support translate_nooped_plural() function\r\n * - Skip gettext calls insied Twig comments (ex. {# __('string', 'domain') #})\r\n */\r\ngulp.task('compile-twigs', function(){\r\n  del.bind(null, [config.cache_folder], {force: true})\r\n  \r\n  /**\r\n   * __\r\n   * _e\r\n   * _x\r\n   * _xn\r\n   * _ex\r\n   * _n_noop\r\n   * _nx_noop\r\n   * translate  -> Match __,  _e, _x and so on\r\n   * \\(         -> Match (\r\n   * \\s*?       -> Match empty space 0 or infinite times, as few times as possible (ungreedy)\r\n   * [\\'\\\"]     -> Match ' or \"\r\n   * .+?        -> Match any character, 1 to infinite times, as few times as possible (ungreedy)\r\n   * ,          -> Match ,\r\n   * .+?        -> Match any character, 1 to infinite times, as few times as possible (ungreedy)\r\n   * \\)         -> Match )\r\n   */\r\n  var gettext_regex = {\r\n    simple : /(__|_e|translate)\\(\\s*?[\\'\\\"].+?[\\'\\\"]\\s*?,\\s*?[\\'\\\"].+?[\\'\\\"]\\s*?\\)/g,\r\n    plural : /_n\\(\\s*?[\\'\\\"].*?[\\'\\\"]\\s*?,\\s*?[\\'\\\"].*?[\\'\\\"]\\s*?,\\s*?.+?\\s*?,\\s*?[\\'\\\"].+?[\\'\\\"]\\s*?\\)/g,\r\n    disambiguation : /(_x|_ex|_nx)\\(\\s*?[\\'\\\"].+?[\\'\\\"]\\s*?,\\s*?[\\'\\\"].+?[\\'\\\"]\\s*?,\\s*?[\\'\\\"].+?[\\'\\\"]\\s*?\\)/g,\r\n    noop : /(_n_noop|_nx_noop)\\((\\s*?[\\'\\\"].+?[\\'\\\"]\\s*?),(\\s*?[\\'\\\"]\\w+?[\\'\\\"]\\s*?,){0,1}\\s*?[\\'\\\"].+?[\\'\\\"]\\s*?\\)/g\r\n  };\r\n\r\n  gulp.src(config.twig_files)\r\n    .pipe(replace(gettext_regex.simple, function( match ){\r\n      return '<?php ' + match + '; ?>';\r\n    }))\r\n    .pipe(replace(gettext_regex.plural, function( match ){\r\n      return '<?php ' + match + '; ?>';\r\n    }))\r\n    .pipe(replace(gettext_regex.disambiguation, function( match ){\r\n      return '<?php ' + match + '; ?>';\r\n    }))\r\n    .pipe(replace(gettext_regex.noop, function( match ){\r\n      return '<?php ' + match + '; ?>';\r\n    }))\r\n    .pipe(rename(function( file_path ) {\r\n      file_path.extname = \".php\"\r\n    }))\r\n    .pipe(gulp.dest(config.cache_folder));\r\n});\r\n\r\n````\r\nHope this helps someone"},"comment":{"url":"https://api.github.com/repos/timber/timber/issues/comments/377819989","html_url":"https://github.com/timber/timber/issues/1465#issuecomment-377819989","issue_url":"https://api.github.com/repos/timber/timber/issues/1465","id":377819989,"user":{"login":"luism-s","id":15066801,"avatar_url":"https://avatars3.githubusercontent.com/u/15066801?v=4","gravatar_id":"","url":"https://api.github.com/users/luism-s","html_url":"https://github.com/luism-s","followers_url":"https://api.github.com/users/luism-s/followers","following_url":"https://api.github.com/users/luism-s/following{/other_user}","gists_url":"https://api.github.com/users/luism-s/gists{/gist_id}","starred_url":"https://api.github.com/users/luism-s/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/luism-s/subscriptions","organizations_url":"https://api.github.com/users/luism-s/orgs","repos_url":"https://api.github.com/users/luism-s/repos","events_url":"https://api.github.com/users/luism-s/events{/privacy}","received_events_url":"https://api.github.com/users/luism-s/received_events","type":"User","site_admin":false},"created_at":"2018-04-01T21:59:48Z","updated_at":"2018-04-01T21:59:48Z","author_association":"CONTRIBUTOR","body":"I'm back.\r\n\r\nFound a problem with some of the regex's, preventing the script from parsing domains with hyphen (‐).\r\n\r\nMy initial post has been updated, as well as the gist: https://gist.github.com/luism-s/ebca42b8b8d70e81f8917f675a784060"}}
{"actor":{"display_login":"luism-s"}}