Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: HTML lexer supports vue bind attributes #1094

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

PBK-B
Copy link

@PBK-B PBK-B commented Dec 12, 2024

Why am I submitting this PR

in Vue, there are v-bind-related attributes that can write simple syntax logic directly on the template syntax. This kind of code syntax exists in many traditional vue projects. I believe people will like that t('translate') written directly in v-bind can be recognized by i18next-parser.

vue sample code:

<template>
  <button :aria-label="t('b_a_l', 'button aria label')">
    button label
  </button>
  <button v-bind:aria-label="$t('button v-bind aria label')">
    button label form v-bind
  </button>
</template>

the solution I tried is to directly transform the existing html-lexer by adding vueBindAttr: Boolean option to support the acquisition of :attribute="t('translate')" and v-bind:attribute="t('translate')" syntax sugar in the html tag, and then parse the functions in it through javascript-lexer, and finally get the desired results. This scheme does not introduce additional dependencies but will make html-lexer dependent on javascript-lexer when the function is enabled.

usage example:

export default {
……
    // see below for more details
    lexers: {
        vue: [
            {
                lexer: 'JavascriptLexer',
                functions: ['t', '$t'], // Array of functions to match
                namespaceFunctions: ['useTranslation', 'withTranslation'],
            },
            {
                lexer: 'HTMLLexer',
                functions: ['t', '$t'],
                vueBindAttr: true,
            },
        ],
        ……
    }
……
}

finally: @karellm TBR; At the same time, thank you for providing such a cool tool to save us a lot of time. I wish you a good day. If there is anything that can help promote this PR merger, welcome to comment.

Does it fix an existing ticket?

#617

Checklist

  • only relevant code is changed (make a diff before you submit the PR)
  • tests are included and pass: yarn test (see details here)
  • documentation is changed or added

@PBK-B PBK-B force-pushed the feat_vue_bind_attr branch from 8b7b067 to b616178 Compare December 12, 2024 09:54
@karellm
Copy link
Member

karellm commented Dec 26, 2024

@PBK-B Thank you for the PR and kind words. Would you be open to create a separate vue lexer that extends the html-lexer? I'm a bit reluctant to add framework specific code to the html-lexer.

Also, I'm confused as to why we need to define both lexers in the config file. Is that necessary?

@PBK-B
Copy link
Author

PBK-B commented Dec 26, 2024

@karellm I seem to have seen that vue-lexer was deleted just now (although I can understand that it is not dependent on vue-template-compiler)
It is not impossible to add a new vue-lexer, but I would like to ask for your thoughts on implementation, because the current changes are only based on html-lexer to add some small features, which itself still has to go through html-lexer first. Scan with javascript-lexer. If I create a new vue-lexer, is it acceptable for me to directly copy a copy of html-lexer?

secondly, configure both javascript-lexer and html-lexer for vue because the vue template syntax code file contains both javascript code and html-like code syntax.
a complete .vue code file looks like this:

<template>
  <button :aria-label="t('b_a_l', 'button aria label')">
    button label
  </button>
  <button v-bind:aria-label="$t('button v-bind aria label')">
    button label form v-bind
  </button>
  <p>{{t("tips", "this is an update prompt")}}</p>
  <p>{{msg}}</p>
  <p>{{elText}}</p>
</template>

<script lang="ts" setup>
import { computed, ref } from "vue"
import { t } from '@/i18n'

const msg = t("msg_text", "check for version updates")
const elText = computed(() => {
    return getVerisonUpdate() ? t('new_version', "new version") : t("not_new_version", "no updates available")
})
</script>

@PBK-B
Copy link
Author

PBK-B commented Dec 26, 2024

In addition, I am worried that adding back the vue-lexer that was originally removed and implementing inconsistent functions will cause confusion when people upgrade the version.

@PBK-B
Copy link
Author

PBK-B commented Jan 4, 2025

@karellm I moved the code out separately and created a VueTemplateLexer (to avoid differentiation from the old VueLexer), calling HTMLLexer and JavascriptLexer in extract and supporting VueTemplate v-bind syntax, If you have any good suggestions, please contact me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants