Skip to content

Instantly share code, notes, and snippets.

@landsman
Last active December 6, 2022 18:06
Show Gist options
  • Save landsman/526d88db01cf5ec50fad257fe2d44574 to your computer and use it in GitHub Desktop.
Save landsman/526d88db01cf5ec50fad257fe2d44574 to your computer and use it in GitHub Desktop.
automatic convert bootstrap v. 3 to bootstrap v. 4 idea ... more on https://github.com/twbs/bootstrap/blob/v4-dev/docs/4.0/migration.md, http://upgrade-bootstrap.bootply.com/
let gulp = require('gulp'),
replace = require('gulp-batch-replace'),
filesExist = require('files-exist');
gulp.task('bt4', () =>
{
let diff = {
'@media (min-width: $screen-xs-min) and (max-width: $screen-sm-max)': '@media (min-width: map-get($grid-breakpoints, xs)) and (max-width: map-get($grid-breakpoints, xs))',
'@media (min-width: $screen-xs) and (max-width: ($screen-md-min - 1))': '@media (min-width: map-get($grid-breakpoints, xs)) and (max-width: map-get($grid-breakpoints, md)-1)',
'@media (min-width: $screen-sm-min) and (max-width: $screen-sm-max)': '@include media-breakpoint-only(md)',
'@media (min-width: $screen-xs-min)': '@include media-breakpoint-up(xs)',
'@media (min-width: $screen-sm)': '@include media-breakpoint-up(md)',
'@media (min-width: $screen-sm-min)': '@include media-breakpoint-up(md)',
'@media (min-width: $screen-md-min)': '@include media-breakpoint-up(md)',
'@media (min-width: $screen-md)': '@include media-breakpoint-up(md)',
'@media (min-width: $screen-md-max)': '@include media-breakpoint-up(md)',
'@media (min-width: $screen-lg-min)': '@include media-breakpoint-up(lg)',
'@media (max-width: ($screen-xs-min - 1))': '@include media-breakpoint-down(xs)',
'@media (max-width: $screen-xs-max)': '@include media-breakpoint-down(xs)',
'@media (max-width: ($screen-sm-min - 1))': '@include media-breakpoint-down(md)',
'@media (max-width: $screen-sm)': '@include media-breakpoint-down(md)',
'@media (max-width: $screen-sm-min)': '@include media-breakpoint-down(md)',
'@media (max-width: $screen-sm-max)': '@include media-breakpoint-down(lg)',
'@media (max-width: $screen-md-max)': '@include media-breakpoint-down(md)',
'@media (max-width: $screen-lg-max)': '@include media-breakpoint-down(lg)',
'@media (max-width: $screen-xs-min - 1)': '@include media-breakpoint-down(xs)',
'@media (max-width: $screen-md-min)': '@include media-breakpoint-down(md)',
// bootstrap 2
'@media (max-width: $screen-xxs)': '@include media-breakpoint-down(xs)',
'.col-*-offset-*': '.offset-*',
'.col-*-push-*': '.order-*-2',
'.col-*-pull-*': '.order-*-1',
'.panel': '.card',
'.panel-heading': '.card-header',
'.panel-title': '.card-title',
'.panel-body': '.card-body',
'.panel-footer': '.card-footer',
'.panel-primary': '.card.bg-primary.text-white',
'.panel-success': '.card.bg-success.text-white',
'.panel-info': '.card.text-white.bg-info',
'.panel-warning': '.card.bg-warning',
'.panel-danger': '.card.bg-danger.text-white',
'.well': '.card.card-body',
'.thumbnail': '.card.card-body',
'.list-inline > li': '.list-inline-item',
'.dropdown-menu > li': '.dropdown-item',
'.nav navbar > li': '.nav-item',
'.nav navbar > li > a': '.nav-link',
'.navbar-right': '.ml-auto',
'.navbar-btn': '.nav-item',
'.navbar-fixed-top': '.fixed-top',
'.nav-stacked': '.flex-column',
'.btn-default': '.btn-secondary',
'.img-responsive': '.img-fluid',
'.img-circle': '.rounded-circle',
'.img-rounded': '.rounded',
//'.form-horizontal': '', // @note: removed
'.radio': '.form-check',
'.checkbox': '.form-check',
'.input-lg': '.form-control-lg',
'.input-sm': '.form-control-sm',
'.control-label': '.form-control-label',
'.table-condensed': '.table-sm',
'.pagination > li': '.page-item',
'.pagination > li > a': '.page-link',
//'.item': '.carousel-item', // @note: this is too much basic word
'.text-help': '.form-control-feedback',
'.pull-right': '.float-right',
'.pull-left': '.float-left',
'.center-block': '.mx-auto',
'.hidden-xs': '.d-none',
'.hidden-sm': '.d-sm-none',
'.hidden-md': '.d-md-none',
'.visible-xs': '.d-block.d-sm-none',
'.visible-sm': '.d-block.d-md-none',
'.visible-md': '.d-block.d-lg-none',
'.visible-lg': '.d-block.d-xl-none',
'.label': '.badge',
'.badge': '.badge.badge-pill',
// twig
'col-xs-': 'col-',
'col-md-': 'col-lg-',
'col-sm-': 'col-md-'
};
let replaceThis = [];
Object.keys(diff).forEach(function(key)
{
replaceThis.push([key, diff[key]]);
});
return gulp
.src(filesExist('./scss/**'))
.pipe(replace(replaceThis))
.pipe(gulp.dest('./build/scss'));
});
@HariPrasad-1493
Copy link

