How to fork a theme

Potentially outdated
This post is older than 365 days and may be outdated. Please use the site-search to search for updated information.
Hello Pagekiteers,
today I am going to show you, how to fork and customize a theme.
Why should I do that?
The Pagekit marketplace contains some really nice themes. But I'm sure that you would like to be something special. Adding custom colors, custom fonts and some JS can be done with spqr/assets, too, but if you would like to change a lot, you should consider to create your own theme.
Some of you may ask: "I am using theme-one
and if I would like to change something, I simply edit the theme's css".
But: This is not the best idea! Let's assume the creator of the theme releases a security-related update. If you update your theme, all your changes might be lost. If you don't update your theme, your website could be successfully attacked.
So there's another possibility: Forking the theme.
Forking?
Yes - forking. Forking is a term used in software development. It simply means that you are not only cloning the software - you are creating your own git repository for it. You can change whatever you want; in some cases forks are being merged with the original repositories (e.g. if you are forking something to add a bugfix or add new functionality) - in other cases you do not merge it (e.g. if you are changing something just for customization).
Let's go
In this tutorial we are using GitHub to create a fork of theme-one
. You only need to visit https://github.com/pagekit/theme-one .
Now click the "Fork" button and choose your own user as the "fork-target". You may need an account - but don't worry: It's free.
Alright - GitHub is now forking the project - this can take some seconds.
Once GitHub forked your repository, you can see an overview of all the files.
Now you are able to change the files online - or, which I prefer, clone the repository and edit it with an IDE.
Cloning the repository
I am using PHPStorm as it's a great IDE for PHP projects, which uses a built-in git client.
Of course you can use every editor you want - you don't even have to use git (although I really advise to use git).
If you don't want to use git at all, you can simply download the files; in this case you don't have to create a fork, too.
If you decide to fork the theme and clone it, you need to know the URL of the repository. If you don't know it, you can just look it up using GitHub's web frontend.
Just copy this URL and open your IDE.
In my case PHPStorm is able to create a new project from git.
Just click "Check out from version control" and click "GitHub" after that.
Now enter the git URL and decide, where you want your theme to be stored.
Now open the project.
Alright - you successfully forked the theme and cloned it on your local machine.
First steps
Once you opened your project, you can see all the files that have been cloned. And you are ready to edit them.
At first, we will have a look at composer.json
.
This file contains all the information about our package
. You might mention that this file contains all the information the original package provided. It got the same name, the same author information etc. Let's change this to:
{
"name": "spqr/theme-two",
"type": "pagekit-theme",
"version": "0.0.1",
"title": "Two",
"description": "SPQR's default theme fork.",
"license": "MIT",
"authors": [
{
"name": "Roman Lossin-Beßler",
"email": "[javascript protected email address]",
"homepage": "https://spqr.wtf"
}
],
"extra": {
"image": "image.jpg"
},
"archive": {
"exclude": ["node_modules", "!/app", "!/css", "/app/assets", "gulpfile.js", "bower.js", "package.js"]
}
}
As you can see, we named the theme theme-two
and changed the vendor prefix
from pagekit
to spqr
. If you are creating your own fork, you would not use spqr
- of course you would use your own vendor prefix (e.g. thomasb
or frankenstein
).
Now save the file and switch over to the file called bower.json
.
Change the content to:
{
"name": "theme-two",
"dependencies": {
"uikit": "#master"
},
"private": true
}
Did you already save the file? Fine - now open package.json
and change the content to:
{
"name": "pagekit-theme-two",
"scripts": {
"install": "bower install && gulp",
"archive": "gulp && webpack -p && composer archive --format=zip"
},
"devDependencies": {
"babel-core": "^6.1.2",
"babel-loader": "^6.1.0",
"babel-plugin-transform-runtime": "^6.1.2",
"babel-preset-es2015": "^6.1.2",
"babel-runtime": "^5.8.0",
"bower": "^1.7.6",
"json-loader": "^0.5.2",
"gulp": "^3.8.10",
"gulp-header": "^1.2.2",
"gulp-less": "^3.0.0",
"gulp-rename": "^1.2.0",
"gulp-util": "^3.0.4",
"merge-stream": "^0.1.7",
"vue-html-loader": "^1.0.0",
"vue-loader": "^8.2.0",
"webpack": "^1.12.9"
}
}
We are almost ready for takeoff - but we need to edit gulpfile.js
before.
Change it to:
/**
* Popular Tasks
* -------------
*
* compile: compiles the .less files of the specified packages
* lint: runs jshint on all .js files
*/
var gulp = require('gulp'),
header = require('gulp-header'),
less = require('gulp-less'),
rename = require('gulp-rename');
// banner for the css files
var banner = "/*! <%= data.title %> <%= data.version %> | (c) 2014 Pagekit | MIT License */\n";
gulp.task('default', ['compile']);
/**
* Compile all less files
*/
gulp.task('compile', function () {
return gulp.src('src/less/theme.less', {base: __dirname})
.pipe(less({compress: true}))
.pipe(header(banner, { data: require('./package.json') }))
.pipe(rename(function (file) {
// the compiled less file should be stored in the css/ folder instead of the less/ folder
file.dirname = file.dirname.replace('less', 'css');
}))
.pipe(gulp.dest(__dirname));
});
/**
* Watch for changes in files
*/
gulp.task('watch', function () {
gulp.watch('less/*.less', ['compile']);
});
Please take care of the path name. I changed it from
return gulp.src('less/theme.less', {base: __dirname})
to
return gulp.src('src/less/theme.less', {base: __dirname})
The last step is to open index.php
and change the content to:
<?php
return [
'name' => 'theme-two',
/**
* Menu positions
*/
'menus' => [
'main' => 'Main',
'offcanvas' => 'Offcanvas'
],
/**
* Widget positions
*/
'positions' => [
'navbar' => 'Navbar',
'hero' => 'Hero',
'top' => 'Top',
'sidebar' => 'Sidebar',
'bottom' => 'Bottom',
'footer' => 'Footer',
'offcanvas' => 'Offcanvas'
],
/**
* Node defaults
*/
'node' => [
'title_hide' => false,
'title_large' => false,
'alignment' => '',
'html_class' => '',
'sidebar_first' => false,
'hero_image' => '',
'hero_viewport' => '',
'hero_contrast' => '',
'hero_parallax' => '',
'navbar_transparent' => '',
'top_style' => 'uk-block-muted',
'main_style' => 'uk-block-default',
'bottom_style' => 'uk-block-muted'
],
/**
* Widget defaults
*/
'widget' => [
'title_hide' => false,
'title_size' => 'uk-panel-title',
'alignment' => '',
'html_class' => '',
'panel' => ''
],
/**
* Settings url
*/
'settings' => '@site/settings#site-theme',
/**
* Configuration defaults
*/
'config' => [
'logo_contrast' => '',
'logo_offcanvas' => ''
],
/**
* Events
*/
'events' => [
'view.system/site/admin/settings' => function ($event, $view) use ($app) {
$view->script('site-theme', 'theme:app/bundle/site-theme.js', 'site-settings');
$view->data('$theme', $this);
},
'view.system/site/admin/edit' => function ($event, $view) {
$view->script('node-theme', 'theme:app/bundle/node-theme.js', 'site-edit');
},
'view.system/widget/edit' => function ($event, $view) {
$view->script('widget-theme', 'theme:app/bundle/widget-theme.js', 'widget-edit');
},
/**
* Custom markup calculations based on theme settings
*/
'view.layout' => function ($event, $view) use ($app) {
if ($app->isAdmin()) {
return;
}
$params = $view->params;
$classes = [
'navbar' => 'tm-navbar',
'hero' => '',
'parallax' => ''
];
$sticky = [
'media' => 767,
'showup' => true,
'animation' => 'uk-animation-slide-top'
];
if ($params['hero_viewport']) {
$classes['hero'] = 'tm-hero-height';
}
// Sticky overlay navbar if hero position exists
if ($params['navbar_transparent'] && $view->position()->exists('hero') && $params['hero_image']) {
$sticky['top'] = '.uk-sticky-placeholder + *';
$classes['navbar'] .= ' tm-navbar-overlay tm-navbar-transparent';
if ($params['hero_viewport']) {
$classes['hero'] = 'uk-height-viewport';
} else {
$classes['hero'] = 'tm-hero-padding';
}
if ($params['hero_contrast']) {
$sticky['clsinactive'] = 'tm-navbar-transparent tm-navbar-contrast';
$classes['navbar'] .= ' tm-navbar-contrast';
} else {
$sticky['clsinactive'] = 'tm-navbar-transparent';
}
}
if ($params['hero_parallax'] && $view->position()->exists('hero') && $params['hero_image']) {
$classes['parallax'] = 'data-uk-parallax="{bg: \'-400\'}"';
}
if ($params['hero_contrast'] && $params['hero_image']) {
$classes['hero'] .= ' uk-contrast';
}
$classes['sticky'] = 'data-uk-sticky=\''.json_encode($sticky).'\'';
$params['classes'] = $classes;
},
'view.system/site/widget-menu' => function ($event, $view) {
if ($event['widget']->position == 'navbar') {
$event->setTemplate('menu-navbar.php');
}
}
]
];
Let's do something magic
Now we need to "compile" all the LESS, SASS and JavaScript: We are using webpack, gulp and bower to get this job done. Please install NodeJS on your computer, switch over to the theme's directory and run npm install
.
This installs all the packages the theme needs to be "compiled" - these packages are defined in package.json
.
Once this is done, just enter bower install
. This fetches the latest UIKit LESS
-files and should not take that much time.
Now simply run gulp
.
We are almost done - the last step is to run webpack
.
Prepare
Now you are good to go. You can now build a zip to upload the files.
Please exclude the following files and folders from zip:
- .git
- .idea (if you are using PHPStorm)
- node_modules
- app/components
- app/assets/uikit/src
- less
You can build your theme.zip
easily using PHPStorm - or do it manually. If you are using PHPStorm, just choose Tools > Deployment > Configuration and create a local deployment path.
Have a look at my configuration:
Now you are good to go to create your zip.
Upload the theme
Now enter the admin backend and enter System > Themes and choose "Upload".
Customize theme
Of course you are able to edit the settings of your new theme:
Uff - that's it
Took a while - but now we're ready.
Now you can adapt the theme over and over again. Always do the following:
- Change the
LESS
-sources - Run
gulp
- Deploy & build archive
- Upload zip
{{ 'Comments (%count%)' | trans {count:count} }}
{{ 'Comments are closed.' | trans }}