@@ -27,6 +27,25 @@ public static function fromString($string, Translations $translations, array $op
2727 'v-bind: ' ,
2828 'v-on: ' ,
2929 ],
30+ // HTML Tags to parse
31+ 'tagNames ' => [
32+ 'translate ' ,
33+ ],
34+ // HTML tags to parse when attribute exists
35+ 'tagAttributes ' => [
36+ 'v-translate '
37+ ],
38+ // Comments
39+ 'commentAttributes ' => [
40+ 'translate-comment '
41+ ],
42+ 'contextAttributes ' => [
43+ 'translate-context '
44+ ],
45+ // Attribute with plural content
46+ 'pluralAttributes ' => [
47+ 'translate-plural '
48+ ]
3049 ];
3150
3251 // Ok, this is the weirdest hack, but let me explain:
@@ -67,6 +86,7 @@ public static function fromString($string, Translations $translations, array $op
6786 $ template ->getLineNo () - 1
6887 );
6988 }
89+
7090 }
7191
7292 /**
@@ -145,6 +165,60 @@ private static function getTemplateTranslations(
145165 // Build a JS string from template element content expressions
146166 $ fakeTemplateJs = self ::getTemplateFakeJs ($ dom );
147167 self ::getScriptTranslationsFromString ($ fakeTemplateJs , $ translations , $ options , $ lineOffset );
168+
169+ self ::getTagTranslations ($ options , $ dom , $ translations );
170+ }
171+
172+ /**
173+ * @param array $options
174+ * @param DOMElement $dom
175+ * @param Translations $translations
176+ */
177+ private static function getTagTranslations (array $ options , DOMElement $ dom , Translations $ translations )
178+ {
179+ $ children = $ dom ->childNodes ;
180+ for ($ i = 0 ; $ i < $ children ->length ; $ i ++) {
181+ $ node = $ children ->item ($ i );
182+
183+ if (!($ node instanceof DOMElement)) {
184+ continue ;
185+ }
186+ $ translatable = false ;
187+ if (\in_array ($ node ->tagName , $ options ['tagNames ' ])) {
188+ $ translatable = true ;
189+ }
190+ $ attrList = $ node ->attributes ;
191+ $ context = null ;
192+ $ plural = "" ;
193+ $ comment = null ;
194+ for ($ j = 0 ; $ j < $ attrList ->length ; $ j ++) {
195+ /** @var DOMAttr $domAttr */
196+ $ domAttr = $ attrList ->item ($ j );
197+ // Check if this is a dynamic vue attribute
198+ if (\in_array ($ domAttr ->name , $ options ['tagAttributes ' ])) {
199+ $ translatable = true ;
200+ }
201+ if (\in_array ($ domAttr ->name , $ options ['contextAttributes ' ])) {
202+ $ context = $ domAttr ->value ;
203+ }
204+ if (\in_array ($ domAttr ->name , $ options ['pluralAttributes ' ])) {
205+ $ plural = $ domAttr ->value ;
206+ }
207+ if (\in_array ($ domAttr ->name , $ options ['commentAttributes ' ])) {
208+ $ comment = $ domAttr ->value ;
209+ }
210+ }
211+ if ($ translatable ) {
212+ $ translation = $ translations ->insert ($ context , \trim ($ node ->textContent ), $ plural );
213+ $ translation ->addReference ($ options ['file ' ], $ node ->getLineNo ());
214+ if ($ comment ) {
215+ $ translation ->addExtractedComment ($ comment );
216+ }
217+ }
218+ if ($ node ->hasChildNodes ()) {
219+ self ::getTagTranslations ($ options , $ node , $ translations );
220+ }
221+ }
148222 }
149223
150224 /**
@@ -197,7 +271,6 @@ private static function getVueAttributeExpressions(
197271 if (!($ node instanceof DOMElement)) {
198272 continue ;
199273 }
200-
201274 $ attrList = $ node ->attributes ;
202275
203276 for ($ j = 0 ; $ j < $ attrList ->length ; $ j ++) {
0 commit comments