I can't seem to grasp or find out why you should use HTML templates with web components when you can simply define the HTML inside the web component (shadowRoot.innerHTML).
What is the benefit of creating a template and cloning it inside the web component? I can see there being a reason if two web components share the same HTML but beside that I have no idea.
Is there something fundamentally important that I'm missing?
Yes, too many blogs do document.createElement("template") where an .innerHTML will do the same ... and with less code ... and faster.
Note, Templates are not tied to the Custom Elements API or shadowDOM.
Each of the 3 Web Components technologies can be used without the other.
Templates
Templates are great when you want to store re-usable content in the HTML Document, because it does not get parsed.
In the old days we would use a <div hidden> and pray its contents did not affect the rest of the page.
Just like the old days you can read the Template.innerHTML and do whatever you want with the String value.
More modern approach is to clone the Template, just be aware that .content property is required, and you get a Document-Fragment value in return.
<template id="MY-TEMPLATE">
<article>
...
</article>
</template>
document.getElementById("MY-TEMPLATE").content.cloneNode(true)
Templates & shadowDOM
When you have Custom Elements with shadowDOM, Templates are great to define that shadowDOM content.
Why so many developers want to do HTML-in-JS and CSS-in-JS I don't understand.
If you have an HTML document, store the content there, way easier to edit.
<template id="MY-ELEMENT">
<style>
/* style shadowDOM here */
</style>
<slot></slot>
</template>
All your MY-ELEMENT then needs to do is:
super() // or this when done in the connectedCallback
.attachShadow({mode: 'open'})
.append(document.getElementById(this.nodeName).content.cloneNode(true))
Performance
an innerHTML String with HTML content will get parsed for every usage.
A template is parsed once, so does save on CPU cycles, when you use the same template many many multiple times
Usage
My personal preference is to keep as much HTML (and CSS) inside <TEMPLATEs> in HTML as possible. Only when I want my components not to be configurable I use static HTML in JS, with .innerHTML, not .createElement("template") for code brevity over (minor) performance gain
Only in SDWCs (Self Destructing Web Components) that need to load/execute ASAP I contain everything inside the Component:
customElements.define('my-head',class extends HTMLElement{
connectedCallback(){
// generate <HEAD> content, <SCRIPTS> and <STYLE> CSS-in-JS here
this.remove();
}
});
What is the benefit of creating a template and cloning it inside the web component?
Speed. Parsing a string and generate internal html objects takes some extra time compared to just cloning nodes. If the web component is used in many places and each will parse string and convert it to html objects. Compare that with just parsing once.
tutorial about web components
Related
We're using the WordPress REST API to power a static site. The site is "headless" in the sense that we don't use a WordPress theme; we rely on the content being exposed via the REST API.
Some of the default Gutenberg blocks - the Buttons block for instance - have styles with hashed class names associated with them that don't seem to be exposed in the API. This would be kind of ok if the class names were predictable but, since they aren't, we have no way of providing the styles on our end.
If we do render the blocks in a theme, the styles are rendered in the footer
Here's an example of the style block for the default Buttons block looks like in a WordPress theme
The Rest API endpoint exposes the markup in content.rendered (including the classnames) but no styles
Is this expected behavior for using Gutenberg and the WordPress REST API? If so, is the correct solution to expose the styles via a custom field (for lack of a better term) on the API?
The unique id (hash) in the classnames are randomly generated each time the blocks are parsed, even when directly calling the REST API. Unfortunately, the inline style attributes like .alignleft are absent from the content markup in the REST API. Being a REST API, it makes sense that style specific information isn't included; this keeps data and presentation of the data separate. It also prevents bloating the API by including style-specific information that would be rarely used outside of WordPress theme.
In your scenario, if you wish to style the resulting HTML content without worrying about the unique id, I'd suggest using css partial selectors, eg:
div[class*="wp-container-"] .wp-block-button{
...
}
Alternatively, as you mentioned, its possbile to extend the REST API to include the styles. While I haven't built a working example of this for styles, when blocks where introduced I ended up extended the REST API to include extra meta data. I'd suggest looking at render_block_data to handle adding in the styles into the content.
Eg. For the buttons block, the serialized content stored in the database as:
<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link">Hello</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->
By using parse_blocks() you can obtain all the block properties into an array and get style information that way. I think this approach is do-able if you just add the generated classnames and not the inline styles. I am keen to know if you find a better way...
My supervisor just handed me a pile of JSON files from a freelancer which we are going to use to make multiple (similar) websites. Lucky me, I'll get to be the one updating the content and css for the different versions.
This is my first time working with JSON, so while I can't be sure that this is a poorly designed template, the fact that the css is very messy (in order to change the color of buttons throughout the site from yellow to orange, at least 15 different classes need to be adjusted, which seems to me to defeat the whole purpose of css...) doesn't give me hope.
I've brute-forced my way through the first two different sites, but since it looks like we'll be doing a lot more of them, I'm looking for ways to streamline the process (in particular making sure to change the content in all the places the content needs changing, which is a lot of files, with different content for different versions).
I'm personally old-school enough to like awk (well, that, and it's what I'm most used to programming in), so my backup plan is to just set up an awk/batch script or two which will take in a "these are the bits of info that go in these specific places" file and update all the relevant files. However, I'm sure there's a better way to do this, which is why I'm turning to y'all.
Is there anything that already exists for streamlining processes like these? Or a coding system/language that's well-suited to this project? A GUI which I can connect to bits of text that need changing?
Ideally, I'd like to set up something that even a monkey (or a non-caffeinated me) could use as often as needed. I'm already going to have to dive into the source code to clean it up (because, gasp, we might need to be able to have more than 5 people on the "our team" page, for example - without bad css/html workarounds), so making other tweaks that'll help with the content update process can happen en route.
I have recently used underscore to render templates from JSON. this is a front end tool, but you could automate it with some backend tools (a simple cURL or file_get_content in php will do).
Here is a link to a tutorial
your template will be a JavaScript template in your html file:
<div id="rendered"></div>
<script type="text/template" class="template">
<%- rc.listTitle %>
</script>
and in your JavaScript code you load:
<script type="text/javascript">
// When rending an underscore template, we want top-level
// variables to be referenced as part of an object. For
// technical reasons (scope-chain search), this speeds up
// rendering; however, more importantly, this also allows our
// templates to look / feel more like our server-side
// templates that use the rc (Request Context / Colletion) in
// order to render their markup.
_.templateSettings.variable = "rc";
// Grab the HTML out of our template tag and pre-compile it.
var template = _.template(
$( "script.template" ).html()
);
// Define our render data (to be put into the "rc" variable).
var templateData = {
listTitle: "Olympic Volleyball Players",
};
// Render the underscore template and inject it after the div rendered
// in our current DOM.
$( "#rendered" ).after(
template( templateData )
);
</script>
Is is possible to define regions in the template, that would pull content from the page?
Let's say I have in my template the following structure:
<div class=sidebar></div>
<div class=content></div>
And from the page content, I would like to pull some html content to the sidebar, and other content to content div.
Is this possible?
With Swig as the Engine
Yes, this is possible. Seehttps://github.com/assemble/boilerplate-swig, in particular, this example, which shows how to use {% macro %} tags to accomplish what you're asking about.
If you want to use Swig, be sure to look at the readme as the assemble-swig repo as well. You have to register swig as the current engine in assemble:
assemble: {
options: {
engine: 'swig'
}
}
With Handlebars as the Engine
If the sidebar content will always be the same, on every page then you can use partials for this. Even if the URLs or active classes change on each page, this should work.
However, dynamic content using template or "block" inheritance, e.g. extend can be achieved with Handlebars helpers.
But since layouts are used with assemble this is a bit trickier to do with "out-of-the-box" helpers. To clarify, just about any helper I can think of will work great with assemble out-of-the-box, except for this - specifically because of how layouts work.
My suggestion is that you add to the existing feature request(s) for this on assemble and/or the handlebars-helpers project to add your use case and thoughts on what you want to achieve:
https://github.com/assemble/assemble/issues/38
https://github.com/assemble/handlebars-helpers/issues/16
#jonschlinkert You should update assemble's documentation, cause start with Assemble isn't so easy and a lot of things are little hidden.
So Luis, you can try this method, which currently works great for me too!
Assemble: Multiple points of content insertion in layout?
I'm working on a Drupal site/theme. The CSS and PHP modifications are fairly easy; they just take a little time to learn and get working exactly how I want.
However, I'm having issues applying CSS styles to some elements because of what I think is a property function.
The code looks like <h2 property="dc:title" datatype="" class="node-title">.
What is a property function and what does it do or control within the page? Also how can I modify or remove it?
It's not a property function; it's an attribute that is used from RDFa, and that is added from the RDF module.
The easier way to remove those attributes is to disable the module, but I would not suggest doing it, as the purpose of that module is to enrich your content with metadata to let other applications better understand its relationships and attributes.
Alternatively, if the problem is just with that property, used for the nodes, then you can implement code similar to the following one:
function mymodule_preprocess_node(&$variables) {
if (isset($variables['title_attributes_array'])) {
$variables['title_attributes_array']['property'] = NULL;
}
}
The module should be executed after the RDF module, to allow its hook to be executed after the one implemented by the RDF module.
I have not seen any compatibility problem between the attributes added by the RDF module and the JavaScript code executed by Drupal core or third-party modules. It would probably be the case to investigate why you are having problems with the JavaScript code when those HTML attributes are added.
in your css file, put:
h2[property="dc:title"]{color:#FFFFFF;}
or if it is a link, you may need:
h2[property="dc:title"] a {color:#FFFFFF;}
From wikipedia, check out RDFa
RDFa (or Resource Description
Framework – in – attributes) is a W3C
Recommendation that adds a set of
attribute-level extensions to XHTML
for embedding rich metadata within Web
documents.
It is basically a way to add more metadata to XHTML docs for better semantics.
I am a total beginner so pls be patient with me if my question might sound too dumb.
I am studying html, css, basic native php, and cakephp at the same time (which is not a good idea, I think its better to master the native cakephp first before jumping to any framework). As far as I know classes and ids are for css styling until I stumbled upon this code when I am studying cakephp:
<div class="posts index">
.
.
.
</div>
Note: I scaffolded a Post
I tried to look in the default css of cakephp for the class "posts index" but I can't find it so I concluded that there may be other uses of html classes aside from css. I am not sure about. I am just guessing. Can somebody explain to me in general about html classes. I also wanna know about the class "posts index" regarding its significance to cakephp. Pls help...
first of all you have to separate your "business logic" (program logic) and your "view" (output). The logic is done by your php code, it doesn't matter whether you use a framework or not. Your output can be html, xml, wml or some other stuff and is generated by your logic, your php code.
-> The class definition is only relevant in your output, so it doesn't matter for your cakePHP!
Next, there's no syntactic rule that every class in html must be defined in css. So your conclusion uses a rule that does not exist :-) It is not nice code because you have unused and needles html code, but it is not wrong. Most frameworks and tools use such "default classes" because of template support. Look at the html code of wordpress templates, there you will find these classnames, too, to make it more easy to change your css files to get different look&feels. When you create a new template with css styles, you know that the "posts index" element contains post-entries...
You can use classes and ids in JavaScript to get and identify elements, but this belongs also to the output/client-side area.
BTW: if you parse your html with some php code and need the class definition to identify an html element in the DOM then it matters, but I don't think you want do this ^^