Make plural with nuxt/i18n using as component - javascript

I am using nuxt/i18n plugin for localize my app.
My translation json file like below,
{
"key": "a car | {count} cars"
}
I now if i wrote as this, i could
{{ $tc('path.to.key',2,{count: 2}) }}
But how can i use this tricky while I am using this translation as below.
<i18n path="path.to.key">
<template #count>
<!-- some html code -->
</template>
</i18n>
I am using this way because i need to use html code for styling to {count} variable.
How can i singular or plural this translation?
Is there any property for i18n component to use this?

Related

What's the best way to pass markdown to an Astro component as a prop

What I'm trying to do
A simple way to render the content of a markdown file when it's passed as a string to another component using .compiledContent (or even using .rawContnent)? Or even a better way than this as obviously usually in Astro we can use the <Content /> Component, but from my knowledge, I can't pass a component or this functionality to another component without using a <slot /> in the parent component.
I have some JS for the parent component and using a <slot/> instead of passing the props to the component would change things, so hopefully looking for a solution with using this.
My setup
Data stored in /src/data/experience as markdown files with a year and a description formatted as markdown in the content section of each file
A component called Tabs.astro which takes props of headings and contents which are both lists of strings
A page /src/pages/experience.astro with the Tabs component in it which is displaying this data
I take the below code to get the data from the markdown files and pass the years and descriptions to the Tab component.
experience.astro
---
import Tabs from "../components/Tabs.astro";
const jobs = await Astro.glob("../data/experience/*.md");
const years = jobs.map((job) => job.frontmatter.year);
const descriptions = jobs.map((job) => job.compiledContent);
---
<!-- My component taking the data to be rendered -->
<Tabs headings={years} contents={descriptions} />
Tabs.astro
And the component renders the info like so
<!-- Tabs -->
<div class="tabs">
<ul class="tabs-header">
{
headings.map((heading) => (
<li>{heading}</li>
))
}
</ul>
<ul class="tabs-content">
{contents.map((content) => <li class="tab">{content}</li>)}
</ul>
</div>
My current solution
At the moment using .compiledContent gets me the correct HTML, however it is all in a string so the HTML doesn't actually render.
What I'm looking for
Is there a native way in Astro to pass markdown as a prop to a component?
If not is there a manual and recommended way in Astro to convert a markdown string and sanitise it to protect against XSS attacks? (if this is a risk in Astro when rendered statically?)
If not what are your most recommended ways to render markdown and sanitise it in JS?
Thanks so much for your time and help! I'm loving using Astro
p.s Also happy to concede and just use a <slot/> in my component if needed... ;)
Astro has a set:html directive you can use in combination with a Fragment like this
<Fragment set:html={post.compiledContent()}/>
After a bit of struggling with this myself, the current solution from the Astro docs for a single file without looping is the following.
Import your file with {Content as YourAliasName} from '../yourPath/yourFileName.md'
Then just use it as a tag <YourAliasName />
Example from the docs for reference:
---
import {Content as PromoBanner} from '../components/promoBanner.md';
---
<PromoBanner />
https://docs.astro.build/en/guides/markdown-content/#the-content-component

How to put html code inside react18next json translation file?

I have blog page on multiple languages and I use react-i18next library for translation.
I have one component called BlogPostPage where I show each post when it's opened, inside the component there is part for showing blog text like this:
import { useTranslation } from "react-i18next";
const [t] = useTranslation(["translation1", "overview"]);
..........
<Typography mb={2} component="p" variant="subtitle1">
{t(`text${state.id}1`)}
</Typography>
and my json translation file looks like this
{
"text51":"<h4>Welcome to our application</h4>",
}
So I want to put html code inside translation text since different post has different html code it really needs to be in json file and not in the component... is there any way that can be done?
Output of my code is:
<h4>Welcome to our application</h4>
Use the Trans component: https://react.i18next.com/latest/trans-component
<Trans i18nKey="text51">
<h4>Welcome to our application</h4>
</Trans>
With <0> instead of <h4>
"text51": "<0>Welcome to our application</0>"
Your issue is that react will try to escape any html it find in strings like this. If you absolutely need to do this you can use the following method:
<div dangerouslySetInnerHTML={{__html: t(`text${state.id}1`)}} />
Beware that there is a reason that react calls this prop dangerouslySetInnerHTML, and doing this is very much an anti-pattern.

