Cypher
Cypher

Reputation: 352

Change some html code into antoher with GULP

Thank you for checking my question. This may sound trivial but I need help here.

I want to learn how to change HTML code with GULP. Or just change some strings with GULP. For example today I need to change this:

<img class="social" src="../symbols/facebook.svg">

to this:

<svg class="social">
    <use xlink:href="../symbols/sprite.svg?v201608061556#facebook"></use>
</svg>

As you can see I am building icon system via symbols and I want to keep my original HTML clean as it can be. So I can work without any watchers and such. Later I just run GULP once and it does the job: create sprite and change HTML to use this sprite.

I tried gulp-replace and it can change one string to another with regex, but it looks too complicated for me with regex. I am not even sure that it is possible to do with regex. And I also want to add timestamp as ?v201608061556. So I want to run some JavaScript that I can write in gulp file.

Next one I tried is gulp-dom and it looks like the thing I need. But I can't make it work due to some errors:

if (node.nodeType === NODE_TYPE.DOCUMENT_NODE) {
        ^
TypeError: Cannot read property 'nodeType' of undefined

Error log in terminal: gulp-dom error output

So the questions is:

  1. Is it possible to make with regex and gulp-replace package?
  2. Does anyone know gulp-dom package. Can I make it work somehow? Is it possible to complete my task with it?
  3. Is there another way to write JavaScript in Gulp task so I can take a string, process it according to my needs with all JavaScript functionality and save?
  4. Can I work with HTML from Gulp the same way I work when I code websites? Work with DOM, use querySelector and classList for example? Maybe jQuery?

Thanks.

Upvotes: 2

Views: 3058

Answers (2)

Gabriel Ferraz
Gabriel Ferraz

Reputation: 632

It would be easier to diagnose the issue if you had posted your gulp tasks stream. With the information you provided I believe you are getting this error because (if you are following the example on the plugin page) you are probably returning the element you modified, not the complete Document representation. Below follows the example from the gulp plugin page:

gulp.task('html', function() {
return gulp.src('./src/index.html')
    .pipe(dom(function(){
        return this.querySelectorAll('body')[0].setAttribute('data-version', '1.0');
    }))
    .pipe(gulp.dest('./public/'));
});

There are two crucial steps you should take to manipulate the DOM with gulp-dom:

  1. first make the changes on the element(s) you want using simple js DOM manipulation methods such as getElmentById, setAttribute, appendChild, etc.
  2. once that is done, your gulp stream should return this (the whole Document), not the element(s) you are targeting for modification.

In your case you could do something like this (If you find this too verbose you may try to use a different plugin/approach altogether):

var gulp = require('gulp');
var dom = require('gulp-dom);

gulp.task('domManipulation', function() {
  return gulp.src('app/index.html')
    .pipe(dom(function(){
      // cache/create all elements you will work with --'this' is your Document
      var parentDiv = this.querySelector('div.imgParent');
      var img = this.querySelector('img.social');
      var svg = this.createElement('svg');
      var use = this.createElement('use');

      // DOM manipulation
      svg.classList.add('social');
      use.setAttribute('xlink:href', "../symbols/sprite.svg?v201608061556#facebook");
      svg.appendChild(use);
      parentDiv.replaceChild(svg, img);

      return this; // return the whole Document
    }))
    .pipe(gulp.dest('dist'));
}); 

I tested the code above and it works just fine. Hope this helps.

Upvotes: 0

Cypher
Cypher

Reputation: 352

Ok, I found a gulp-change. It gives you file content as a string. You can do everything you want with that string with javascript and then return it back to pipe.

Upvotes: 1

Related Questions