HariPrasad-1493 commented Jun 1, 2021

@kerryj89 thanks, but why jQuery? It's little bit outdated today.

No problem! Thanks for your script, also. As for jQuery syntax, it's what https://github.com/creativetimofficial/bootstrap-converter uses (it uses cheerio which they call jQuery for the server, never heard of it until recently). That will be helpful to programmatically rewrite my HTML in more complex scenarios where elements or classes might have moved around. Honestly as outdated as jQuery might be in customer facing sites, the sizzle engine is still a joy to use with how frictionless it is to traverse up and down the DOM. I think it's very applicable for this one time conversion use case.

It doesnt work for angular project though , since angular uses ngTemplates & template binding which are modified by this converter

eg. *ngIf="domains && domains.length>0" converted to *ngif="domains&& domains.length>0" where the conditional clause is altered

@HariPrasad-1493
Copy link

HariPrasad-1493 commented Jun 1, 2021

@landsman how do i run it though on a project structure with files like
Testapp >> home.ts home.html home.css

@landsman
Copy link
Author

landsman commented Jun 1, 2021

@HariPrasad-1493 Really up to you. You can copy paste defined object and write your own replace script. This is just a draft.

@HariPrasad-1493
Copy link

@HariPrasad-1493 Really up to you. You can copy paste defined object and write your own replace script. This is just a draft.

Ohk.. thought this was some gulp task i can run even though i haven't used gulp before :)

@kerryj89
Copy link

kerryj89 commented Jun 4, 2021

It doesnt work for angular project though , since angular uses ngTemplates & template binding which are modified by this converter

eg. *ngIf="domains && domains.length>0" converted to *ngif="domains&& domains.length>0" where the conditional clause is altered

I was able to use it on an AngularJS project and it didn't convert to html entity. It wasn't perfect but got 90% right. Maybe this can help: https://stackoverflow.com/a/31574528/3266845 I still looked through each template to make sure. I noticed it would close my attributes (i.e. <span attr-foo>Test</span> would turn into <span attr-foo="">Test</span> and sometimes would get confused by quotes and close prematurely. The worst is when it just removed a chunk of code sneakily, maybe a memory fault.

Sorry for this off-topic-on-topic reply, landsman.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment