0

I am trying to find the way to expand a JavaScript variable value in HTML.

I know that it is possible to do it in PHP, like this:

<?php
   $myString = "Hello World";
?>

<p><?=$myString?></p>

Is it possible to do likewise in JavaScript with a similar native inline tag?


Note

I am aware of other solutions such as calling other functions, which is exactly what I want to avoid.

Community
  • 1
  • 1
Nicolas
  • 894
  • 1
  • 12
  • 22
  • No, in javascript running in a browser, you should generally access the elements you want, and add the content programatically, something like `document.querySelector('p').innerHTML = 'Hello World'` would be the way to go. You could also insert a script tag and use `document.write` but that's just about the worst way to do this. – adeneo Mar 23 '16 at 16:44
  • Why do you want to avoid using functions? Functions are good... I guess you could do it a very dirty way, like , but this is pure evil. You shouldn't really do this with PHP either, by the way. – Eihwaz Mar 23 '16 at 16:44
  • Do you mean this: `
    a b
    `?
    – eithed Mar 23 '16 at 16:45
  • Short answer: no. Long answer: https://facebook.github.io/jsx/ – Hypaethral Mar 23 '16 at 16:45
  • @Eiwhaz, Because I have a bunch of HTML object ID's used in Javascript that I want to keep centralized, rather than to spread them everywhere in my HTML files. Refactoring would be much easier using JavaScript variables than the actual literals – Nicolas Mar 23 '16 at 16:50
  • Yes, you can do that with a templating language, writing something like `

    {{myString}}

    `.
    –  Mar 23 '16 at 16:50
  • @torazaburo, do you mean like 'twig'? – Nicolas Mar 23 '16 at 16:51
  • I don't know twig, but there are a dozen good JS templating packages. –  Mar 23 '16 at 16:52
  • @torazaburo, I tried in Twig and doesn't work. It only works if I define the variable within the twig template, not in an external javascript file / block. But thanks anyway – Nicolas Mar 23 '16 at 17:07

2 Answers2

1

There is no native way for injecting JavaScript values into HTML by just using a tag like the PHP <=? tag. What comes closest might be ES6 template literals.

It can look like this:

var mystring = 'Hello World';

document.write(`

<p>${mystring}</p>

<div> 
   some other stuff
</div>

`);

This version of JavaScript is available in most browsers today, but will of course not work in older browser versions, nor for current Internet Explorer versions (are we surprised?) -- but it works in Edge.

There are no native capabilities in HTML that allow injection of JavaScript values following the PHP-like syntax. In my opinion, the above comes as close as you can get. The only way to access to JavaScript variables from within HTML is with specific attributes (like "onclick") -- which serve another purpose --, and with script tags, which do not work like the <?= PHP tag either, but more like the standard <?php tag.

Using templating libraries might be an option (e.g. mustache, underscore, EJS, handlerbars, pug, plates, dust.js, hogan.js, jsrender, markupjs, nunjucks...).

A simple, poor man's template library - class/content based

The above listed templating engines offer advanced features, but here is a very basic implementation that understands this kind of HTML:

<span class="template">`I want to say "${mystring}"`</span>

When the page loads, the "poor man's library" should render that as:

<span>I want to say "Hello World"</span>

Here is the code for doing just that:

/* my simple template library: you would include this from another JS file */
document.addEventListener("DOMContentLoaded", function(event) {
  var templates = document.getElementsByClassName('template');
  [].forEach.call(templates, function (template) {
    template.textContent = eval(template.textContent);
    template.setAttribute('class', '');
  });
});

/* my set of variables */
var mystring = 'Hello World';
# my simple template CSS
.template {display: none};
<span class="template">`I want to say "${mystring}"`</span>

A simple, poor man's template library - attribute based

Here is variation on the same concept. Now the syntax is a custom tag inject of which the value attribute has the value to inject. Here it is the "library" that injects the template literal backticks. This could also have been done in the first version.

/* my simple template library: you would include this from another JS file */
document.addEventListener("DOMContentLoaded", function(event) {
  var templates = document.getElementsByTagName('inject');
  [].forEach.call(templates, function (template) {
    template.textContent = eval('`' + template.getAttribute('value') + '`');
    template.removeAttribute('value');
  });
});

/* my set of variables */
var mystring = 'Hello World';
<inject value='I want to say "${mystring}"' />
trincot
  • 211,288
  • 25
  • 175
  • 211
  • 1
    Maybe the downvoter could explain what the issue is. – trincot Mar 23 '16 at 16:53
  • Thanks @trincot, but this solution will overcomplicate what I am trying to achieve. Best regards. – Nicolas Mar 23 '16 at 17:08
  • Sometimes the answer to a question cannot be *"Yes, here it is"*, because it just is not possible. So also in this case: the answer is more a "No, but look at this". Still, it is an answer to a Yes-No question (*"Is it possible...?"*). In the mean while I added some more info to my answer. – trincot Mar 23 '16 at 17:31
  • 1
    I added a poor man's template library to show what the idea of such library is. Please have a look at it. – trincot Mar 23 '16 at 22:48
  • thanks again for this. I can see it is working in the Stack Overflow code snippet, but I couldn't make it work in this jsFiddle: https://jsfiddle.net/pando/9app3dj6/1/ – Nicolas Mar 23 '16 at 23:02
  • By default JS fiddle makes the JS execute on load. Change the option in the top-right corner of the JS panel to "no-wrap in head". – trincot Mar 24 '16 at 07:39
  • I added yet another version of this templating principle: this time it is attribute based. It makes it quite concise. – trincot Mar 24 '16 at 08:04
1

I don't see how it's possible to achieve in JavaScript what you're trying to achieve.

The closest thing I can think of, is something like this :

<script>var message = "Hello World";</script>

<div>Before message</div>
<div>
    <script>document.write(message);</script>
</div>
<div>After message</div>

It is, however, recommended to avoid using document.write!


Note

Based on the info you provided in the comments, I think you're looking for one of the following approaches :

Community
  • 1
  • 1
John Slegers
  • 38,420
  • 17
  • 182
  • 152
  • Certainly closer to what I want, but not the kind of shorthand that I expected. Thanks anyway. N – Nicolas Mar 23 '16 at 20:23
  • @Nicolas : I'm not sure what use cases you had in mind, but maybe you should consider something like Mustache templates?! -> https://mustache.github.io/mustache.5.html – John Slegers Mar 24 '16 at 10:47
  • What I am trying to achieve is to make a central repository in Java Script of object ID's used in HTML (for example
    . The reason of doing that is that most of my JavaScripts access those ID to display / modify the layouts. When the templates are small, then there is no problem, but the bigger my project gets, the more difficult it becomes. I am using TWIG for templating, so when I use the {% include %} statement, there are lots of ID clashes
    – Nicolas Mar 24 '16 at 14:35
  • 1
    @Nicolas : Why not replace Twig with Mustache? Mustache is similar to Twig, but it has official implementations for both PHP and JavaScript, which means you can use the same template both in frontend and backend. Alternatively, consider using a (non-official) port of Twig to JavaScript -> https://github.com/justjohn/twig.js/ – John Slegers Mar 24 '16 at 14:38
  • I'll certainly have a look. Cheers. – Nicolas Mar 24 '16 at 14:41
  • @Nicolas : Let me know if that helps — Anyway, I just updated my answer with a note that references these options. – John Slegers Mar 24 '16 at 14:47