VueJs Conditional handlebars

I'm trying to use VueJs conditional rendering using handlebars in vueJs 2.0 as per their documentation but eslint is coming back with and error:
- avoid using JavaScript keyword as property name: "if" in expression {{#if ok}}
- avoid using JavaScript keyword as property name: "if" in expression {{/if}}
VueJs does not seem to be rendering it.
<!-- Handlebars template -->
{{#if ok}}
<h1>Yes</h1>
{{/if}}
If you are trying to use Vue.js syntax, the documentation outlines just a few lines down what's done for Vue.js. You would use the v-if directive.
<h1 v-if="ok">Yes</h1>
If like you mentioned, you're wanting to use Handlebars alongside Vue.js, note that both of them use the same {{ curly braces in templates. You may need to change Vue's use of the curly braces like so...
Vue.config.delimiters = ['<%', '%>'];
Either:
Using v-if to conditionally render
<h1 v-if="isVisible"> Yes </h1>
or using v-show to add a hidden attribute to that element style
<h1 v-show="isVisible"> Yes </h1>
either can be used but be careful with v-if since the element won't be in the DOM if the condition is not met.
I believe that is simply to document that the conditional does not go on a parent tag, but rather it is placed directly on the node that you want to conditionally display.
In other words its simply a comparison not part of Vue.js markup, but rather part of Handlebars.
Vue conditional rendering syntax
<h1 v-if="ok">Yes</h1>
<h1 v-show="ok">Yes</h1>
Details in original docs.
https://v2.vuejs.org/v2/guide/conditional.html#v-if-vs-v-show
Firstly, You should look at the vue documentation .https://v2.vuejs.org/v2/guide/conditional.html#v-if-vs-v-showjs and by the way, you can use "v-if" and "v-show"attributes, in flowing related to
examples.
<h1 v-if='isShow'>Test</h1>
<h1 v-show='isShow'>Test</h1>
For anyone coming here from a search trying to conditionally render inside {{ }} braces, you could always use a computed property:
import { computed } from 'vue';
<script setup>
const submitButtonText = computed(() => {
return props.formObject ? 'Save' : 'Create';
});
</script>
<template>
<form>
<button type="submit">
{{ submitButtonText }}
</button>
</form>
</template>
v-if and v-if-else work perfect for large elements, but this is great for simple one-line conditional text.

Render HTML Tag Vue.js

I am trying to add a render a template using the push mutation method. I want to push a section component, but instead of the template content I get the raw output of <vsection></vsection'. Can anyone help me render the actual template content and not the raw tags? I included a jsbin below.
http://jsbin.com/wurofatuve/1/edit?html,js,output
You're thinking about this a little oddly. What I think you'd be better off doing is putting a v-for on a <vsection> component.
<vsection v-for="section in sections">
{{ section.content }}
</vsection>
This way, when you push content to sections it'll out put another one. You'll also have to adjust your section component so you can use the content.
<template id="section-template">
<div class="section">
<slot></slot>
</div>
</template>
Here it is working like I think you want: http://jsbin.com/suhadidobe/1/edit?html,js,output

Emoticons displayed as raw HTML code

I am using the mattimo:emoticons package in Meteor (https://atmospherejs.com/mattimo/emoticons) to display emoticons. I am using this simple template to test it:
<template name="test">
{{parseEmoticons ":-)"}}
</template>
which is displayed through the route "/test" like so:
Router.route('/test/', function () {
this.render("test");
});
This should display a simple smiley, but instead I get the raw HTML in the browser:
<img class="meteoremoticon" src="/packages/mattimo_emoticons/assets/images/emoticons/caritas_07.png">
How do I get the browser to render the HTML instead of just displaying the unprocessed HTML?
From Meteor documentation:
{{{content}}} - Triple-braced template tags are used to insert raw HTML. Be careful with these! It's your job to make sure the HTML is safe, either by generating it yourself or sanitizing it if it came from a user input.
So, try to use triple braces
<template name="test">
{{{ parseEmoticons ":-)" }}}
</template>

Categories

Resources