Choose tagName group block Gutenberg - html

I'm learning to use and develop some custom blocks in gutenberg.
I was wondering and trying to add my custom section tag block, but then i looked up to the group core block code.
<SelectControl
label={ __( 'HTML element' ) }
options={ [
{ label: __( 'Default (<div>)' ), value: 'div' },
{ label: '<header>', value: 'header' },
{ label: '<main>', value: 'main' },
{ label: '<section>', value: 'section' },
{ label: '<article>', value: 'article' },
{ label: '<aside>', value: 'aside' },
{ label: '<footer>', value: 'footer' },
] }
value={ TagName }
onChange={ ( value ) =>
setAttributes( { tagName: value } )
}
/>
Am i right thinking this means ther should be a select that allow you to choose the tag?
Also i tried modifing the code in the editor from
<!-- wp:group {className":"is-style-twentytwentyone-border"} -->
<div class="wp-block-group is-style-twentytwentyone-border"><div class="wp-block-group__inner-container"></div></div>
<!-- /wp:group -->
to
<!-- wp:group {"tagName":"section","className":"is-style-twentytwentyone-border"} -->
<section class="wp-block-group is-style-twentytwentyone-border"><div class="wp-block-group__inner-container"></div></section>
<!-- /wp:group -->
And it works! It doesn't break the block and it's rendered correctly on the frontpage with a section tag.
Am i missing something? Is there a way to make the selection tag appear in the editor? I'd like my user to be able to choose the tag without editing the code manually

Actually i was looking at the testing version of gutenberg, and i works as expected by the code, not the one shipped with wordpress.
Still there are various way to add a filter to the group, letting the user choose the tag, but it's something that involves some coding. Better build a new block from scratch.

Related

React Dynamic Template with Form Control - Auto Correcting HTML Tag

hopefully someone there who can guide me on rite way. trying to create dynamic html with dynamic control. here is my example.
const [oHtml, setoHtml] = React.useState([
{
type: "html",
control: "<table><tr><td>",
},
{
type: "control",
control: (
<CustomInput
labelText="Password"
id="password"
formControlProps={{
fullWidth: true,
}}
inputProps={{
type: "password",
autoComplete: "off",
}}
/>
),
},
{
type: "html",
control: "</td></tr></table>",
},
]);
and here how i am rendering.
return (
<div>
{Object.keys(oHtml).map(function (keyName, keyIndex) {
if (oHtml[keyName].type === "html") {
console.log(oHtml[keyName].control);
return ReactHtmlParser(oHtml[keyName].control);
} else {
return oHtml[keyName].control;
}
})}
</div>
);
issue is when React run <table><tr><td> its auto fixing tag and making it <table><tr><td></td></tr></table>
what i want to control inside td.
is there any way i can disable react to add missing tags itself?
The thing is that ReactHtmlParser can't be used to parse partial html.
You can try
return ReactHtmlParser(
oHtml.map(v => v.control).join("")
)
Btw, your oHtml is an array, so no need for Object.keys.

Anchor Tag in Next.js

I'm tryin got use an anchor tag in Next.js
I don't get any console errors when I set it up and click the link, but the page does not jump to the id tag.
This issue on github suggests that people need to figure out a lot of custom code to use anchors. That can't be right.
I have:
const links = [
{ label: 'Solutions', href: '#solutions', id: 'solutions' },
]
<NavLink.Desktop key={index} href={link.href} id={link.id}>
{link.label}
</NavLink.Desktop>
I get no errors, but the page does not jump to the label that has an id of 'solutions'.
Does anyone know how to solve this, or where to go for ideas on how - it can't be intented that complex custom code is required to use an anchor tag?
Chakra UI has a Link component
<Link href='https://chakra-ui.com' isExternal>
Chakra Design system <ExternalLinkIcon mx='2px' />
</Link>
If you use the regular anchor tags
<Link href="#anchor_one">Menu one</Link>
<Link href="#anchor_two">Menu two</Link>
Then you can add the id for the anchors to the sections you want to navigate into
<div id="anchor_one" />
<div id="anchor_two" />
This can be either pages or components.
I hope this helped a little bit.
As said by #juliomalves in the comments, you have to specify the id attribute on the element in which you wish to navigate to. Not on the anchor tag.
The id for the anchor should be set on the element you want to link to, not on the link itself.
The below code works for me in Next.js -
export default function Home() {
return (
<div>
Click
<section
style={{ marginTop: "1000px", marginBottom: "1000px" }}
id="section"
>
<h1>Test</h1>
</section>
</div>
);
}
Your code should look like this -
const links = [{ label: 'Solutions', href: '#solutions', id: 'solutions' }]
<NavLink.Desktop
key={index}
href={link.href}
// id={link.id} - This is wrong, as you're referring to the same element
>
{link.label}
</NavLink.Desktop>
// Rather set the id attribute in a separate div/section element
<div id={link.id}>
<h2>Solutions</h2>
</div>
maybe try
const links = [
{ label: 'Solutions', href: '#solutions', id: 'solutions' },
]
<NavLink.Desktop key={index} href={links[0].href} id={links[0].id}>
{link.label}
</NavLink.Desktop>
since you only have 1 element in the links array, if you have multiple just map through the array
It is possible to scroll to anchor programatically using Router.push:
import { useRouter } from 'next/router'
const Foo = () => {
const { push } = useRouter()
const handleClick = () => {
push("#blah")
}
return (
<div>
<button onClick={handleClick}>Scroll</button>
<div>Foo</div>
<div>Bar</div>
<div id="blah">Blah</div>
</div>
)
}
Next.js recognises that you are passing something that is not a link to a new page and will concat it (in the example #blah) to the end of the URL.
Have a read about Link from next/link its a built in feature.
https://nextjs.org/docs/api-reference/next/link
https://github.com/vercel/next.js/blob/canary/examples/hello-world/pages/index.js#L7

Markdowned content not reflected in my html template (<em><strong>)

In my Django project, I am using markdownify to convert my markdown to HTML.
I have a problem while rendering the HTML content to my template.
some tags like <em>, <strong> are not getting reflected.
I have tried using the safe filter as suggested in this stackoverflow post but I find no changes!
Is there any other filter I can use or any method to render correctly
in settings.py
MARKDOWNIFY = {
"default": {
"STRIP": True,
"BLEACH": True,
"MARKDOWNIFY_LINKIFY_TEXT": True,
"WHITELIST_TAGS": [
'a',
'abbr',
'acronym',
'b',
'blockquote',
'em',
'i',
'li',
'ol',
'p',
'strong',
'ul'
],
"WHITELIST_ATTRS": [
'href',
'src',
'alt',
],
"WHITELIST_STYLES": [
'color',
'font-weight',
],
"LINKIFY_TEXT": {
"PARSE_URLS": True,
"PARSE_EMAIL": True,
"CALLBACKS": [],
"SKIP_TAGS": ['pre', 'code',],
},
"WHITELIST_PROTOCOLS": [
'http',
'https',
],
"MARKDOWN_EXTENSIONS": [
'markdown.extensions.fenced_code',
'markdown.extensions.extra',
]
},
}
in my template:
<div class="col-8">
{{ entry|markdownify|safe }}
</div>
the content:
#This is the H1 tag for Heading
but these are working
- paragraph
- all the headers
- list tag
things not getting converted
- *Italics not working*
- **And also bold text**
In my template,this is what i get
This is the H1 tag for Heading
but these are working
paragraph
all the headers
list tag
things not getting converted
<em>Italics not working</em>
<strong>And also bold text</strong>
Images for reference:
content to be markdowned
final outcome that I got

VueJS - calling multiple image src as custom props

I have a small set of icons i want to call as a custom image prop depending on what type of item the component is. Code looks like this:
Vue.component('otherArticles', {
template: `
<!-- Component -->
<li>
<img :src="icon.text && icon.video" alt="icon">
<a :href="url">{{ Title }}</a>
</li>
`,
props: {
title: String,
url: String,
icon: [
{
text: "/resources/img/icons/text-icon.svg",
video: "/resources/img/icons/video-icon.svg"
}
]
}
});
Ideally in my html I would like to call them like this:
<!--Component with text icon-->
<other-articles
icon='text' <!-- how i'd like to call the text icon as img src -->
url="."
title="Text article title">
</other-articles>
<!--Component with video icon-->
<other-articles
icon='video' <!-- how i'd like to call the video icon as img src -->
url="."
title="Video article title">
</other-articles>
The img src binding is incorrect I know, i'm using it as an example of how i'm thinking it should be done, but I'm looking for any and all recommendations on how to do this correctly so I can call it the html as the example shows.
I only have these two icons and the src location for each may change but i would like to call it the same way even if i have to update the src location for either one in the future, keeping the html calls the same or similar. Any help would be appreciated. Thanks
First start by declaring your icon list as the following in your data function:
data() {
return {
iconList: {
text: '/resources/text.png',
video: '/resource/video.png',
}
};
}
Make sure to remove the list and rename the object, as you cannot have a prop and an entry in data with the same name. Then add your definition for icon to your props section as the following:
props: {
icon: {
type: String,
required: true,
},
},
This tells Vue to typecheck the prop as a string, and warn when it's not present or not a string.
Now you need to update your template function to use this new prop as an key to lookup the related icon:
template: `
<img :src="iconList[icon]"/>
`,
Now you can use your component as <comp icon="video"/>

Angular bootstrap HTML processing of tab dynamic content

I'm using Angular Bootstrap tabs. I'd like to use them with their content loaded from an Angular Model. However, all HTML in the content loaded fromt eh model is ignored. i.e. if I have
$scope.tabs = [
{ title:'Dynamic Title 1', content:"<b>Dynamic</b> content 1" },
{ title:'Dynamic Title 2', content:'Dynamic content 2', disabled: true }
];
The first tab's content is "Dynamic content 1", not "Dynamic content 1" with "Dynamic" in bold. If the content as statically supplied in the html file, it would show correctly.
Plunker to demonstrate the problem
Anyone know how I can force the html to be parsed properly?
Thank you,
Greg
Based in the comments, you can create a function called:
scope.trustHtml = function(content){
return $sce.trustAsHtml( content );
}
and then change your HTML to be like:
<tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disabled="tab.disabled">
<span ng-bind-html="trustHtml(tab.content)"></span>
</tab>