js design patterns. Design Patterns in JavaScript in Simple Words

As long as you develop simple applications in Javascript, you won't have much trouble displaying data on a web page.

But when it comes to processing a large amount of data that is stored in arrays and objects and that must be displayed on the page according to certain rules, difficulties can arise here.

For example, you need to display on a page a list of site users with all their parameters (for example, id, name. There may also be age, gender, etc.). Let's assume that this data is inside the usersData object

Var usersData = [ ( name: "Dima", id: 1 ), ( name: "Katy", id: 2 ), ( name: "Lena", id: 3 ) ];

To solve this problem, you can use a loop, then the solution might look like this:

For(var i=0; i" + userData.name[i] + ""; }

Agree that only a programmer who knows how to write in Javascript can work with this form of notation. Provide such code to a layout designer, and he will not understand anything there.

But it will be much more clear to display the data in this form:

  • :((:name))
  • Even a person who knows only the HTML markup language can already understand this form of recording. Intuitively, you can figure out that the corresponding variable values ​​will be substituted in curly brackets.

    This form of recording becomes possible using so-called templates.

    A template is a specific template in HTML code, which is written according to certain rules. When Javascript code begins to interact with such a template, the template code will be converted into HTML code or DOM tree nodes on the page.

    The syntax of templates in Javascript can be different. Single standard no, and everything will depend on which library or plugin you use.

    Here is a template that creates a menu on the site:

    Here, instead of curly braces, this notation is used:

    Here is another example of a template that substitutes the appropriate values ​​for CSS styles, depending on the actions performed by the user.

    MyButton ( box-shadow: ; background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, ), color-stop(1, )); background:linear-gradient(to bottom, 5% , 100%); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="", endColorstr="",GradientType=0);

    To summarize, let's see what advantages using templates will give us:

    Intuitive code, even for non-programmers;

    A more abbreviated form of notation;

    Data, javascript code and output to pages are separated from each other, which makes them much easier to manage.

    In general, whether or not to use Javascript templates on web pages is up to you. I have already made a decision for myself and am already starting to use them in some of my developments.

    Sometimes it is not desirable to instantiate a class directly. Then we resort to generative patterns, which can select the optimal instantiation mechanism.

    Simple Factory

    Making doors yourself when building a house would be quite difficult, so you get them ready-made from the store.

    Pattern A simple factory produces the required copy without bothering the client with the intricacies of this process.

    Implementation example

    Let's create an implicit interface for all doors:

    /* Door getWidth() getHeight() */ class WoodenDoor ( constructor(width, height)( this.width = width this.height = height ) getWidth() ( return this.width ) getHeight() ( return this.height ) )

    We will organize a factory that will produce them:

    Const DoorFactory = ( makeDoor: (width, height) => new WoodenDoor(width, height) )

    That's it, you can work:

    Const door = DoorFactory.makeDoor(100, 200) console.log("Width:", door.getWidth()) console.log("Height:", door.getHeight())

    The pattern is useful if creating an object requires some logic. It makes sense to move repetitive code into a separate Simple Factory.

    Factory method

    A recruiting manager works with candidates for various vacancies. Instead of delving into the intricacies of each position, he delegates the technical interview to fellow specialists.

    This pattern allows you to create different variations of an object without polluting the constructor with unnecessary code.

    Implementation example

    Let's start with the hamburger itself:

    Class Burger ( constructor(builder) ( this.size = builder.size this.cheeze = builder.cheeze || false this.pepperoni = builder.pepperoni || false this.lettuce = builder.lettuce || false this.tomato = builder .tomato || false ) )

    And here is the Builder:

    Class BurgerBuilder ( constructor(size) ( this.size = size ) addPepperoni() ( this.pepperoni = true return this ) addLettuce() ( this.lettuce = true return this ) addCheeze() ( this.cheeze = true return this ) addTomato() ( this.tomato = true return this ) build() ( return new Burger(this) ) )

    Voila! Here's our burger:

    Const burger = (new BurgerBuilder(14)) .addPepperoni() .addLettuce() .addTomato() .build()

    The Builder pattern is needed if an object can exist in different variations or the instantiation process consists of several steps.

    Singleton

    The country must have a single president, otherwise there will be chaos.

    This pattern wraps an object and dynamically changes its behavior.

    Implementation example

    Let's take coffee for example. The simplest coffee that implements the appropriate interface:

    /* Coffee interface: getCost() getDescription() */ class SimpleCoffee( getCost() ( return 10 ) getDescription() ( return "Simple coffee" ) )

    We want to be able to add various additives to coffee, for this we will create some decorators:

    Class MilkCoffee ( constructor(coffee) ( this.coffee = coffee ) getCost() ( return this.coffee.getCost() + 2 ) getDescription() ( return this.coffee.getDescription() + ", milk" ) ) class WhipCoffee ( constructor(coffee) ( this.coffee = coffee ) getCost() ( return this.coffee.getCost() + 5 ) getDescription() ( return this.coffee.getDescription() + ", whip" ) ) class VanillaCoffee ( constructor (coffee) ( this.coffee = coffee ) getCost() ( return this.coffee.getCost() + 3 ) getDescription() ( return this.coffee.getDescription() + ", vanilla" ) )

    Now you can make coffee to your taste:

    Let someCoffee someCoffee = new SimpleCoffee() console.log(someCoffee.getCost())// 10 console.log(someCoffee.getDescription())// Simple Coffee someCoffee = new MilkCoffee(someCoffee) console.log(someCoffee.getCost( ))// 12 console.log(someCoffee.getDescription())// Plain coffee, milk someCoffee = new WhipCoffee(someCoffee) console.log(someCoffee.getCost())// 17 console.log(someCoffee.getDescription() )// Plain coffee, milk, cream someCoffee = new VanillaCoffee(someCoffee) console.log(someCoffee.getCost())// 20 console.log(someCoffee.getDescription())// Plain coffee, milk, cream, vanilla

    Facade

    To turn on the computer, just press a button. It's very simple, but there's a lot of complex stuff going on inside the computer that turns on. A simple interface to a complex system is the Façade.

    Implementation example

    Let's create a computer class:

    Class Computer ( getElectricShock() ( console.log("Ouch!") ) makeSound() ( console.log("Beep beep!") ) showLoadingScreen() ( console.log("Loading..") ) bam() ( console.log("Ready to be used!") ) closeEverything() ( console.log("Bup bup bup buzzzz!") ) sooth() ( console.log("Zzzzz") ) pullCurrent() ( console. log("Haaah!") ) )

    and a simple Façade for its complex functions:

    Class ComputerFacade ( constructor(computer) ( this.computer = computer ) turnOn() ( this.computer.getElectricShock() this.computer.makeSound() this.computer.showLoadingScreen() this.computer.bam() ) turnOff() ( this.computer.closeEverything() this.computer.pullCurrent() this.computer.sooth() ) )

    This makes working with a computer much easier:

    Const computer = new ComputerFacade(new Computer()) computer.turnOn() // Ouch! Beep beep! Loading.. Ready to be used! computer.turnOff() // Bup bup buzzz! Haah! Zzzzz

    Opportunist

    On long-distance trains, water for hot drinks is boiled in large containers - for everyone at once. This allows you to save electricity (or gas).

    On job search sites you can subscribe to job options that interest you. When a suitable offer appears, the site sends you a notification.

    The Observer pattern allows you to notify all interested objects about changes that have occurred.

    Implementation example

    Applicants want to receive notifications:

    Const JobPost = title = (( title: title )) class JobSeeker ( constructor(name) ( this._name = name ) notify(jobPost) ( console.log(this._name, "has been notified of a new posting:", jobPost.title) ) )

    And the Notice Board can send these notifications:

    Class JobBoard ( constructor() ( this._subscribers = ) subscribe(jobSeeker) ( this._subscribers.push(jobSeeker) ) addJob(jobPosting) ( this._subscribers.forEach(subscriber = ( subscriber.notify(jobPosting) )) ) )

    // create subscribers const jonDoe = new JobSeeker("John Doe") const janeDoe = new JobSeeker("Jane Doe") const kaneDoe = new JobSeeker("Kane Doe") // create a message board // sign up applicants const jobBoard = new JobBoard() jobBoard.subscribe(jonDoe) jobBoard.subscribe(janeDoe) // notify subscribers about a new vacancy jobBoard.addJob(JobPost("Software Engineer")) // John Doe has been notified of a new posting: Software Engineer // Jane Doe has been notified of a new posting: Software Engineer

    Visitor

    To travel abroad, you need to obtain permission (visa). But once in the country, you can safely visit a variety of places without asking for additional permission. You just need to know about them.

    The Visitor pattern allows you to add additional operations to objects without changing their source code.

    Implementation example

    Let's simulate a zoo with different types animals:

    Class Monkey ( shout() ( console.log("Ooh oo aa aa!") ) accept(operation) ( operation.visitMonkey(this) ) class Lion ( roar() ( console.log("Roaaar!") ) accept(operation) ( operation.visitLion(this) ) ) class Dolphin ( speak() ( console.log("Tuut tuttu tuutt!") ) accept(operation) ( operation.visitDolphin(this) ) )

    Now we want to listen to what sounds they make. To do this, we will create a Visitor:

    Const speak = ( visitMonkey(monkey)( monkey.shout() ), visitLion(lion)( lion.roar() ), visitDolphin(dolphin)( dolphin.speak() ) )

    It simply accesses each class and calls the desired method:

    Const monkey = new Monkey() const lion = new Lion() const dolphin = new Dolphin() monkey.accept(speak) // Ooh oo aa aa! lion.accept(speak) // Roaaar! dolphin.accept(speak) // Tuut tutt tuutt!

    The visitor allows existing objects not to be modified. With its help, you can, for example, add the ability to jump to all these animals without creating additional methods.

    Const jump = ( visitMonkey(monkey) ( console.log("Jumped 20 feet high! on to the tree!") ), visitLion(lion) ( console.log("Jumped 7 feet! Back on the ground!") ) , visitDolphin(dolphin) ( console.log("Walked on water a little and disappeared") ) )

    Monkey.accept(speak) // Ooh oo aa aa! monkey.accept(jump) // Jumped 20 feet high! on to the tree! lion.accept(speak) // Roaaar! lion.accept(jump) // Jumped 7 feet! Back on the ground! dolphin.accept(speak) // Tuut tutt tuutt! dolphin.accept(jump) // Walked on water a little and disappeared

    Strategy

    To organize some set of data, you use a bubble sort algorithm. It copes well with small volumes, but slows down with large ones. Quicksort has the opposite problem. Then you decide to change the algorithm depending on the size of the set. This is your Strategy.

    The Strategy template allows you to switch the algorithm used depending on the situation.

    Implementation example

    First-class functions will help you implement the Strategy in JavaScript.

    Const bubbleSort = dataset => ( console.log("Sorting with bubble sort") // ... // ... return dataset ) const quickSort = dataset => ( console.log("Sorting with quick sort") / / ... // ... return dataset )

    And this is a client who can use any strategy:

    Const sorter = dataset => ( if(dataset.length > 5)( return quickSort ) else ( return bubbleSort ) )

    Now you can sort the arrays:

    Const longDataSet = const shortDataSet = const sorter1 = sorter(longDataSet) const sorter2 = sorter(shortDataSet) sorter1(longDataSet) // Sorting with quick sort sorter2(shortDataSet) // Sorting with bubble sort

    State

    You draw in Paint. Depending on your choice, the brush changes its state: it paints in red, blue or any other color.

    The State pattern allows you to change the behavior of a class when the state changes.

    Implementation example

    Let's create text editor, in which you can change the state of the text - bold, italic, etc.

    These are the conversion functions:

    Const upperCase = inputString => inputString.toUpperCase() const lowerCase = inputString => inputString.toLowerCase() const defaultTransform = inputString => inputString

    And here is the editor himself:

    Class TextEditor ( constructor(transform) ( this._transform = transform ) setTransform(transform) ( this._transform = transform ) type(words) ( console.log(this._transform(words)) ) )

    You can work:

    Const editor = new TextEditor(defaultTransform) editor.type("First line") editor.setTransform(upperCase) editor.type("Second line") editor.type("Third line") editor.setTransform(lowerCase) editor.type ("Fourth line") editor.type("Fifth line") // First line // SECOND LINE // THIRD LINE // fourth line // fifth line

    Template method

    You build a house according to a specific plan: first the foundation, then the walls and only then the roof. The order of these steps cannot be changed, but their implementation may vary.

    A template method defines the "skeleton" of the algorithm, but delegates the implementation of the steps to child classes.

    Implementation example

    Let's create a tool for testing, building and deploying the application.

    The base class defines the skeleton of the assembly algorithm:

    Class Builder ( // Template method build() ( this.test() this.lint() this.assemble() this.deploy() ) )

    And the child classes are the specific implementation of each step:

    Class AndroidBuilder extends Builder ( test() ( console.log("Running android tests") ) lint() ( console.log("Linting the android code") ) assemble() ( console.log("Assembling the android build" ) ) deploy() ( console.log("Deploying android build to server") ) ) class IosBuilder extends Builder ( test() ( console.log("Running ios tests") ) lint() ( console.log("Linting the ios code") ) assemble() ( console.log("Assembling the ios build") ) deploy() ( console.log("Deploying ios build to server") ) )

    Let's assemble the project:

    Const androidBuilder = new AndroidBuilder() androidBuilder.build() // Running android tests // Linting the android code // Assembling the android build // Deploying android build to server const iosBuilder = new IosBuilder() iosBuilder.build() // Running ios tests // Linting the ios code // Assembling the ios build // Deploying ios build to server

    • Translation

    Translator's note: The topic of inheritance in JavaScript is one of the most difficult for beginners. With the addition of the new syntax with the class keyword, understanding inheritance clearly has not become easier, although nothing radically new has appeared. This article does not touch on the nuances of implementing prototypal inheritance in JavaScript, so if the reader has any questions, I recommend reading the following articles: Basics and Misconceptions about JavaScript and Understanding OOP in JavaScript [Part 1]

    For any comments related to the translation, please contact us in a personal message.

    JavaScript is a very powerful language. So powerful that many coexist in it in various ways design and creation of objects. Each method has its pros and cons and I would like to help beginners figure it out. This is a continuation of my previous post, Stop “categorizing” JavaScript. I have received many questions and comments asking for examples, and for this very purpose I decided to write this article.

    JavaScript uses prototypical inheritance This means that in JavaScript, objects are inherited from other objects. Simple objects in JavaScript created using () curly braces have only one prototype: Object.prototype. Object.prototype, in turn, is also an object, and all properties and methods Object.prototype available for all objects.

    Arrays created using square brackets have several prototypes, including Object.prototype And Array.prototype. This means that all properties and methods Object.prototype And Array.prototype available for all arrays. Properties and methods of the same name, for example .valueOf And .ToString, are called from the nearest prototype, in this case from Array.prototype.

    Prototype Definitions and Object Creation Method 1: Constructor Pattern JavaScript has a special type of function called constructors, which act in the same way as constructors in other languages. Constructor functions are called only using the keyword new and associate the created object with the context of the constructor function through the keyword this. A typical constructor might look like this:
    function Animal(type)( this.type = type; ) Animal.isAnimal = function(obj, type)( if(!Animal.prototype.isPrototypeOf(obj))( return false; ) return type ? obj.type === type: true; ); function Dog(name, breed)( Animal.call(this, "dog"); this.name = name; this.breed = breed; ) Object.setPrototypeOf(Dog.prototype, Animal.prototype); Dog.prototype.bark = function())( console.log("ruff, ruff"); ); Dog.prototype.print = function())( console.log("The dog " + this.name + " is a " + this.breed); ); Dog.isDog = function(obj)( return Animal.isAnimal(obj, "dog"); );
    Using this constructor looks the same as creating an object in other languages:
    var sparkie = new Dog("Sparkie", "Border Collie"); sparkie.name; // "Sparkie" sparkie.breed; // "Border Collie" sparkie.bark(); // console: "ruff, ruff" sparkie.print(); // console: "The dog Sparkie is a Border Collie" Dog.isDog(sparkie); // true
    bark And print prototype methods that apply to all objects created using the constructor Dog. Properties name And breed are initialized in the constructor. It is a common practice for all methods to be defined in the prototype and properties to be initialized by the constructor. Method 2: Defining a class in ES2015 (ES6) Keyword class has been reserved in JavaScript from the very beginning and now it's finally time to use it. Class definitions in JavaScript are similar to other languages.
    class Animal ( constructor(type)( this.type = type; ) static isAnimal(obj, type)( if(!Animal.prototype.isPrototypeOf(obj))( return false; ) return type ? obj.type === type : true; ) ) class Dog extends Animal ( constructor(name, breed)( super("dog"); this.name = name; this.breed = breed; ) bark())( console.log("ruff, ruff" ); ) print())( console.log("The dog " + this.name + " is a " + this.breed); ) static isDog(obj)( return Animal.isAnimal(obj, "dog"); ) )
    Many people find this syntax convenient because it combines the constructor and declaration of static and prototype methods in one block. The usage is exactly the same as in the previous method.
    var sparkie = new Dog("Sparkie", "Border Collie"); Method 3: Explicit Prototype Declaration, Object.create, Factory Method This method shows what the new keyword syntax is actually class uses prototypical inheritance. This method also allows you to create new object without using an operator new.
    var Animal = ( create(type)( var animal = Object.create(Animal.prototype); animal.type = type; return animal; ), isAnimal(obj, type)( if(!Animal.prototype.isPrototypeOf(obj) )( return false; ) return type ? obj.type === type: true; ), prototype: () ); var Dog = ( create(name, breed)( var proto = Object.assign(Animal.create("dog"), Dog.prototype); var dog = Object.create(proto); dog.name = name; dog. breed = breed; return dog; ), isDog(obj)( return Animal.isAnimal(obj, "dog"); ), prototype: ( bark())( console.log("ruff, ruff"); ), print( )( console.log("The dog " + this.name + " is a " + this.breed); ) ) );
    This syntax is convenient because the prototype is declared explicitly. It is clear what is defined in the prototype and what is defined in the object itself. Method Object.create is convenient because it allows you to create an object from a specified prototype. Checking with .isPrototypeOf still works in both cases. The uses are varied, but not excessive:
    var sparkie = Dog.create("Sparkie", "Border Collie"); sparkie.name; // "Sparkie" sparkie.breed; // "Border Collie" sparkie.bark(); // console: "ruff, ruff" sparkie.print(); // console: "The dog Sparkie is a Border Collie" Dog.isDog(sparkie); // true Method 4: Object.create, top-level factory, deferred prototype This method is a slight modification of method 3, where the class itself is a factory, as opposed to the case where the class is an object with a factory method. Similar to the constructor example (method 1), but uses a factory method and Object.create.
    function Animal(type)( var animal = Object.create(Animal.prototype); animal.type = type; return animal; ) Animal.isAnimal = function(obj, type)( if(!Animal.prototype.isPrototypeOf(obj) )( return false; ) return type ? obj.type === type: true; ); Animal.prototype = (); function Dog(name, breed)( var proto = Object.assign(Animal("dog"), Dog.prototype); var dog = Object.create(proto); dog.name = name; dog.breed = breed; return dog; ) Dog.isDog = function(obj)( return Animal.isAnimal(obj, "dog"); ); Dog.prototype = ( bark())( console.log("ruff, ruff"); ), print())( console.log("The dog " + this.name + " is a " + this.breed); ) );
    This method is interesting because it is similar to the first method, but does not require a keyword new and works with the operator instanceOf. The usage is the same as in the first method, but without using the keyword new:
    var sparkie = Dog("Sparkie", "Border Collie"); sparkie.name; // "Sparkie" sparkie.breed; // "Border Collie" sparkie.bark(); // console: "ruff, ruff" sparkie.print(); // console: "The dog Sparkie is a Border Collie" Dog.isDog(sparkie); // true Comparison Method 1 vs Method 4 There are very few reasons to use Method 1 instead of Method 4. Method 1 requires either the use of a keyword new, or adding the following check in the constructor:
    if(!(this instanceof Foo))( return new Foo(a, b, c); )
    In this case it is easier to use Object.create with factory method. You also can't use functions Function#call or Function#apply with constructor functions because they override keyword context this. The check above may solve this problem, but if you need to work with an unknown number of arguments in advance, you should use a factory method. Method 2 vs Method 3 Same reasoning about constructors and operator new that were mentioned above are also applicable in this case. Checking with instanceof required if new syntax is used class without using an operator new or are used Function#call or Function#apply.My opinion A programmer should strive for clarity in his code. The Method 3 syntax makes it very clear what is actually happening. It also makes it easy to use multiple inheritance and stack inheritance. Since the operator new violates the open/closed principle due to incompatibility with apply or call, it should be avoided. Keyword class hides the prototypical nature of inheritance in JavaScript behind the mask of a class system.
    “Simple is better than sophisticated,” and using classes because it is considered more “sophisticated” is just an unnecessary, technical headache.
    Usage Object.create is more expressive and clear than using copula new And this. Additionally, the prototype is stored in an object that can be outside the context of the factory itself, and thus can be more easily modified and extended by adding methods. Just like classes in ES6.
    Keyword class, may be the most detrimental feature of JavaScript. I have enormous respect for the brilliant and very hardworking people who were involved in the process of writing the standard, but even brilliant people sometimes do the wrong thing. -Eric Elliott
    Adding something unnecessary and possibly harmful, contrary to the very nature of language, is thoughtless and erroneous.
    If you decide to use class, I sincerely hope that I never have to work with your code. In my opinion, developers should avoid using constructors, class And new, and use methods that are more natural to the paradigm and architecture of the language. Glossary Object.assign(a, b) copies all enumerable properties of an object b to object a and then returns the object a
    Object.create(proto) creates a new object from the specified prototype proto
    Object.setPrototypeOf(obj, proto) changes internal property [] object obj on proto

    Tags: Add tags

    WordPress uses templates everywhere and Javascript is no exception. In this post, we’ll talk about the ability built into WordPress to create HTML templates, which can then be used in JS. These templates are very easy to create and use, just like many other things in WordPress.

    There are many ways to create templates in Javascript, there is even a separate specification for them called Mustache. It is implemented in many languages, including Javascript. For example, the Handlebars library uses this specification and even extends it a little. Or the popular Underscore mini-library.

    Since version 3.5, WordPress already has a convenient template engine for JS in its core. For example, it is used in the admin panel when creating blocks for the media loader. Based on the aforementioned Underscore library, the syntax has been slightly modified to be more consistent with the Mustache specification.

    To create templates in WordPress there is a method wp.template

    wp.template(id)

    Creates a template object from HTML code. To get ready-made HTML code for use in JS, you need to pass data to fill out the template into the created object.

    Returns

    Function. A function to pass data to for template interpolation.

    Using var template = wp.template(id); var HTML = template(data); id (line)

    ID of the HTML element that contains the HTML code of the template. The HTML element must have the id attribute specified here with the tmpl- prefix.

    For example, if you specify foo here, then the HTML element must have id id="tmpl-foo" .

    Data (an object) JS data object that will be used to fill the template. For example: ( text: "Hello") .

    Pattern Filling (Interpolation)
    • (((data.unescaped))) - uncleaned data.
    • ((data.escaped)) - cleared data.
    • - process js (eval).
    Data prefix.

    data in the template is the source data object. You need to use the data key in the template.

    To match the data structure returned by the wp_send_json_success() and wp_send_json_error() functions, wp.template wraps all received data in a data variable. Therefore, before each parameter in the template you need to specify data. , otherwise we will get the error: (property) is not defined .

    Correct (((data.name)))

    Incorrect (((name)))

    Example template

    It will simply be output.

    Let's display the value of the escapedValue ((data.escapedValue)) variable.

    If the data contains markup, print it without escaping:

    (((data.unescapedValue)))

    When you need to perform some logic.

    Will only be printed if data.trueValue = true.

    Creating and generating a template Creating a template

    To ensure that the template does not appear in any way in the DOM tree, it is customary to create it in a script tag with the type indication type="text/html" .

    Hello (((data.name)))

    The id attribute must start with tmpl- , anything after this prefix will then be used in the wp.template("my-template") function.

    Creating a template in a script tag is a hack that is great for creating html element but, which is not used by the browser in any way. When a type that is incomprehensible to the browser is specified, it simply ignores the html tag, which is what we need.

    The template can also be created in any other HTML element (for example, in , which can then be hidden), the only thing you need to do is specify the id attribute.

    There is also a special one for creating templates HTML tag however it is not supported in IE. But overall it is quite relevant.

    Template generation

    wp.template() returns a function, so don't try to pass the result to an html element or print the result to the console. Typically, the result of wp.template() is passed into a variable, and then that variable is used as a function and passed the data with which the template should be filled.

    Example (template shown above)

    // JS var template = wp.template("my-template"), data = ( name: "Victor" ); jQuery(".my-element").html(template(data));

    As a result, we get in HTML:

    Hello Victor

    An example of AJAX commenting using a template

    Create a template and include the script in the theme's functions.php file:

  • (((data.gravatar))) ((data.comment_author))