How does a frameworks like Vue implement their own custom syntaxes within an HTML document?
So I want to create a template engine, consequently I need to know how to implement my own custom syntax. I thought that an easy one would be the double curlys that can be used in Vue. Example of curlys:
<h1>{{pageTitle}}</h1>
My first thought was to use `String.prototype.replaceAll(regex, string); but I got stuck at the regex I would use. In fact thinking about it now, I probably need a dynamic regular expression maybe?
p.replaceAll(/\{\{()\}\}/g, '<p>{{embeddedVar}}</p>')
The other option I considered was a parser, or a lexer, but I didn't even know where to start. I built them in school in C++. I thought maybe NPM has one pre-built?
It seems like several developers have wrote their own custom template engine that has built-in support for the double curly brackets. I was thinking that maybe there is a common way that its being implemented.
The Vue syntax is indeed not understood by the browser. the work is done by the Vue library that's imported in every Vue app.
The original markup (with the curly braces showing up) can even be seen for a split second when the page is loading, and this is because Vue hasn't loaded up all the way yet.
Related
I am trying to build a component to handle the editing of a substructure of my data. This piece of data is an object but in the main object, it is optional. So when invoking component I am trying to use the ?? operator to pass in an empty object to avoid access of undef issue. I would also like to be able to use the ?. operator for the same reason. Like so.
<template>
<my-sub-component :value="value.scf_rule??{}" />
</template>
However, Vuejs doesn't really like the question marks in the HTML attributes on my template. I get the following error:
Syntax Error: SyntaxError: Unexpected token (1:93)
This should be a really simple lookup on the web but I have been looking for quite a while and it's not easy. It doesn't help that searching for question marks isn't really possible.
I've tried escaping it with a backslash, that doesn't seem to work. Anyone know how I can have an expression in my attribute that uses the question mark operator? I suppose I could define my own nvl utility function but that seems a tad silly.
If you remove any kind of build stack from the equation, you can use whatever your platform supports. Your browser then will run the code just as you author it.
Otherwise you are limited to what the acorn parser version used by your webpack/bundler supports (usually everything finalized in the spec and proposals that have reached stage 4). With Vue, you're probably using webpack.
If you are fine with your code being transpiled to older JS versions, use Babel along with the necessary plugins 1 2.
We use DNN and often need to pass a few context specific values (like page id or module-on-page-id) into an AngularJS app. We've developed our own conventions how to do this, but would like to hear from others how they approach this to find a best practice.
So basically the situation is that the server-page has information needed by the JS. Using WebAPI is not an option, as these values are known in the page, but not in a separate request. Things I've seen so far have been:
Use in-view-razor like href="#Tab.TabId/{{...}}" (I don't like this)
Place the values in the ng-init like ng-init="config = { prop1: '#Tab.TabId' }"
Create a separate <script> tag where we generate a module on the fly containing these values so angular.module("config", []).constant('prop1', '#Tab.TabId')
Create a json with razor in the page somewhere and inject all of it as a module into the app using a generic code which does the same as #3, just with cleaner code re-use.
I've seen all these and have also used all. Currently we avoid #1 as we believe it's not good to mix templating languages and because it doesn't allow externalizing parts of the view. So basically we use #2 as for quick-and-simple (and a bit dirty) + #3/#4 for larger projects.
Do you have a better way, or which way would you prefer?
We are using variant #4.
This has the advantage that the JSON defines the exact interface for the config needed by the JS module. And Razor is great to generate URLs using #Url.Action.
we use NewtonSoft and do JSONConvert.SerializeObject(ObjectName) and then pass it over as a Session from the controller and then use #Html.Raw(ObjectName) and its a JSON Object that can be utilized easily in javascript...
I am using eclipse as my IDE but I don't like the installed formatters. I also builded my own one but didn't get it to work like I want it to. For example things like that happen often:
Is there somebody out there with a good JavaScript formatter or a link with a list of some. I only found a few (e.g. the google formatter) but I don't like one of them.
Try changing the formatting preferences individually.
Window->Preferences->JavaScript->Code Style->Formatter
You'll have to save them as a new file. The only issue i have is that the object declaration won't use tabs instead of spaces for the property declarations.
I've had this same question when working with different templating systems in different languages in the past, so first,
The general question
I want to use a sub-template to include a certain UI component which might appear in different places on a number of different pages. This UI component requires certain CSS and JS files.
I want to Do The Right Thing with CSS and JS resources, which, as far as I know and in broad terms, is to a) combine as many as possible b) minify as much as possible and maybe c) put what I can at the end of my markup so the browser doesn't have to wait for them to load before displaying content.
So, if I've got various different UI components, as well as different headers and sidebars in different sections of the site, which all require their own special CSS and JS to function correctly, what's the best way for me to manage them through a templating system so that the final markup is as small and well-organised as possible?
Specifics of my situation
I'm working on a large legacy PHP site, on which, to give the original authors the benefit of the doubt, development may have begun before MVC became really mainstream, and before there were so many choices of frameworks around to use. So there is no consistent MVC framework, no routing, no templating (no ORM either, but that particular curse isn't as relevant here).
I'm going to have to keep things ticking over, squashing bugs and adding a few new features until a complete rewrite is usable, so I'm trying to breathe some sanity into things as I go along.
The easiest place to start seemed to be the views layer, for which I'm using TinyButStrong. An example of their sub-templates can be found here, but like I said, I think this is a very general question.
Things I've considered
With a more integrated framework I'd like to be able to do something like $view->add_js($foo), but transitioning to a full-blown framework is what other people are doing while I try keep the existing codebase seaworthy. There isn't even really enough consistent organisation of files to roll something like this by hand.
At the moment the best thing I can come up with is making a DOMDocument out of the view right before it's output and manipulating <link> and <script> tags at that point. I don't know if that's a bit crazy though. Given the generality of the problem I'd like to think that there's a known sensible way to go about it.
Many thanks for your input.
It's hard for the reader to know what can or cannot be done with your code base. A common way to handle this situation would be to pass parameters to the view template, and the template can then include conditional chunks or include sub-templates based on your parameters. This does not require a full-fledged framework, a stand-alone template engine should do. If your template engine supports inheritance there is a nice pattern for handling assets in your templates - check here for example http://symfony.com/doc/2.0/book/templating.html.
Manipulating the Dom for each request to handle this kind of thing seems bit unorthodox.
What you want in this situation is some form of template inheritance; that is, technology whereby a sub-template has access to areas in a 'parent' template, and can edit or replace content in those areas. Using this ability, CSS and JS required for a component included via a sub-template can be added in to the <head> element of the parent page.
In Twig, this is achieved using named blocks. First, you create your parent template (or layout, as it's called in Twig), e.g. index.html.twig. You include in it a named block like {% block myCss %}.
Next, to create a sub-template, you begin the template with the line {% extends ::index.html.twig %}. Then, the content of a block defined in the sub-template with the same name as a block in the parent template (in this case {% block myCSS %}) will get substituted into the parent template. To append rather than replace content in the parent template, use {{ parent() }} to include content already existing in the parent.
An example of this with code is available at the link given by #Basel Shishani. I've heard that Twig is modelled after Django, and template inheritance in Django looks very similar (with the exception of using {{ block.super }} instead of {{ parent() }}. There is a discussion of how to achieve the same ends in TinyButStrong.
As a wider point, the Assetic library looks like a very promising solution for managing CSS and JS assets, in order to avoid duplication (e.g. where the same JS file is required by multiple components/subtemplates), enable concatenation and minification of assets, and more. This presentation of its features gives more details.
When I first started with Javascript, I usually just put whatever I needed into functions and called them when I needed them. That was then.
Now, as I am building more and more complex web applications with Javascript; taking advantage of its more responsive user interaction, I am realizing that I need to make my code more readable - not only by me, but anyone who replaces me. Besides that, I would like the reduce the moments of 'what the heck, why did I do this' when I read my own code months later (yes, I am being honest here, I do have what the heck was I thinking moments myself, although I try to avoid such cases)
A couple weeks ago, I got into Joose, and so far, it has been good, but I am wondering what the rest do to make their chunk their codes into meaningful segments and readable by the next programmer.
Besides making it readable, what are your steps in making your HTML separated from your code logic? Say you need to create dynamic table rows with data. Do you include that in your Javascript code, appending the td element to the string or do you do anything else. I am looking for real world solutions and ideas, not some theoretical ideas posed by some expert.
So, in case you didnt't understand the above, do you use OOP practices. If you don't what do you use?
For really JS-heavy applications, you should try to mimic Java.
Have as little JS in your HTML as possible (preferably - just the call to the bootstrap function)
Break the code into logical units, keep them all in separate files
Use a script to concatenate/minify the files into a single bundle which you will serve as part of your app
Use JS namespaces to avoid cluttering up the global namespace:
var myapp = {};
myapp.FirstClass = function() { ... };
myapp.FirstClass.prototype.method = function() { ... };
myapp.SecondClass = function() { ... };
Using all these techniques together will yield a very manageable project, even if you are not using any frameworks.
I use unobtrusive javascript, so, outside of the script tags I don't keep any javascript in the html.
The two are completely separated.
A javascript function will start when the DOM tree is completed, which will go through the html and add the javascript events, and whatever else needs to be changed.
In order to organize, I tend to have some javascript files that are named similar to the html pages that they use, and then for common functions I tend to group them by what they do, and pick a name that explains that.
So, for example, if I have UI functions then I may call them: myapp_ui_functions.js
I try to put the name of the application in the filename, unless there is some javascript that is common to several projects, such as strings.js.
I have (usually) one file that contains a bunch of functions and that's it. That is included in every page that uses Javascript. In the pages themselves, I'll make the calls to the functions like:
$(function() {
$("#delete").click(delete_user);
$("#new").click(new_user);
});
where delete_user() and new_user() are defined in the external file.
I too use unobtrusive Javascript, which for me means jQuery (there are other libraries that are unobtrusive).
You don't want a separate file for each page. That just means more unnecessary external HTTP requests. With one file—assuming you've cached it effectively—it'll be downloaded once and that's it (until it changes).
If I have a large amount of Javascript or the site is effectively split into multiple areas then I may split the Javascript but that's not often the case.
Also, in terms of my source code, I may have multiple JS files but I'll often end up combining them into one download for the client (to reduce HTTP requests).
More at Multiple javascript/css files: best practices? and Supercharging Javascript in PHP.
I've been rewriting a lot of my reusable code as jQuery plugins. I moved to jQuery from Prototype when I started doing ASP.NET MVC. Overtime I've migrated a lot my reusable code, or at least the ideas, from Prototype-based OO to jQuery-style plugins. Most of these are stored in their own JS files (mainly intranet apps so page load speed is pretty high anyway despite the extra requests). I suppose I could add a build step that coalesces these if I needed to.
I've also settled on a MasterPage approach that uses a ContentPlaceHolder for scripts that is right before the closing body tag. The standard jQuery/jQuery UI loads, and any other common JS goes right before the script placeholder in the MasterPage. I have tiny bit of JS at the top of the MasterPage that defines an array that holds any functions that partial views need to run on page load. These functions are run from the base document.ready() function in the MasterPage.
All of my JS is completely separate from my mark up. Some JS may exist in partial views -- these are encapsulated when the partial may be included more than once to make it specific to that instance of the view -- but generally not. Typically only included in the placeholders so that it's loaded at the bottom of the page.
Also, if you want to go OO heavy, check out mochikit: http://www.mochikit.com/
I find that developing your javascript using OO methodology is the way to go if you want it to be clean, readable and even somewhat secure. I posted the following question
Cleanest format for writing javascript objects
And got some fantastic responses on how to write my javascript code well. If you follow these basic principles you can use almost any library, such as yui, jquery and prototype, with ease.