Initial import
v1 of Vue.js-based site
18
.babelrc
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"modules": false,
|
||||
"targets": {
|
||||
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
|
||||
}
|
||||
}],
|
||||
"stage-2"
|
||||
],
|
||||
"plugins": ["transform-runtime"],
|
||||
"env": {
|
||||
"test": {
|
||||
"presets": ["env", "stage-2"],
|
||||
"plugins": ["istanbul"]
|
||||
}
|
||||
}
|
||||
}
|
9
.editorconfig
Normal file
@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
2
.eslintignore
Normal file
@ -0,0 +1,2 @@
|
||||
build/*.js
|
||||
config/*.js
|
27
.eslintrc.js
Normal file
@ -0,0 +1,27 @@
|
||||
// http://eslint.org/docs/user-guide/configuring
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: 'babel-eslint',
|
||||
parserOptions: {
|
||||
sourceType: 'module'
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
},
|
||||
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
|
||||
extends: 'standard',
|
||||
// required to lint *.vue files
|
||||
plugins: [
|
||||
'html'
|
||||
],
|
||||
// add your custom rules here
|
||||
'rules': {
|
||||
// allow paren-less arrow functions
|
||||
'arrow-parens': 0,
|
||||
// allow async-await
|
||||
'generator-star-spacing': 0,
|
||||
// allow debugger during development
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
|
||||
}
|
||||
}
|
16
.gitignore
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
dist/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
test/unit/coverage
|
||||
test/e2e/reports
|
||||
selenium-debug.log
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
8
.postcssrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||
|
||||
module.exports = {
|
||||
"plugins": {
|
||||
// to edit target browsers: use "browserslist" field in package.json
|
||||
"autoprefixer": {}
|
||||
}
|
||||
}
|
35
build/build.js
Normal file
@ -0,0 +1,35 @@
|
||||
require('./check-versions')()
|
||||
|
||||
process.env.NODE_ENV = 'production'
|
||||
|
||||
var ora = require('ora')
|
||||
var rm = require('rimraf')
|
||||
var path = require('path')
|
||||
var chalk = require('chalk')
|
||||
var webpack = require('webpack')
|
||||
var config = require('../config')
|
||||
var webpackConfig = require('./webpack.prod.conf')
|
||||
|
||||
var spinner = ora('building for production...')
|
||||
spinner.start()
|
||||
|
||||
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
|
||||
if (err) throw err
|
||||
webpack(webpackConfig, function (err, stats) {
|
||||
spinner.stop()
|
||||
if (err) throw err
|
||||
process.stdout.write(stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
chunkModules: false
|
||||
}) + '\n\n')
|
||||
|
||||
console.log(chalk.cyan(' Build complete.\n'))
|
||||
console.log(chalk.yellow(
|
||||
' Tip: built files are meant to be served over an HTTP server.\n' +
|
||||
' Opening index.html over file:// won\'t work.\n'
|
||||
))
|
||||
})
|
||||
})
|
48
build/check-versions.js
Normal file
@ -0,0 +1,48 @@
|
||||
var chalk = require('chalk')
|
||||
var semver = require('semver')
|
||||
var packageConfig = require('../package.json')
|
||||
var shell = require('shelljs')
|
||||
function exec (cmd) {
|
||||
return require('child_process').execSync(cmd).toString().trim()
|
||||
}
|
||||
|
||||
var versionRequirements = [
|
||||
{
|
||||
name: 'node',
|
||||
currentVersion: semver.clean(process.version),
|
||||
versionRequirement: packageConfig.engines.node
|
||||
},
|
||||
]
|
||||
|
||||
if (shell.which('npm')) {
|
||||
versionRequirements.push({
|
||||
name: 'npm',
|
||||
currentVersion: exec('npm --version'),
|
||||
versionRequirement: packageConfig.engines.npm
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
var warnings = []
|
||||
for (var i = 0; i < versionRequirements.length; i++) {
|
||||
var mod = versionRequirements[i]
|
||||
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
|
||||
warnings.push(mod.name + ': ' +
|
||||
chalk.red(mod.currentVersion) + ' should be ' +
|
||||
chalk.green(mod.versionRequirement)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (warnings.length) {
|
||||
console.log('')
|
||||
console.log(chalk.yellow('To use this template, you must update following to modules:'))
|
||||
console.log()
|
||||
for (var i = 0; i < warnings.length; i++) {
|
||||
var warning = warnings[i]
|
||||
console.log(' ' + warning)
|
||||
}
|
||||
console.log()
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
9
build/dev-client.js
Normal file
@ -0,0 +1,9 @@
|
||||
/* eslint-disable */
|
||||
require('eventsource-polyfill')
|
||||
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
|
||||
|
||||
hotClient.subscribe(function (event) {
|
||||
if (event.action === 'reload') {
|
||||
window.location.reload()
|
||||
}
|
||||
})
|
92
build/dev-server.js
Normal file
@ -0,0 +1,92 @@
|
||||
require('./check-versions')()
|
||||
|
||||
var config = require('../config')
|
||||
if (!process.env.NODE_ENV) {
|
||||
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
|
||||
}
|
||||
|
||||
var opn = require('opn')
|
||||
var path = require('path')
|
||||
var express = require('express')
|
||||
var webpack = require('webpack')
|
||||
var proxyMiddleware = require('http-proxy-middleware')
|
||||
var webpackConfig = process.env.NODE_ENV === 'testing'
|
||||
? require('./webpack.prod.conf')
|
||||
: require('./webpack.dev.conf')
|
||||
|
||||
// default port where dev server listens for incoming traffic
|
||||
var port = process.env.PORT || config.dev.port
|
||||
// automatically open browser, if not set will be false
|
||||
var autoOpenBrowser = !!config.dev.autoOpenBrowser
|
||||
// Define HTTP proxies to your custom API backend
|
||||
// https://github.com/chimurai/http-proxy-middleware
|
||||
var proxyTable = config.dev.proxyTable
|
||||
|
||||
var app = express()
|
||||
var compiler = webpack(webpackConfig)
|
||||
|
||||
var devMiddleware = require('webpack-dev-middleware')(compiler, {
|
||||
publicPath: webpackConfig.output.publicPath,
|
||||
quiet: true
|
||||
})
|
||||
|
||||
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
|
||||
log: () => {},
|
||||
heartbeat: 2000
|
||||
})
|
||||
// force page reload when html-webpack-plugin template changes
|
||||
compiler.plugin('compilation', function (compilation) {
|
||||
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
|
||||
hotMiddleware.publish({ action: 'reload' })
|
||||
cb()
|
||||
})
|
||||
})
|
||||
|
||||
// proxy api requests
|
||||
Object.keys(proxyTable).forEach(function (context) {
|
||||
var options = proxyTable[context]
|
||||
if (typeof options === 'string') {
|
||||
options = { target: options }
|
||||
}
|
||||
app.use(proxyMiddleware(options.filter || context, options))
|
||||
})
|
||||
|
||||
// handle fallback for HTML5 history API
|
||||
app.use(require('connect-history-api-fallback')())
|
||||
|
||||
// serve webpack bundle output
|
||||
app.use(devMiddleware)
|
||||
|
||||
// enable hot-reload and state-preserving
|
||||
// compilation error display
|
||||
app.use(hotMiddleware)
|
||||
|
||||
// serve pure static assets
|
||||
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
|
||||
app.use(staticPath, express.static('./static'))
|
||||
|
||||
var uri = 'http://localhost:' + port
|
||||
|
||||
var _resolve
|
||||
var readyPromise = new Promise(resolve => {
|
||||
_resolve = resolve
|
||||
})
|
||||
|
||||
console.log('> Starting dev server...')
|
||||
devMiddleware.waitUntilValid(() => {
|
||||
console.log('> Listening at ' + uri + '\n')
|
||||
// when env is testing, don't need open it
|
||||
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
|
||||
opn(uri)
|
||||
}
|
||||
_resolve()
|
||||
})
|
||||
|
||||
var server = app.listen(port)
|
||||
|
||||
module.exports = {
|
||||
ready: readyPromise,
|
||||
close: () => {
|
||||
server.close()
|
||||
}
|
||||
}
|
71
build/utils.js
Normal file
@ -0,0 +1,71 @@
|
||||
var path = require('path')
|
||||
var config = require('../config')
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
|
||||
exports.assetsPath = function (_path) {
|
||||
var assetsSubDirectory = process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsSubDirectory
|
||||
: config.dev.assetsSubDirectory
|
||||
return path.posix.join(assetsSubDirectory, _path)
|
||||
}
|
||||
|
||||
exports.cssLoaders = function (options) {
|
||||
options = options || {}
|
||||
|
||||
var cssLoader = {
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
minimize: process.env.NODE_ENV === 'production',
|
||||
sourceMap: options.sourceMap
|
||||
}
|
||||
}
|
||||
|
||||
// generate loader string to be used with extract text plugin
|
||||
function generateLoaders (loader, loaderOptions) {
|
||||
var loaders = [cssLoader]
|
||||
if (loader) {
|
||||
loaders.push({
|
||||
loader: loader + '-loader',
|
||||
options: Object.assign({}, loaderOptions, {
|
||||
sourceMap: options.sourceMap
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Extract CSS when that option is specified
|
||||
// (which is the case during production build)
|
||||
if (options.extract) {
|
||||
return ExtractTextPlugin.extract({
|
||||
use: loaders,
|
||||
fallback: 'vue-style-loader'
|
||||
})
|
||||
} else {
|
||||
return ['vue-style-loader'].concat(loaders)
|
||||
}
|
||||
}
|
||||
|
||||
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
|
||||
return {
|
||||
css: generateLoaders(),
|
||||
postcss: generateLoaders(),
|
||||
less: generateLoaders('less'),
|
||||
sass: generateLoaders('sass', { indentedSyntax: true }),
|
||||
scss: generateLoaders('sass'),
|
||||
stylus: generateLoaders('stylus'),
|
||||
styl: generateLoaders('stylus')
|
||||
}
|
||||
}
|
||||
|
||||
// Generate loaders for standalone style files (outside of .vue)
|
||||
exports.styleLoaders = function (options) {
|
||||
var output = []
|
||||
var loaders = exports.cssLoaders(options)
|
||||
for (var extension in loaders) {
|
||||
var loader = loaders[extension]
|
||||
output.push({
|
||||
test: new RegExp('\\.' + extension + '$'),
|
||||
use: loader
|
||||
})
|
||||
}
|
||||
return output
|
||||
}
|
18
build/vue-loader.conf.js
Normal file
@ -0,0 +1,18 @@
|
||||
var utils = require('./utils')
|
||||
var config = require('../config')
|
||||
var isProduction = process.env.NODE_ENV === 'production'
|
||||
|
||||
module.exports = {
|
||||
loaders: utils.cssLoaders({
|
||||
sourceMap: isProduction
|
||||
? config.build.productionSourceMap
|
||||
: config.dev.cssSourceMap,
|
||||
extract: isProduction
|
||||
}),
|
||||
transformToRequire: {
|
||||
video: 'src',
|
||||
source: 'src',
|
||||
img: 'src',
|
||||
image: 'xlink:href'
|
||||
}
|
||||
}
|
75
build/webpack.base.conf.js
Normal file
@ -0,0 +1,75 @@
|
||||
var path = require('path')
|
||||
var utils = require('./utils')
|
||||
var config = require('../config')
|
||||
var vueLoaderConfig = require('./vue-loader.conf')
|
||||
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, '..', dir)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
app: './src/main.js'
|
||||
},
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: '[name].js',
|
||||
publicPath: process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsPublicPath
|
||||
: config.dev.assetsPublicPath
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
alias: {
|
||||
'vue$': 'vue/dist/vue.esm.js',
|
||||
'@': resolve('src')
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|vue)$/,
|
||||
loader: 'eslint-loader',
|
||||
enforce: 'pre',
|
||||
include: [resolve('src'), resolve('test')],
|
||||
options: {
|
||||
formatter: require('eslint-friendly-formatter')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderConfig
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
include: [resolve('src'), resolve('test')]
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('img/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('media/[name].[hash:7].[ext]')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
35
build/webpack.dev.conf.js
Normal file
@ -0,0 +1,35 @@
|
||||
var utils = require('./utils')
|
||||
var webpack = require('webpack')
|
||||
var config = require('../config')
|
||||
var merge = require('webpack-merge')
|
||||
var baseWebpackConfig = require('./webpack.base.conf')
|
||||
var HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
||||
|
||||
// add hot-reload related code to entry chunks
|
||||
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
|
||||
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
|
||||
})
|
||||
|
||||
module.exports = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
|
||||
},
|
||||
// cheap-module-eval-source-map is faster for development
|
||||
devtool: '#cheap-module-eval-source-map',
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': config.dev.env
|
||||
}),
|
||||
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
// https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: 'index.html',
|
||||
template: 'index.html',
|
||||
inject: true
|
||||
}),
|
||||
new FriendlyErrorsPlugin()
|
||||
]
|
||||
})
|
124
build/webpack.prod.conf.js
Normal file
@ -0,0 +1,124 @@
|
||||
var path = require('path')
|
||||
var utils = require('./utils')
|
||||
var webpack = require('webpack')
|
||||
var config = require('../config')
|
||||
var merge = require('webpack-merge')
|
||||
var baseWebpackConfig = require('./webpack.base.conf')
|
||||
var CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
var HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
|
||||
var env = process.env.NODE_ENV === 'testing'
|
||||
? require('../config/test.env')
|
||||
: config.build.env
|
||||
|
||||
var webpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
extract: true
|
||||
})
|
||||
},
|
||||
devtool: config.build.productionSourceMap ? '#source-map' : false,
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: utils.assetsPath('js/[name].[chunkhash].js'),
|
||||
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
|
||||
},
|
||||
plugins: [
|
||||
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': env
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compress: {
|
||||
warnings: false
|
||||
},
|
||||
sourceMap: true
|
||||
}),
|
||||
// extract css into its own file
|
||||
new ExtractTextPlugin({
|
||||
filename: utils.assetsPath('css/[name].[contenthash].css')
|
||||
}),
|
||||
// Compress extracted CSS. We are using this plugin so that possible
|
||||
// duplicated CSS from different components can be deduped.
|
||||
new OptimizeCSSPlugin({
|
||||
cssProcessorOptions: {
|
||||
safe: true
|
||||
}
|
||||
}),
|
||||
// generate dist index.html with correct asset hash for caching.
|
||||
// you can customize output by editing /index.html
|
||||
// see https://github.com/ampedandwired/html-webpack-plugin
|
||||
new HtmlWebpackPlugin({
|
||||
filename: process.env.NODE_ENV === 'testing'
|
||||
? 'index.html'
|
||||
: config.build.index,
|
||||
template: 'index.html',
|
||||
inject: true,
|
||||
minify: {
|
||||
removeComments: true,
|
||||
collapseWhitespace: true,
|
||||
removeAttributeQuotes: true
|
||||
// more options:
|
||||
// https://github.com/kangax/html-minifier#options-quick-reference
|
||||
},
|
||||
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
|
||||
chunksSortMode: 'dependency'
|
||||
}),
|
||||
// split vendor js into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'vendor',
|
||||
minChunks: function (module, count) {
|
||||
// any required modules inside node_modules are extracted to vendor
|
||||
return (
|
||||
module.resource &&
|
||||
/\.js$/.test(module.resource) &&
|
||||
module.resource.indexOf(
|
||||
path.join(__dirname, '../node_modules')
|
||||
) === 0
|
||||
)
|
||||
}
|
||||
}),
|
||||
// extract webpack runtime and module manifest to its own file in order to
|
||||
// prevent vendor hash from being updated whenever app bundle is updated
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'manifest',
|
||||
chunks: ['vendor']
|
||||
}),
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
to: config.build.assetsSubDirectory,
|
||||
ignore: ['.*']
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
|
||||
if (config.build.productionGzip) {
|
||||
var CompressionWebpackPlugin = require('compression-webpack-plugin')
|
||||
|
||||
webpackConfig.plugins.push(
|
||||
new CompressionWebpackPlugin({
|
||||
asset: '[path].gz[query]',
|
||||
algorithm: 'gzip',
|
||||
test: new RegExp(
|
||||
'\\.(' +
|
||||
config.build.productionGzipExtensions.join('|') +
|
||||
')$'
|
||||
),
|
||||
threshold: 10240,
|
||||
minRatio: 0.8
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (config.build.bundleAnalyzerReport) {
|
||||
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
||||
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
|
||||
}
|
||||
|
||||
module.exports = webpackConfig
|
31
build/webpack.test.conf.js
Normal file
@ -0,0 +1,31 @@
|
||||
// This is the webpack config used for unit tests.
|
||||
|
||||
var utils = require('./utils')
|
||||
var webpack = require('webpack')
|
||||
var merge = require('webpack-merge')
|
||||
var baseConfig = require('./webpack.base.conf')
|
||||
|
||||
var webpackConfig = merge(baseConfig, {
|
||||
// use inline sourcemap for karma-sourcemap-loader
|
||||
module: {
|
||||
rules: utils.styleLoaders()
|
||||
},
|
||||
devtool: '#inline-source-map',
|
||||
resolveLoader: {
|
||||
alias: {
|
||||
// necessary to to make lang="scss" work in test when using vue-loader's ?inject option
|
||||
// see discussion at https://github.com/vuejs/vue-loader/issues/724
|
||||
'scss-loader': 'sass-loader'
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': require('../config/test.env')
|
||||
})
|
||||
]
|
||||
})
|
||||
|
||||
// no need for app entry during tests
|
||||
delete webpackConfig.entry
|
||||
|
||||
module.exports = webpackConfig
|
6
config/dev.env.js
Normal file
@ -0,0 +1,6 @@
|
||||
var merge = require('webpack-merge')
|
||||
var prodEnv = require('./prod.env')
|
||||
|
||||
module.exports = merge(prodEnv, {
|
||||
NODE_ENV: '"development"'
|
||||
})
|
38
config/index.js
Normal file
@ -0,0 +1,38 @@
|
||||
// see http://vuejs-templates.github.io/webpack for documentation.
|
||||
var path = require('path')
|
||||
|
||||
module.exports = {
|
||||
build: {
|
||||
env: require('./prod.env'),
|
||||
index: path.resolve(__dirname, '../dist/index.html'),
|
||||
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
productionSourceMap: true,
|
||||
// Gzip off by default as many popular static hosts such as
|
||||
// Surge or Netlify already gzip all static assets for you.
|
||||
// Before setting to `true`, make sure to:
|
||||
// npm install --save-dev compression-webpack-plugin
|
||||
productionGzip: false,
|
||||
productionGzipExtensions: ['js', 'css'],
|
||||
// Run the build command with an extra argument to
|
||||
// View the bundle analyzer report after build finishes:
|
||||
// `npm run build --report`
|
||||
// Set to `true` or `false` to always turn it on or off
|
||||
bundleAnalyzerReport: process.env.npm_config_report
|
||||
},
|
||||
dev: {
|
||||
env: require('./dev.env'),
|
||||
port: 8080,
|
||||
autoOpenBrowser: true,
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
proxyTable: {},
|
||||
// CSS Sourcemaps off by default because relative paths are "buggy"
|
||||
// with this option, according to the CSS-Loader README
|
||||
// (https://github.com/webpack/css-loader#sourcemaps)
|
||||
// In our experience, they generally work as expected,
|
||||
// just be aware of this issue when enabling this option.
|
||||
cssSourceMap: false
|
||||
}
|
||||
}
|
3
config/prod.env.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
NODE_ENV: '"production"'
|
||||
}
|
6
config/test.env.js
Normal file
@ -0,0 +1,6 @@
|
||||
var merge = require('webpack-merge')
|
||||
var devEnv = require('./dev.env')
|
||||
|
||||
module.exports = merge(devEnv, {
|
||||
NODE_ENV: '"testing"'
|
||||
})
|
13
index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>DJS Consulting</title>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/static/favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
10810
package-lock.json
generated
Normal file
95
package.json
Normal file
@ -0,0 +1,95 @@
|
||||
{
|
||||
"name": "djs-consulting",
|
||||
"version": "1.0.0",
|
||||
"description": "DJS Consulting Main Web Site",
|
||||
"author": "Daniel J. Summers <daniel@djs-consulting.com>",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "node build/dev-server.js",
|
||||
"start": "node build/dev-server.js",
|
||||
"build": "node build/build.js",
|
||||
"unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
|
||||
"e2e": "node test/e2e/runner.js",
|
||||
"test": "npm run unit && npm run e2e",
|
||||
"lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^2.3.3",
|
||||
"vue-router": "^2.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^7.1.2",
|
||||
"babel-core": "^6.22.1",
|
||||
"babel-eslint": "^7.1.1",
|
||||
"babel-loader": "^7.1.1",
|
||||
"babel-plugin-transform-runtime": "^6.22.0",
|
||||
"babel-preset-env": "^1.3.2",
|
||||
"babel-preset-stage-2": "^6.22.0",
|
||||
"babel-register": "^6.22.0",
|
||||
"chalk": "^2.0.1",
|
||||
"connect-history-api-fallback": "^1.3.0",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.28.0",
|
||||
"cssnano": "^3.10.0",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-friendly-formatter": "^3.0.0",
|
||||
"eslint-loader": "^1.7.1",
|
||||
"eslint-plugin-html": "^3.0.0",
|
||||
"eslint-config-standard": "^6.2.1",
|
||||
"eslint-plugin-promise": "^3.4.0",
|
||||
"eslint-plugin-standard": "^2.0.1",
|
||||
"eventsource-polyfill": "^0.9.6",
|
||||
"express": "^4.14.1",
|
||||
"extract-text-webpack-plugin": "^2.0.0",
|
||||
"file-loader": "^0.11.1",
|
||||
"friendly-errors-webpack-plugin": "^1.1.3",
|
||||
"html-webpack-plugin": "^2.28.0",
|
||||
"http-proxy-middleware": "^0.17.3",
|
||||
"webpack-bundle-analyzer": "^2.2.1",
|
||||
"cross-env": "^5.0.1",
|
||||
"karma": "^1.4.1",
|
||||
"karma-coverage": "^1.1.1",
|
||||
"karma-mocha": "^1.3.0",
|
||||
"karma-phantomjs-launcher": "^1.0.2",
|
||||
"karma-phantomjs-shim": "^1.4.0",
|
||||
"karma-sinon-chai": "^1.3.1",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-spec-reporter": "0.0.31",
|
||||
"karma-webpack": "^2.0.2",
|
||||
"lolex": "^1.5.2",
|
||||
"mocha": "^3.2.0",
|
||||
"chai": "^3.5.0",
|
||||
"sinon": "^2.1.0",
|
||||
"sinon-chai": "^2.8.0",
|
||||
"inject-loader": "^3.0.0",
|
||||
"babel-plugin-istanbul": "^4.1.1",
|
||||
"phantomjs-prebuilt": "^2.1.14",
|
||||
"chromedriver": "^2.27.2",
|
||||
"cross-spawn": "^5.0.1",
|
||||
"nightwatch": "^0.9.12",
|
||||
"selenium-server": "^3.0.1",
|
||||
"semver": "^5.3.0",
|
||||
"shelljs": "^0.7.6",
|
||||
"opn": "^5.1.0",
|
||||
"optimize-css-assets-webpack-plugin": "^2.0.0",
|
||||
"ora": "^1.2.0",
|
||||
"rimraf": "^2.6.0",
|
||||
"url-loader": "^0.5.8",
|
||||
"vue-loader": "^12.1.0",
|
||||
"vue-style-loader": "^3.0.1",
|
||||
"vue-template-compiler": "^2.3.3",
|
||||
"webpack": "^2.6.1",
|
||||
"webpack-dev-middleware": "^1.10.0",
|
||||
"webpack-hot-middleware": "^2.18.0",
|
||||
"webpack-merge": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
130
src/App.vue
Normal file
@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<header>
|
||||
<router-link to="/">
|
||||
<img src="/static/djs-consulting.png" alt="DJS Consulting" title="DJS Consulting" />
|
||||
</router-link>
|
||||
<img src="/static/slogan.png" alt="Your Web Design, Hosting, and Application Solution Source"
|
||||
title="Your web design, hosting, and application solution source!" />
|
||||
<span> </span>
|
||||
</header>
|
||||
<div id="content">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<footer>
|
||||
<span>A <strong><a href="/">DJS Consulting</a></strong> original design</span>
|
||||
<span style="flex-grow:3;"> </span>
|
||||
<span>Secured by <strong><a href="//letsencrypt.org">Let's Encrypt</a></strong></span>
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'app'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css?family=Play:400,700|Source+Sans+Pro:400,400i,700');
|
||||
body {
|
||||
margin: 0px;
|
||||
font-family: "Source Sans Pro", "Segoe UI", Ubuntu, Tahoma, "DejaVu Sans", "Liberation Sans", Arial, sans-serif;
|
||||
background-color: #FFFAFA;
|
||||
}
|
||||
a {
|
||||
color: navy;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
border-bottom: dotted 1px navy;
|
||||
}
|
||||
a img {
|
||||
border:0;
|
||||
}
|
||||
acronym {
|
||||
border-bottom:dotted 1px black;
|
||||
}
|
||||
h1, h2, h3, footer {
|
||||
font-family: "Play", "Segoe UI", Ubuntu, "DejaVu Sans", "Liberation Sans", Arial, sans-serif;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin: 21px 0;
|
||||
font-size: 24pt;
|
||||
}
|
||||
h2 {
|
||||
margin: 19px 0;
|
||||
width: 80%;
|
||||
border-bottom: solid 2px navy;
|
||||
}
|
||||
p {
|
||||
margin: 16px 0;
|
||||
}
|
||||
#content {
|
||||
margin: 0 15px;
|
||||
font-size: 1.05em;
|
||||
}
|
||||
.hdr {
|
||||
font-size: 14pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
.valid_img {
|
||||
width: 88px;
|
||||
height: 31px;
|
||||
border: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
height: 70px;
|
||||
border-bottom:solid 2px #3A1D00;
|
||||
background: #FFE88E;
|
||||
}
|
||||
header a:hover {
|
||||
border-bottom:none;
|
||||
}
|
||||
.content-item {
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
font-size: 12pt;
|
||||
}
|
||||
article.page .metadata {
|
||||
display: none;
|
||||
}
|
||||
.strike {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
footer {
|
||||
border-top: solid 5px #3A1D00;
|
||||
border-bottom: solid 1px #3A1D00;
|
||||
padding: 1px 15px 3px 15px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
/*text-align: right; */
|
||||
font-size: 1em;
|
||||
background-color: #FFE88E;
|
||||
color: black;
|
||||
clear: both;
|
||||
}
|
||||
footer a:link, footer a:visited {
|
||||
color: black;
|
||||
}
|
||||
footer a:hover {
|
||||
border-bottom: none;
|
||||
color: maroon;
|
||||
}
|
||||
.alignleft {
|
||||
float:left;
|
||||
padding-right: 5px;
|
||||
}
|
||||
ul {
|
||||
padding-left: 40px;
|
||||
}
|
||||
li {
|
||||
list-style-type: disc;
|
||||
}
|
||||
</style>
|
588
src/components/AppData.vue
Normal file
@ -0,0 +1,588 @@
|
||||
<script>
|
||||
const CATEGORIES = [
|
||||
{ id: 1, name: 'Web Sites and Applications' },
|
||||
{ id: 2, name: 'WordPress' },
|
||||
{ id: 3, name: 'Static Sites' },
|
||||
{ id: 4, name: 'Personal' }
|
||||
]
|
||||
const APPS = [
|
||||
{
|
||||
id: 'bay-vista',
|
||||
name: 'Bay Vista Baptist Church',
|
||||
url: 'https://bayvista.org',
|
||||
active: true,
|
||||
categoryId: 3,
|
||||
frontPageText: 'Biloxi, Mississippi',
|
||||
frontPageOrder: 1,
|
||||
indexText: 'Southern Baptist church in Biloxi, Mississippi',
|
||||
paragraphs: [
|
||||
`Bay Vista Baptist Church has served the spiritual needs of Mississippi‘s Gulf Coast for decades. They
|
||||
emphasize serving their community as well; they were a hub for
|
||||
<abbr title="Federal Emergency Management Agency">FEMA</abbr> during Hurricane Katrina relief and recovery
|
||||
efforts, and they are a relay point for each year’s
|
||||
<a href="https://www.samaritanspurse.org/what-we-do/operation-christmas-child/">Operation Christmas
|
||||
Child</a> campaign. As of late 2013, the authors of their current website were no longer around, and no one could
|
||||
get to the site to update it. We proposed setting up a site based on WordPress, where multiple people could have
|
||||
the ability to maintain the site, reducing the risk of that happening again. We also mentioned that such a site
|
||||
could also serve a sermon podcast feed, increasing the reach of their ministry.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did (2014)',
|
||||
narrative: `We manually downloaded all the publically-accessible parts of their old site, and used that content
|
||||
to create a WordPress-based site, updating a few outdated items along the way. We also established a
|
||||
podcast feed for their sermons. A few months after initially setting up the site, we updated the
|
||||
theme to be more mobile-friendly.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Did (2016)',
|
||||
narrative: `In the nearly three years since we had set up the site, we were the only ones updating it. We had
|
||||
recently migrated some older blogs to use the static site generator Jekyll, were impressed with the
|
||||
performance gains. We converted their site, to include writing a custom template to support the
|
||||
podcast feed; it is now generated along with the rest of the site.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: 'DJS Consulting hosts this site; we also publish sermons to their podcast feed weekly.'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'cassy-fiano',
|
||||
name: 'Cassy Fiano',
|
||||
url: 'http://www.cassyfiano.com',
|
||||
active: false,
|
||||
categoryId: 2,
|
||||
indexText: 'A “rising star” conservative blogger',
|
||||
paragraphs: [
|
||||
`Cassy Fiano (now Cassy Chesser) began blogging back in 2007 on Blogger. She worked hard to network with other
|
||||
bloggers, and wrote prolifically. As she approached the end of her first year of blogging, she was about to
|
||||
outgrow Blogger. She asked in a blog post if anyone had experience with Movable Type, the platform used by another
|
||||
blog to which she contributed. I replied that I did not, but that I had experience with WordPress.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did (2008)',
|
||||
narrative: `We assisted her with finding a theme, and customized that theme to contain the same sidebar elements
|
||||
as her current Blogger theme. We modified her old Blogger template to send people to her new blog
|
||||
(using redirection) after displaying a note that the blog had moved.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Did (2012)',
|
||||
narrative: `In July 2012, we began hosting the site, as well as continuing support for theme updates. This
|
||||
joined her military wife blog
|
||||
<a href="/applications/hard-corps-wife" title="Hard Corps Wife • DJS Consulting">Hard Corps
|
||||
Wife</a>, which we had begun hosting in mid-2011.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: `Cassy formally decommissioned this site in early 2014.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'daniel-j-summers',
|
||||
name: 'Daniel J. Summers',
|
||||
url: 'https://daniel.summershome.org',
|
||||
active: true,
|
||||
categoryId: 4,
|
||||
noAboutLink: true,
|
||||
frontPageText: 'Daniel’s personal blog',
|
||||
frontPageOrder: 1
|
||||
},
|
||||
{
|
||||
id: 'daniels-weekly-devotions',
|
||||
name: 'Daniel\'s Weekly Devotions',
|
||||
url: 'https://devotions.summershome.org',
|
||||
active: true,
|
||||
categoryId: 4,
|
||||
noAboutLink: true,
|
||||
frontPageText: 'A word from the Word each week',
|
||||
frontPageOrder: 2
|
||||
},
|
||||
{
|
||||
id: 'dr-melissa-clouthier',
|
||||
name: 'Dr. Melissa Clouthier',
|
||||
url: 'http://melissablogs.com',
|
||||
active: true,
|
||||
categoryId: 2,
|
||||
frontPageText: 'Information Pollination',
|
||||
frontPageOrder: 1,
|
||||
indexText: 'Politics, health, podcasts and more',
|
||||
paragraphs: [
|
||||
`Dr. Melissa Clouthier saw our work with
|
||||
<a href="/applications/cassy-fiano" title="Cassy Fiano • DJS Consulting">Cassy</a>’s site, and asked
|
||||
us to help her move off Blogger as well. Melissa blogs from the political right, but also covers health issues and
|
||||
social media. She had been blogging for a several years, and wanted to bring her old content with her to her new
|
||||
site.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did',
|
||||
narrative: `We created a custom theme based on another site, and developed graphics to complement that theme. We
|
||||
also imported the content from her Blogger site into the WordPress site, and created a featured
|
||||
content template for the front page.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: 'DJS Consulting continues to provide WordPress upgrades, backups, and theme tweaks.'
|
||||
}
|
||||
],
|
||||
footnotes: [
|
||||
`<em>(NOTE: The thumbnail of the site represents a new skin on the original theme; while the theme is the same,
|
||||
DJS Consulting did not create the graphics.)</em>`
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'emerald-mountain-christian-school',
|
||||
name: 'Emerald Mountain Christian School',
|
||||
url: 'http://www.emeraldmountainchristianschool.org',
|
||||
active: false,
|
||||
linkInactive: true,
|
||||
categoryId: 1,
|
||||
indexText: 'Classical, Christ-centered education near Wetumpka, Alabama',
|
||||
paragraphs: [
|
||||
`Emerald Mountain Christian School is a private Christian school founded over 50 years ago. They use the Principle
|
||||
Approach®, which emphasizes research, reasoning, relating, and recording to help students synthesize the
|
||||
information they learn, rather than just requiring rote memorization. More information about the school’s
|
||||
rich history can be found on their site.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did (2004)',
|
||||
narrative: `They had a website with very basic information and very little styling. We developed a theme (the
|
||||
one in the thumbnail), based in large part on the design of their printed materials, and they
|
||||
approved the design. Initially, the site only contained the content from their previous site. We then
|
||||
put their school calendar of events up on the site, where parents could find the dates for upcoming
|
||||
events. Finally, we put all the material from their Parent Information Packet online, which helped
|
||||
prospective families learn more about the school before visiting it.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Did (2011)',
|
||||
narrative: `The underlying engine of the basic website was switched from PHP to an ASP MVC web application, and
|
||||
the back-end database was switched from MySQL to a PostgreSQL database.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Did (2013)',
|
||||
narrative: `We passed off the content and hosting of the site to a new maintainer. They have since redesigned
|
||||
it; it is accessible via the URL above, and at
|
||||
<a href="http://emcspatriots.org" title="EMCS Patriots">EMCSpatriots.org</a>.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'futility-closet',
|
||||
name: 'Futility Closet',
|
||||
url: 'https://futilitycloset.com',
|
||||
active: true,
|
||||
categoryId: 2,
|
||||
frontPageText: 'An idler’s miscellany of compendious amusements',
|
||||
frontPageOrder: 2,
|
||||
indexText: 'An idler’s miscellany of compendious amusements',
|
||||
paragraphs: [
|
||||
`Futility Closet exists as a place to give people a break from the dullness of work, by providing puzzles,
|
||||
anecdotes, and more. It began on a shared host, but was growing too large and popular for that platform.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did',
|
||||
narrative: `We determined what the traffic requirements and size of the blog were, then made some
|
||||
recommendations. Greg Ross, the site author, decided on one of our recommendations. He had backups of
|
||||
the existing database, so we were able to set up a server and restore the data onto that new server.
|
||||
We configured WordPress and locked down the server, and this blog was moved quickly.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: `DJS Consulting still hosts Futility Closet, ensuring that the underlying server receives performance
|
||||
and security upgrades, monitoring site performance, and maintaining regular backups.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'hard-corps-wife',
|
||||
name: 'Hard Corps Wife',
|
||||
url: 'http://www.hardcorpswife.com',
|
||||
active: false,
|
||||
categoryId: 2,
|
||||
indexText: 'Cassy’s life as a Marine wife',
|
||||
paragraphs: [
|
||||
`Capitalizing on the growth from her Cassy Fiano blog, Cassy (now Chesser) began a separate blog in which she
|
||||
could chronicle her experience as a military spouse.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did',
|
||||
narrative: `We customized the header and sidebar of the theme, and set up the hardcorpswife.com domain.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: `In 2013, Cassy shifted priorities and closed this site down. She can still be found at other places
|
||||
around the web.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'liberty-pundits',
|
||||
name: 'Liberty Pundits',
|
||||
url: 'http://libertypundits.net',
|
||||
active: false,
|
||||
categoryId: 2,
|
||||
indexText: 'The home for conservatives',
|
||||
paragraphs: [
|
||||
`At its founding, Liberty Pundits was a joint venture by 3 established bloggers
|
||||
(<a href="http://melissablogs.com" title="Dr. Melissa Clouthier">Melissa Clouthier</a>, Bill Dupray, and Clyde
|
||||
Middleton) that, in their words, was aimed at becoming the new home for conservatives on the Internet. With the
|
||||
three of them all being prolific bloggers in their own right, and the help of many contributors, Liberty Pundits
|
||||
was a bustling hub of information.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did',
|
||||
narrative: `Bill and Clyde had been part of Patriot Room, an already-recognized powerhouse, and their desire was
|
||||
for Liberty Pundits to contain the content that they had contributed to Patriot Room. The technical
|
||||
lead on that blog had moved on, so we did some divining of what was there. Once we deduced the
|
||||
current setup, we obtained the data from that site, determined how it would need to be manipulated to
|
||||
become part of a WordPress blog, then accomplished the data migration. Initially, this was deployed
|
||||
on the same shared hosting account where LibertyPundits.com, their podcast distribution site, already
|
||||
resided. The site’s traffic quickly overwhelmed that solution. They then were moved by their
|
||||
host to a <abbr title="Virtual Private Server">VPS</abbr>, which performed moderately better, but
|
||||
still had quite a few issues, mostly related to the site’s traffic volume. We recommended a new
|
||||
server configuration, including migrating from a fully-featured web server to a more lightweight web
|
||||
server, along with caching, and configured that server. This configuration eliminated the
|
||||
bottlenecks, and enabled them to have several 100,000+ hit days with no appreciable slowdowns.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: `DJS Consulting maintained the server, keeping it current with performance and security upgrades. We
|
||||
also provided support to the primary 3 bloggers, when they had questions about WordPress or how the
|
||||
site was performing. The site closed in August of 2011, as the primary authors moved on to other
|
||||
endeavors.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'linux',
|
||||
name: 'Linux Resources',
|
||||
url: '/linux',
|
||||
active: true,
|
||||
categoryId: 1,
|
||||
noAboutLink: true,
|
||||
frontPageText: 'Handy information for Linux folks',
|
||||
frontPageOrder: 2
|
||||
},
|
||||
{
|
||||
id: 'mindy-mackenzie',
|
||||
name: 'Mindy Mackenzie',
|
||||
url: 'http://mindymackenzie.com',
|
||||
active: true,
|
||||
categoryId: 2,
|
||||
frontPageText: 'WSJ-best-selling author of The Courage Solution',
|
||||
frontPageOrder: 3,
|
||||
indexText: '<em>Wall Street Journal</em> best-selling author and C-suite advisor',
|
||||
paragraphs: [
|
||||
`Mindy Mackenzie, the prior Chief Performance Officer of Beam, Inc., is known as the “Velvet Hammer”
|
||||
for her tough-yet-caring style of leadership. Her <em>Wall Street Journal</em> best-selling book <em>The Courage
|
||||
Solution: The Power of Truth-Telling with Your Boss, Peers, and Team</em> details her spin-free approach to
|
||||
personal and business success.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did',
|
||||
narrative: `We assumed maintenance of her site in 2015, several months in advance of the book launch of <em>The
|
||||
Courage Solution</em>. We worked with her, and her publicists and other professionals, to ensure that
|
||||
the book launch went smoothly. We customized her WordPress installation to support her Media
|
||||
Appearances as a custom type, where they could be entered, tracked, and listed as of the date they
|
||||
occurred. We also implemented rotating videos on the front page of the site.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: 'We continue to provide backups, WordPress support, and content updates for Mindy’s site.'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'nsx',
|
||||
name: 'Not So Extreme Makeover: Community Edition',
|
||||
url: 'http://notsoextreme.org',
|
||||
active: false,
|
||||
archiveUrl: 'https://hosted.djs-consulting.com/archive/notsoextreme_org',
|
||||
categoryId: 1,
|
||||
indexText: 'Public site for the makeover; provides event-driven management of volunteers, donations, and families needing help',
|
||||
paragraphs: [
|
||||
`In January 2008, a few members of <a href="http://hoffmantown.org" title="Hoffmantown Church">Hoffmantown
|
||||
Church</a> in Albuquerque, New Mexico had an idea. The ABC show
|
||||
<em><a href="http://abc.go.com/shows/extreme-makeover-home-edition">Extreme Makeover: Home Edition</a></em> had
|
||||
just done
|
||||
<a href="http://abc.go.com/shows/extreme-makeover-home-edition/episode-detail/martinez-family/224884" title="Martinez Family • Extreme Makeover: Home Edition">a
|
||||
build for a pastor in the “war zone” area of town</a>, and this brought attention to Gerald Martinez
|
||||
and the work he had done to help clean up this area of town. Through
|
||||
<a href="http://www.loveincabq.org/" title="Love INC of South Albuquerque">Love INC of South Albuquerque</a>, they
|
||||
learned that there were many other homes in that area that could use the “Ty Pennington touch.” While
|
||||
the goal was not to knock down homes and build new ones, the goal was no less extreme. The goal of the “Not
|
||||
So Extreme Makeover: Community Edition” was to help 50 families in 5 days during spring break week in 2008.
|
||||
From an idea in January to 57 families helped by March 29th, it was an amazing whirlwind.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did',
|
||||
narrative: `The call went out for the need for “everything from carpenters to computer nerds,” and
|
||||
Daniel thought, “Hey, I’m a computer nerd!” We obtained the domain name and stood
|
||||
up the public website quickly using WordPress, which also allowed the coordinators to put content up.
|
||||
We next began developing an application (NSXapp) where volunteers could sign up for “X
|
||||
Week”, with over 80 different skill, talent, and ability categories. We then created a way to
|
||||
identify families and their needs, and a place for people with donations to let us know what they
|
||||
would be. From there, we created the ability to begin matching needs with goods (stuff) and abilities
|
||||
(people), organizing the stuff into donated trailers and people into teams. During X Week, we
|
||||
generated schedules and reports that were used to track the execution of the project.<br><br>
|
||||
After we recovered, Love INC expressed an interest in a version that would allow them to handle these
|
||||
same areas on an ongoing basis; this was the genesis of
|
||||
<a href="/applications/tcms" title="The Clearinghouse Management System • DJS Consulting">TCMS</a>.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: `NSXapp was officially decommissioned in 2012. (It still exists in archived form, if a need arises to
|
||||
use it again.) A <a href="//hosted.djs-consulting.com/archive/notsoextreme_org"> snapshot of the NSX
|
||||
public site</a> remains as a record of what happened those three months in 2008.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'olivet-baptist',
|
||||
name: 'Olivet Baptist Church',
|
||||
url: 'https://olivet-baptist.org',
|
||||
active: true,
|
||||
categoryId: 3,
|
||||
frontPageText: 'Gulfport, Mississippi',
|
||||
frontPageOrder: 2,
|
||||
indexText: 'Southern Baptist church in Gulfport, Mississippi',
|
||||
paragraphs: [
|
||||
`Olivet Baptist Church’s pastor saw our work with
|
||||
<a href="/applications/bay-vista" title="Bay Vista Baptist Church • DJS Consulting">Bay Vista</a>, and asked
|
||||
us what would be involved with setting up something similar for his church. Olivet did not currently have a
|
||||
website.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did (2014)',
|
||||
narrative: `We registered the domain name for the church, then set up a fresh WordPress install. They had
|
||||
expressed a desire to do as much of the content of the site themselves, so we supported them as they
|
||||
worked through its initial setup. We also, as with Bay Vista, established the framework for a sermon
|
||||
podcast feed.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Did (2016)',
|
||||
narrative: `As with Bay Vista’s site, this was converted to be a statically-generated site. We also
|
||||
created a mobile-friendly site layout that looked similar to the one they had been using.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: `DJS Consulting hosts this site; we also publish sermons to their podcast feed weekly.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'photography-by-michelle',
|
||||
name: 'Photography by Michelle',
|
||||
url: 'https://www.summershome.org',
|
||||
active: false,
|
||||
linkInactive: true,
|
||||
categoryId: 1,
|
||||
indexText: 'Photography services in Albuquerque, New Mexico',
|
||||
paragraphs: [
|
||||
`Michelle Summers (yes, Daniel’s wife) had been photographing her children for years. When her sons were on
|
||||
sports teams, she was disappointed with the cost of team photography, and felt that she could do a better job at a
|
||||
lower cost. Thus was born Photography by Michelle. She specializes in outdoor photography of families, children,
|
||||
and sports teams, as well as maternity photography and holiday cards.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did (2007)',
|
||||
narrative: `We created the site with a few custom pages, including a gallery page that would automatically
|
||||
display whatever pictures were there. We also, using WordPress and a custom image plugin, set up a
|
||||
site where customers can view the proofs from their photography session.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Did (2012)',
|
||||
narrative: `The custom PHP/WordPress site was replaced by a custom ASP MVC web application, which handles the
|
||||
front pages and the proof set galleries. The proof display was also upgraded to allow cursor-key
|
||||
navigation of proofs.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: `As Michelle is no longer doing professional photography, the current version of this site is a
|
||||
simple thank-you to her customers over the years.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'prayer-tracker',
|
||||
name: 'PrayerTracker',
|
||||
url: 'https://prayer.djs-consulting.com',
|
||||
active: true,
|
||||
categoryId: 1,
|
||||
frontPageText: 'A prayer request tracking website (Free for any church or Sunday School class!)',
|
||||
frontPageOrder: 1,
|
||||
indexText: 'Provides an ongoing, centralized prayer list for Sunday School classes and other groups',
|
||||
paragraphs: [
|
||||
`Years ago, Daniel was responsible for keeping up with prayer requests for his Sunday School class. To help him
|
||||
keep up with requests, automatically drop requests that were old, and track long-term requests, he wrote a custom
|
||||
app made up of a few pages. Over time, he added security mechanisms and other options, arriving at the site that
|
||||
exists today. It is provided free for the asking to any church, Sunday School class, or small group that desires a
|
||||
tool to help them establish a continuous list of prayer requests.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did (2005)',
|
||||
narrative: `Created the original site using PHP, storing the data in a MySQL database.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Did (2011)',
|
||||
narrative: `We rewrote this application using ASP MVC 3 backed by a PostgreSQL database, building the security
|
||||
additions from the ground up, and posturing it for an interface with
|
||||
<a href="/applications/virtual-prayer-room" title="Virtual Prayer Room • DJS Consulting">Virtual
|
||||
Prayer Room</a>.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Did (2012)',
|
||||
narrative: `In April 2012, version 4.0 was released with support for Spanish - our first multi-lingual
|
||||
application!`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: `Host and maintain this application.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'riehl-world-news',
|
||||
name: 'Riehl World News',
|
||||
url: 'http://riehlworldview.com',
|
||||
active: true,
|
||||
categoryId: 2,
|
||||
frontPageText: 'Riehl news for real people',
|
||||
frontPageOrder: 4,
|
||||
indexText: 'Riehl news for real people',
|
||||
paragraphs: [
|
||||
`Dan Riehl began blogging as “The Carnivorous Conservative” back in 2004, specializing in the areas of
|
||||
crime and politics. He changed to “Riehl World View” a short time later, and writes both news and
|
||||
opinion pieces. He was a prolific blogger, publishing over 15 posts a day on most days. He wanted to take his blog
|
||||
in a different direction, and was having trouble getting his Movable Type blog do move with him.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did',
|
||||
narrative: `We spoke with him regarding his ideal direction and assisted through the selection and customization
|
||||
of his eventual chosen theme. We also did some work on the customization of that theme. Additionally,
|
||||
we imported the large volume of posts from the Movable Type blog into his new WordPress blog.`
|
||||
},
|
||||
{
|
||||
heading: 'What We Still Do',
|
||||
narrative: `DJS Consulting continues to provide backups and WordPress updates for Riehl World News.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'tcms',
|
||||
name: 'The Clearinghouse Management System',
|
||||
url: 'http://tcms.us',
|
||||
active: false,
|
||||
categoryId: 1,
|
||||
indexText: 'Assists a needs clearinghouse in connecting people with needs to people that can help meet those needs',
|
||||
paragraphs: [
|
||||
`The TCMS motto, “Putting People Over Paperwork,” sums up the mission of this system. To successfully
|
||||
run a needs clearinghouse, such as those run by Love INC affiliates, there is a lot of paperwork involved. Clients
|
||||
must be tracked, along with their needs; these needs must be verified; resources for goods and services must be
|
||||
known; volunteers must be known and sent communications to keep them involved. All of this adds up to a
|
||||
significant recordkeeping (i.e., paperwork) burden.`,
|
||||
`TCMS addresses these issues by providing a repository for all clearinghouse operation needs. It can eliminate
|
||||
duplication of work, as well as link clients with goods and services. It also provides the means to communicate
|
||||
with volunteers, either en masse or using selective criteria. This allows the recordkeeping requirement to be
|
||||
smaller and quicker, giving more time for the actual helping of clients. It uses WordPress for its front end; this
|
||||
can provide organizations with a web presence that they can maintain without having to employ a web guru, using
|
||||
WordPress’s <abbr title="What You See Is What You Get">WYSIWYG</abbr> editor and management tools.`,
|
||||
`TCMS was decommissioned in 2014.`
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'tech-blog',
|
||||
name: 'DJS Consulting Tech Blog',
|
||||
url: 'https://techblog.djs-consulting.com',
|
||||
active: true,
|
||||
categoryId: 3,
|
||||
frontPageText: 'Technical information (AKA “geek stuff”) from DJS Consulting',
|
||||
frontPageOrder: 3,
|
||||
indexText: 'Geek stuff from DJS Consulting',
|
||||
paragraphs: [
|
||||
`The DJS Consulting Tech Blog grew from Daniel’s personal experience with learning and using the Linux
|
||||
operating system. His first experience with blogging consisted of pages that had to be edited every time a new
|
||||
post was made. The initial posts were titled “My Linux Adventure,” and existed as a copy of this
|
||||
home-grown blog. The DJS Consulting Tech Blog has that, plus tech tips regarding many different computer
|
||||
products. It covers web servers, databases, programming languages (a lot of PHP), and open-source software. DJS
|
||||
Consulting also hosts 64-bit RPM builds of xine, a Linux multimedia player; the tech blog, via the RSS feed for
|
||||
that category, can deliver notices of updated versions directly to subscribed users. Finally, it also contains
|
||||
notices of new versions of DJS Consulting-developed WordPress plug-ins (“Daniel’s Dropdowns”
|
||||
<em>(inactive, as its functionality is now part of the WordPress core)</em> and “HCSB Verse of the Day
|
||||
(Plus)”).`,
|
||||
`The original theme, “Almost Spring,” started as a pastel green and orange theme for WordPress.
|
||||
However, it was customized to match the original look and feel of those initial static pages that served as the
|
||||
blog from 2004-2006, and was converted to a BlogEngine.NET theme when we changed blogging platforms. When we went
|
||||
back to WordPress, we changed to a simple theme called “Mantra,” which has unobtrusive social media
|
||||
integration.`
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'the-shark-tank',
|
||||
name: 'The Shark Tank',
|
||||
url: 'http://shark-tank.net',
|
||||
active: false,
|
||||
categoryId: 2,
|
||||
indexText: 'Florida’s political feeding frenzy',
|
||||
paragraphs: [
|
||||
`The Shark Tank is a news and opinion site centered on south Florida politics (and the state at large). They
|
||||
provided extensive coverage of Rep. Allen West’s winning campaign in 2010, and are continuing their focused
|
||||
news and opinion to current political races.`
|
||||
],
|
||||
activity: [
|
||||
{
|
||||
heading: 'What We Did',
|
||||
narrative: `They were displeased with their current theme, and had found a theme (and a demo site) that they
|
||||
preferred. We set up the theme, ensured that their content would fit in the new theme’s
|
||||
requirements, and helped them turn off parts that they didn’t need. We also converted the
|
||||
social media connections from their old site to a style that would work nicely in the new theme.`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'virtual-prayer-room',
|
||||
name: 'Virtual Prayer Room',
|
||||
url: 'https://virtualprayerroom.us',
|
||||
active: false,
|
||||
categoryId: 1,
|
||||
indexText: 'Gives prayer warriors access to requests from wherever they may be, and sends them daily updates',
|
||||
paragraphs: [
|
||||
`Many churches have prayer rooms - rooms set aside for people to come in to pray. Hoffmantown Church in
|
||||
Albuquerque, New Mexico was one of these churches. However, they had seen the use of this physical prayer room
|
||||
dwindling over the years. People had become less willing to drive to the church, especially at night, and security
|
||||
became an issue as well; either prayer warriors had to know how to disable the security system, or the church
|
||||
would have to remain unlocked.`,
|
||||
`Having seen our work with the
|
||||
<a href="/applications/nsx/" title="Not So Extreme Makeover: Community Edition • DJS Consulting">Not So
|
||||
Extreme Makeover: Community Edition</a>, the church contacted us to see if something similar could be developed to
|
||||
help their prayer ministry. The resulting application that was developed extends the prayer room to wherever the
|
||||
prayer warrior can get an Internet connection! Prayer warriors can enlist right from the site, and must be
|
||||
approved. Requests and updates are tracked by date/time, and warriors can record when they’ve prayed for a
|
||||
request from the site, or from clicking a link in the daily e-mail they receive with requests from their interest
|
||||
areas. As many prayer needs are confidential, security and confidentiality are very important. Virtual Prayer Room
|
||||
ensures these by providing varying security levels for prayer warriors and the ability to mark each request as
|
||||
confidential.`,
|
||||
`In 2016, Hoffmantown Church elected to begin using another package for their prayer requests. While a few other
|
||||
churches had expressed interest in it, none ultimately decided to use it; so, in 2017, Virtual Prayer Room was
|
||||
officially decommissioned.`
|
||||
]
|
||||
}
|
||||
]
|
||||
export default {
|
||||
categories: CATEGORIES,
|
||||
apps: APPS
|
||||
}
|
||||
</script>
|
67
src/components/Application.vue
Normal file
@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<article>
|
||||
<page-title :title="pageTitle" />
|
||||
<h1>{{ application.name }}<br>
|
||||
<small><small>
|
||||
<a v-if="application.active || application.linkInactive" :href="application.url">{{ application.url }}</a>
|
||||
<span v-if="!application.active && !application.linkInactive">{{ application.url }}</span>
|
||||
</small></small>
|
||||
</h1>
|
||||
<aside>
|
||||
<img :src="imageLink">
|
||||
</aside>
|
||||
<p v-for="(p, idx) in application.paragraphs" v-bind:key="idx" v-html="p"></p>
|
||||
<p v-for="(act, idx) in application.activity" v-bind:key="idx" v-bind:act="act">
|
||||
<strong>{{ act.heading }}</strong> – <span v-html="act.narrative"></span>
|
||||
</p>
|
||||
<p v-for="(p, idx) in application.footnotes" v-bind:key="idx" v-html="p"></p>
|
||||
<p>
|
||||
<br>
|
||||
<router-link :to="{ name: 'ApplicationList' }">« Back to Web Sites and Applications</router-link>
|
||||
</p>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppData from './AppData.vue'
|
||||
import PageTitle from './PageTitle.vue'
|
||||
|
||||
export default {
|
||||
props: ['app'],
|
||||
data: function () {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
application: function () {
|
||||
return AppData.apps.find(app => app.id === this.$props.app)
|
||||
},
|
||||
imageLink: function () {
|
||||
return `/static/screenshots/${this.application.id}.png`
|
||||
},
|
||||
pageTitle: function () {
|
||||
return `${this.application.name} « Applications`
|
||||
}
|
||||
},
|
||||
components: {
|
||||
PageTitle
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
h1 {
|
||||
line-height: .75em;
|
||||
}
|
||||
aside {
|
||||
float: right;
|
||||
width: auto;
|
||||
padding-left: 15px;
|
||||
}
|
||||
aside img {
|
||||
border: solid 3px #3A1D00;
|
||||
border-top-right-radius: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
}
|
||||
</style>
|
30
src/components/ApplicationList.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<article>
|
||||
<page-title title="Applications" />
|
||||
<h1>Web Sites and Applications</h1>
|
||||
<h2>Current Projects</h2>
|
||||
<application-list-item v-for="app in current" v-bind:app="app" v-bind:key="app.id" />
|
||||
<h2>Past Projects</h2>
|
||||
<application-list-item v-for="app in past" v-bind:app="app" v-bind:key="app.id" />
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppData from './AppData.vue'
|
||||
import ApplicationListItem from './ApplicationListItem.vue'
|
||||
import PageTitle from './PageTitle.vue'
|
||||
|
||||
export default {
|
||||
name: 'application-list',
|
||||
data: function () {
|
||||
return {
|
||||
current: AppData.apps.filter(app => app.active && !app.noAboutLink),
|
||||
past: AppData.apps.filter(app => !app.active && !app.noAboutLink)
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ApplicationListItem,
|
||||
PageTitle
|
||||
}
|
||||
}
|
||||
</script>
|
28
src/components/ApplicationListItem.vue
Normal file
@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<p>
|
||||
<span class="app-name" v-html="app.name"></span> ~
|
||||
<router-link :to="{ name: 'Application', params: { app: app.id } }">About</router-link>
|
||||
<span v-if="app.active"> ~ <a :href="app.url">Visit</a></span>
|
||||
<span v-if="!app.active && app.archiveUrl"> ~ <a :href="app.archiveUrl">Visit</a> <em>(archive)</em></span><br>
|
||||
<span v-html="app.indexText"></span>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'application-list-item',
|
||||
props: ['app'],
|
||||
data: function () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.app-name {
|
||||
font-family: "Play", "Segoe UI", Ubuntu, "DejaVu Sans", "Liberation Sans", Arial, sans-serif;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
color: maroon;
|
||||
}
|
||||
</style>
|
206
src/components/Home.vue
Normal file
@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<article>
|
||||
<page-title title="Welcome!" />
|
||||
<h1>Welcome to DJS Consulting!</h1>
|
||||
<app-sidebar />
|
||||
<p>
|
||||
DJS Consulting can develop an interactive web application to fit almost any need.
|
||||
<router-link to="/applications" title="Web Sites and Applications">View the complete list of our current web
|
||||
sites and applications!</router-link>
|
||||
</p>
|
||||
<h2>Process Automation and User Engagement</h2>
|
||||
<p>
|
||||
Computers can be used to augment or automate nearly any process; could you think of generating bank statements,
|
||||
processing mailing lists, or tracking orders without some form of automation? We develop web-based solutions to
|
||||
automate <em>your</em> processes, ensuring that your business constraints are satisfied; these systems can run on
|
||||
the Internet or your private network. For Internet-facing solutions, we engineer solutions that allow them to
|
||||
interact with you securely, presented in an engaging manner. And, by "engagement," we are not describing intrusive
|
||||
page pop-ups and other <span class="strike">marketing gimmicks</span> web annoyances; we determine an optimal user
|
||||
experience for <em>your</em> customers, and tailor the solution to work for both of you.
|
||||
</p>
|
||||
<p>Several of our projects fit this description.</p>
|
||||
<ul>
|
||||
<li>
|
||||
<router-link to="/applications/virtual-prayer-room" title="Virtual Prayer Room">Virtual Prayer
|
||||
Room</router-link> helped the prayer ministry of
|
||||
<a href="http://www.hoffmantown.org" title="Hoffmantown Church in Albuquerque, NM">Hoffmantown Church</a>
|
||||
enable their prayer warriors to have access to requests wherever they are, even in their inbox once a day!
|
||||
</li>
|
||||
<li>
|
||||
<router-link to="/applications/tcms" title="TCMS">TCMS</router-link> was an application that helped
|
||||
organizations such as <a href="http://www.loveincabq.org">Love INC of South Albuquerque</a> connect people with
|
||||
needs to people who can help fulfill those needs. TCMS sprung from the
|
||||
<a href="http://hosted.djs-consulting.com/archive/notsoextreme_org" title="Not So Extreme Makeover: Community Edition (Archive)">Not
|
||||
So Extreme Makeover: Community Edition</a> in Albuquerque, New Mexico during spring break 2008; we not only
|
||||
developed the public presence, but a private system called
|
||||
<router-link to="/applications/nsx/" title="NSX • DJS Consulting">NSXapp</router-link> that enabled the
|
||||
management of the volunteers, families, and things for this massive effort.
|
||||
</li>
|
||||
<li>
|
||||
We continue to offer
|
||||
<router-link to="/applications/prayertracker" title="PrayerTracker • DJS Consulting">PrayerTracker</router-link>,
|
||||
a free-to-use web application that helps Sunday School classes (or other small groups) generate a prayer request
|
||||
list; it provides a central place for list management and continuity.
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Information Publicizing <small><em>(including WordPress)</em></small></h2>
|
||||
<p>
|
||||
In the early days of the World Wide Web, it was known as the "information superhighway." From its inception, the
|
||||
web's primary goal is information. The open nature of the Internet allows anyone, anywhere to say anything,
|
||||
provided they can connect a machine to the network. In fact, there are software products to handle everything
|
||||
except creating the content; all you have to bring is the ability to form a coherent thought, and type that
|
||||
thought into a box. <a href="https://wordpress.org" title="WordPress">WordPress</a> is one of the most popular
|
||||
<abbr title="Web Log">blog</abbr>ging platforms in use today; it allows authors to concentrate on the content of
|
||||
their websites, rather than forcing authors to turn into programmers.
|
||||
</p>
|
||||
<h3>Custom-Built Sites</h3>
|
||||
<ul>
|
||||
<li>
|
||||
We developed and maintained the site for <a href="http://www.emeraldmountainchristianschool.org">Emerald
|
||||
Mountain Christian School</a> for 9 years, where they had information about the type of curriculum they teach,
|
||||
the school's 40+-year history, a calendar of events, and how to get more information.
|
||||
</li>
|
||||
<li>
|
||||
We built and maintained the site for <a href="http://www.summershome.org">Photography by Michelle</a>, which had
|
||||
information, prices, and samples of the photographer's work, as well as the ability for customers to view proofs
|
||||
and make photo selections online.
|
||||
</li>
|
||||
<li>
|
||||
The sites for <a href="//bayvista.org" title="Bay Vista Baptist Church">Bay Vista Baptist Church</a> and
|
||||
<a href="//olivetbaptist.org" title="Olivet Baptist Church">Olivet Baptist Church</a> utilize a "static site
|
||||
generator," where the entire site is generated from source files, then served. It requires no back-end database,
|
||||
which means that the server can send them as fast as its clients can take them. These two sites even have a
|
||||
generated podcast feed! Adding content to these types of sites requires a bit more technical knowledge beyond
|
||||
"typing text in a box," but it is a great way to build ultra-fast, scalable web sites.
|
||||
</li>
|
||||
<li>
|
||||
This site is a single-page application (SPA) utilizing the <a href="//vuejs.org">Vue.js</a> JavaScript
|
||||
framework. The application pages are generated based on an internal data set, and the other pages are simple
|
||||
text components. Its bundling means that the initial page is small, and after the initial load, it runs entirely
|
||||
in the browser or on a phone or tablet. Sites that reference external data sets would still need to access the
|
||||
Internet to retrieve data, but this is much more efficient than having to download the entire page every single
|
||||
click.
|
||||
</li>
|
||||
</ul>
|
||||
<h3>WordPress Design, Customization, and Support</h3>
|
||||
<ul>
|
||||
<li>
|
||||
We helped <router-link to="/applications/cassy-fiano" title="Cassy Fiano">Cassy Fiano</router-link> and
|
||||
<a href="http://melissablogs.com" title="Dr. Melissa Clouthier • Information Pollination">Dr.Melissa
|
||||
Clouthier</a> both move their blogs from Blogspot to their own domains.
|
||||
</li>
|
||||
<li>
|
||||
We migrated <router-link to="/applications/liberty-pundits" title="Liberty Pundits">Liberty
|
||||
Pundits</router-link> from a custom blog platform to WordPress, and set up and maintained their server, which
|
||||
routinely cleared 100,000 hits per day in its prime.
|
||||
</li>
|
||||
<li>
|
||||
For <a href="//www.futilitycloset.com" title="Futility Closet">Futility Closet</a>, we moved their site from a
|
||||
shared hosting platform to its own <abbr title="Virtual Private Server">VPS</abbr>, to enable it to handle its
|
||||
ever-increasing traffic.
|
||||
</li>
|
||||
<li>
|
||||
TCMS and NSXapp both used WordPress as their front end, which also provided a public web presence that the
|
||||
customers could update themselves.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
On our <a href="//techblog.djs-consulting.com" title="DJS Consulting Tech Blog">tech blog</a> you can browse the
|
||||
<a href="//techblog.djs-consulting.com/category/wordpress" title="WordPress - DJS Consulting Tech Blog">WordPress</a>
|
||||
category for information on plug-ins, and you'll find that the themes on all of the WordPress blogs linked on the
|
||||
right have been customized.
|
||||
</p>
|
||||
<h2>Web Services</h2>
|
||||
<p>
|
||||
A web service is a way of using the Internet to provide or accept information that makes sense to computers; this
|
||||
allows other sites or applications to consume information from, or provide information to, your service. This
|
||||
enables communication between applications, without having to establish any communication channels other than the
|
||||
ones that web browsers already use. It isn't the best fit for every application, but when it is useful, it is
|
||||
<em>very</em> useful.
|
||||
</p>
|
||||
<p>
|
||||
Photography by Michelle has a web service that a desktop application utilizes to create the online proof sets
|
||||
right from the computer where the images reside. We also
|
||||
<a href="//techblog.djs-consulting.com/2010/4040-web-service.html" title="40/40 Web Service">wrote a service</a>
|
||||
for the 2010 <a href="http://erlc.com/4040/" title="40/40 Prayer Vigil - Ethics and Religious Liberty Commission of the Southern Baptist Convention">40/40
|
||||
Prayer Vigil</a>, which was utilized by several sites to display the current day's (or hour's) prayer focus, and
|
||||
<a href="//techblog.djs-consulting.com/2012/4040-web-service-for-2012.html" title="40/40 Web Service for 2012">wrote
|
||||
one for 2012</a> as well. <em>(As the ERLC does not host these any more, this service is no longer active.)</em>
|
||||
</p>
|
||||
<h2>Legacy Data Sharing</h2>
|
||||
<p>
|
||||
Our background in mainframe applications gives us a knowledgeable perspective on retrieving information from
|
||||
older, “legacy” systems. This data can be migrated to a more modern relational or document database,
|
||||
where a web application can retrieve the information; in some cases, the data can even be exposed as a web service
|
||||
in place. These types of systems are often a great way for companies to expose their data to their customers,
|
||||
without having to move their day-to-day system from its current environment. While we currently have no active
|
||||
projects along these lines, our developers have done them in the past for other organizations; sadly, none can be
|
||||
linked publicly.
|
||||
</p>
|
||||
<h2>Why Web-Based?</h2>
|
||||
<p>
|
||||
Developing a web-based solution has many advantages, whether that application can be used just on a local, private
|
||||
network (an intranet), or on the Internet.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
The application is available from any computer connected to the network — your home computer, your mobile
|
||||
phone or tablet, a shared comptuer in a library - wherever!
|
||||
</li>
|
||||
<li>
|
||||
There is no special software to install — every computer and mobile device has a web browser on it, and we
|
||||
ensure our solutions work on today's most popular web browsers, including Microsoft® Edge, Mozilla Firefox,
|
||||
and Google Chrome.
|
||||
</li>
|
||||
<li>
|
||||
Web-based solutions are easy to implement in a step-by-step fashion, so your most critical needs can be
|
||||
addressed and deployed first. Enhancements are generally easy to do as well.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
We'd be happy to discuss your information technology needs, and how we may be able to help you. Just
|
||||
<a href="mailto:daniel@djs-consulting.com">e-mail us</a> and let us know what we can do for you!
|
||||
</p>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppSidebar from './sidebar/AppSidebar.vue'
|
||||
import PageTitle from './PageTitle.vue'
|
||||
|
||||
export default {
|
||||
name: 'home',
|
||||
data: function () {
|
||||
return {
|
||||
toggleExamples: function (e) {
|
||||
e.preventDefault()
|
||||
const el = document.getElementById('test')
|
||||
if (el.style.height === '0px') {
|
||||
el.style.height = 'auto'
|
||||
const hite = el.clientHeight
|
||||
console.log('height = ' + hite)
|
||||
el.style.height = '0'
|
||||
window.requestAnimationFrame(function () {
|
||||
el.style.overflow = 'visible'
|
||||
el.style.height = hite + 'px'
|
||||
setTimeout(function () { el.style.overflow = 'visible' }, 1000)
|
||||
})
|
||||
} else {
|
||||
el.style.height = '0'
|
||||
setTimeout(function () { el.style.overflow = 'hidden' }, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
AppSidebar,
|
||||
PageTitle
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.examples {
|
||||
transition: all 1s ease;
|
||||
}
|
||||
</style>
|
15
src/components/PageTitle.vue
Normal file
@ -0,0 +1,15 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'page-title',
|
||||
props: ['title'],
|
||||
created () {
|
||||
document.title = `${this.title} « DJS Consulting`
|
||||
},
|
||||
watch: {
|
||||
title () {
|
||||
document.title = `${this.title} « DJS Consulting`
|
||||
}
|
||||
},
|
||||
render () { }
|
||||
}
|
||||
</script>
|
221
src/components/linux/Averatec.vue
Normal file
@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<article>
|
||||
<page-title title="Installing WBEL4 (RHEL4) on an Averatec 6200 Laptop « Linux Resources" />
|
||||
<h1>Installing WBEL4 (RHEL4) on an Averatec 6200 Laptop</h1>
|
||||
<aside>
|
||||
<p>
|
||||
<strong>Topics:</strong><br>
|
||||
<a href="#what">What Do I Have?</a><br>
|
||||
<a href="#partitioning">Partitioning</a><br>
|
||||
<a href="#installing">Installation</a><br>
|
||||
<a href="#video">Video</a><br>
|
||||
<a href="#wireless">Wireless Networking</a><br>
|
||||
<a href="#tweaks">Other Tweaks</a><br>
|
||||
<a href="#left">What’s Left?</a>
|
||||
</p>
|
||||
</aside>
|
||||
<p>
|
||||
As an early Father’s Day 2005 present, I received a new Averatec 6240 laptop. Being the Linux enthusiast
|
||||
that I am, within 24 hours of getting it, I had wiped the Windows XP Home Edition® that came on it. The
|
||||
previous week, I had downloaded <a href="http://www.whiteboxlinux.org">White Box Enterprise Linux
|
||||
(http://www.whiteboxlinux.org)</a> version 4, with an eye to upgrading my existing computer, so I had a recent set
|
||||
of CDs burned already. (WBEL is a clone of Red Hat Enterprise Linux, as is CentOS, so these instructions may be
|
||||
helpful for all RHEL derivatives.) I’ve organized this into topics – just click one to jump right to
|
||||
it.
|
||||
</p>
|
||||
<p>
|
||||
<small><em>(Note: This information is provided as information only, and a reflection of what I did to get my
|
||||
laptop running the way I wanted it. It may or may not work for you – no guarantee is specified or implied,
|
||||
and I cannot be held responsible for any hardware failure or data loss you may encounter by following any of the
|
||||
steps in this guide. At any rate, it’s still probably worth double what you’re paying for
|
||||
it… ;>)</em></small>
|
||||
</p>
|
||||
<p>
|
||||
<del>
|
||||
<strong>A Work in Progress</strong> – This page is not complete – check the “What’s
|
||||
Left?” topic to see what changes still need to be made before I’ll consider it
|
||||
“complete”.
|
||||
</del>
|
||||
This page is as complete as it’s ever going to be.
|
||||
</p>
|
||||
<h2><a name="what"></a>What Do I Have?</h2>
|
||||
<p>
|
||||
To determine what type of hardware you have, you can use the command <tt>/sbin/lspci</tt>. On this laptop, I was
|
||||
able to boot with <a href="http://wwww.knoppix.com">Knoppix</a>, one of the most feature-rich Linux Live CD
|
||||
distributions out there. The list on this laptop is shown below…
|
||||
</p>
|
||||
<blockquote>
|
||||
<pre>0000:00:00.0 Host bridge: Silicon Integrated Systems [SiS] 760/M760 Host (rev 03)
|
||||
0000:00:01.0 PCI bridge: Silicon Integrated Systems [SiS] SG86C202
|
||||
0000:00:02.0 ISA bridge: Silicon Integrated Systems [SiS] SiS85C503/5513 (LPC Bridge) (rev 25)
|
||||
0000:00:02.5 IDE interface: Silicon Integrated Systems [SiS] 5513 [IDE]
|
||||
0000:00:02.6 Modem: Silicon Integrated Systems [SiS] AC'97 Modem Controller (rev a0)
|
||||
0000:00:02.7 Multimedia audio controller: Silicon Integrated Systems [SiS] Sound Controller (rev a0)
|
||||
0000:00:03.0 USB Controller: Silicon Integrated Systems [SiS] USB 1.0 Controller (rev 0f)
|
||||
0000:00:03.1 USB Controller: Silicon Integrated Systems [SiS] USB 1.0 Controller (rev 0f)
|
||||
0000:00:03.3 USB Controller: Silicon Integrated Systems [SiS] USB 2.0 Controller
|
||||
0000:00:04.0 Ethernet controller: Silicon Integrated Systems [SiS] SiS900 PCI Fast Ethernet (rev 91)
|
||||
0000:00:0a.0 CardBus bridge: ENE Technology Inc CB1410 Cardbus Controller (rev 01)
|
||||
0000:00:0e.0 Network controller: RaLink Ralink RT2500 802.11 Cardbus Reference Card (rev 01)
|
||||
0000:00:18.0 Host bridge: Advanced Micro Devices [AMD] K8 NorthBridge
|
||||
0000:00:18.1 Host bridge: Advanced Micro Devices [AMD] K8 NorthBridge
|
||||
0000:00:18.2 Host bridge: Advanced Micro Devices [AMD] K8 NorthBridge
|
||||
0000:00:18.3 Host bridge: Advanced Micro Devices [AMD] K8 NorthBridge
|
||||
0000:01:00.0 VGA compatible controller: Silicon Integrated Systems [SiS] 661FX/M661FX/M661MX/741/M741/760/M760 PCI/AGP</pre>
|
||||
</blockquote>
|
||||
<p>
|
||||
This may seem like a waste of time (especially if you don’t have a Knoppix CD lying around already, but this
|
||||
information can be invaluable when you try to get these devices working. A couple of things jump out from the
|
||||
above list – most of the hardware in this box was made by Silicon Integrated Systems, with the notable
|
||||
exception of the cardbus controller and the 802.11 (wireless) network adapter.
|
||||
</p>
|
||||
<h2><a name="partitioning"></a>Partitioning</h2>
|
||||
<p>
|
||||
Partitioning was a particular concern for me, as I wanted to set up a dual-boot Windows/Linux installation.
|
||||
Windows must have its files on the first partition for it to successfully boot, so I set up Windows first. I
|
||||
messed up a bit, as I tried to declare a 100MB boot partition as the first partition. Windows insisted on
|
||||
formatting it, so it could put its boot files on it, so I basically have a wasted 100MB at the front of my drive.
|
||||
(Not a big deal…)
|
||||
</p>
|
||||
<p>
|
||||
I created a 12GB partition for Windows, and a 15GB partition for “shared” data – I formatted it
|
||||
as FAT32 (vfat), so that both Windows and Linux can read it. This was fine, but combined with my extra 100MB
|
||||
partition, the WBEL installer was unable to automatically partition the remaining free space. This
|
||||
isn’t a big problem – there’s are two pretty simple rules to remember about partitions that
|
||||
Linux needs…
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
There must be a root (“/”) partition (I calculated the size of this by subtracting the amount of
|
||||
swap space I needed (see the next rule), then allocating the remaining free space to the root partition)
|
||||
</li>
|
||||
<li>
|
||||
There must be a swap partition (actually the “swap” filesystem type) that is twice as big as your
|
||||
RAM (for this machine, that meant 1024MB)
|
||||
</li>
|
||||
</ul>
|
||||
<p>Here is my current partition table…</p>
|
||||
<blockquote>
|
||||
<pre># /sbin/fdisk -l
|
||||
|
||||
Disk /dev/hda: 60.0 GB, 60011642880 bytes
|
||||
255 heads, 63 sectors/track, 7296 cylinders
|
||||
Units = cylinders of 16065 * 512 = 8225280 bytes
|
||||
|
||||
Device Boot Start End Blocks Id System
|
||||
/dev/hda1 * 1 13 104391 6 FAT16
|
||||
/dev/hda2 14 7295 58492665 f W95 Ext'd (LBA)
|
||||
/dev/hda5 14 1580 12586896 7 HPFS/NTFS
|
||||
/dev/hda6 1581 3589 16137261 b W95 FAT32
|
||||
/dev/hda7 3590 7158 28667961 83 Linux
|
||||
/dev/hda8 7159 7289 1052226 82 Linux swap</pre>
|
||||
</blockquote>
|
||||
<h2><a name="installing"></a>Installing</h2>
|
||||
<p>
|
||||
Installing Linux is naturally the first thing you’ll need to do. However, the default install options did
|
||||
not work for me. What did work was <tt>linux nofb xdriver=sis</tt>. This tells anaconda to not use a framebuffer
|
||||
(which, as I read, is incompatible with most of the LCD flat-panels that laptops have), and to use the
|
||||
“sis” (Silicon Integrated Systems) driver. Even with this, the installer will not detect the SiS video
|
||||
card or the flat-panel display – but that’s okay, just let it install with the VESA driver and a
|
||||
generic 1024×768 layout. It’ll be stretched, but definitely readable. (See the “video”
|
||||
topic for how to fix this.) Also, if you really mess something up, you’ll need to pass those parameters in
|
||||
the rescue mode – the full command is <tt>linux rescue nofb xdriver=sis</tt>.
|
||||
</p>
|
||||
<p>
|
||||
I picked the server install, and selected most packages – this setup allows me to run both GNOME and KDE,
|
||||
and build applications for either. Be sure to install the system files, so you can compile kernel modules if you
|
||||
need them (which you’ll need to do for the xdriver and wireless driver). Do not skip the OpenOffice.org I18N
|
||||
libraries – even though they’re huge, it won’t run without them. (I learned that the hard way.)
|
||||
</p>
|
||||
<h2><a name="video"></a>Video</h2>
|
||||
<p>
|
||||
I mentioned that during the install, the monitor would not be detected. Using the system viedo config, you can set
|
||||
the LCD panel to 1280×800. Then, head over to <a href="http://www.winischhofer.at/linuxsisvga.shtml">Thomas
|
||||
Winischhofer’s site about the SiS video driver</a>. He is the author of the SiS driver that’s
|
||||
distributed with Linux, and his site has a lot of information about this chipset. On his site, he has built on
|
||||
that base, in his own time, and created a very usable driver for the SiS chipset. There are links to download
|
||||
various products – I downloaded the driver and the sisctrl program, and built them.
|
||||
</p>
|
||||
<p>
|
||||
Once I restarted the machine, it was better, but not quite there. I posted on the forums (also on the Winischhofer
|
||||
site) about my problem, and the author himself responded
|
||||
(<a href="http://www.winischhofer.at/sisforum/viewtopic.php?t=76">the thread is here</a>). In my case,
|
||||
1280×800 was not put in by the driver – but, I think it may have been because I hadn’t set the
|
||||
LCD panel settings when I installed the driver.
|
||||
</p>
|
||||
<h2><a name="wireless"></a>Wireless Networking</h2>
|
||||
<p>
|
||||
The RaLink wireless ethernet card has a very capable open-source driver. It can be downloaded from
|
||||
<a href="http://rt2x00.serialmonkey.com/wiki/index.php/Main_Page">SerialMonkey’s web site</a>. I downloaded
|
||||
the driver, followed the instructions, and couldn’t get it to work. It installed the adapter as ra0, but
|
||||
Linux was finding it as eth1 - and I couldn’t get eth1 to change to ra0, or ra0 to change to eth1. I finally
|
||||
posted a message on the
|
||||
<a href="http://sourceforge.net/forum/forum.php?thread_id=1294781&forum_id=370891">driver’s
|
||||
SourceForge.net forums</a>, and the author told me that I needed to use <tt>make install-fedora</tt> instead of
|
||||
just <tt>make install</tt>.
|
||||
</p>
|
||||
<p>
|
||||
Every so often, I had problems getting the wireless card to connect with my home LAN. I changed my DHCP lease
|
||||
times from two weeks to two hours, and that problem cleared up. I think, for some reason, the router was not
|
||||
sensing when the wireless card would disconnect – so, when it tried to connect again, the router would just
|
||||
ignore it. Windows didn’t seem to have similar problems, but that’s a small tweak to make that
|
||||
hasn’t affected any of the other computers on the network. I have gotten good responses from the developers
|
||||
of the wireless driver, and hope to be able to help them track this down if they’re interested. (They are
|
||||
concentrating most of their new work on a new driver called “rt2x00″ that will work for all RaLink
|
||||
RT2400 and RT2500 series network adapters, so this feature may be available in them. They’ve also moved
|
||||
their forums - <a href="http://rt2x00.serialmonkey.com/phpBB2/index.php">the official support forms can be found
|
||||
here</a>.)
|
||||
</p>
|
||||
<h2><a name="tweaks"></a>Other Tweaks</h2>
|
||||
<p>They’ll be here soon!</p>
|
||||
<h2><a name="left"></a>What’s Left?</h2>
|
||||
<p>Issues I’m still working on…</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>PCMCIA</strong> – This is so slow initializing that rhgb (Red Hat’s graphical booter)
|
||||
actually switches back to console one. I’m sure there’s a way to make it not take so long, I just
|
||||
need to figure out what it is.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Audio Input</strong> – I tried to use the microphone in jack, and nothing would take sound from
|
||||
it.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Shared Data Between XP and WBEL</strong> – This is working differently than WBEL3 did – once
|
||||
I figure it out, it’ll be here too
|
||||
</li>
|
||||
</ul>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PageTitle from '@/components/PageTitle.vue'
|
||||
|
||||
export default {
|
||||
name: 'averatec',
|
||||
data: function () {
|
||||
return {}
|
||||
},
|
||||
components: {
|
||||
PageTitle
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
aside {
|
||||
float: right;
|
||||
width: auto;
|
||||
border: solid 2px navy;
|
||||
border-right: none;
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
margin-right: -15px;
|
||||
}
|
||||
aside p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
38
src/components/linux/Linux.vue
Normal file
@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<article>
|
||||
<page-title title="Linux Resources" />
|
||||
<h1>Linux Resources</h1>
|
||||
<p>We at DJS Consulting love Linux! Below are the resources we provide.</p>
|
||||
<p>
|
||||
» <router-link to="/linux/installing-wbel4-rhel4-on-an-averatec-6200-laptop" title="Installing WBEL4 (RHEL4) on an Averatec 6200 Laptop - DJS Consulting Linux Resources">Installing
|
||||
Linux on an Averatec 6200 Laptop</router-link>
|
||||
</p>
|
||||
<p>
|
||||
» <router-link to="/linux/xine-rpms-for-el-x86_64-architecture" title="xine RPMs for EL / x86_64 Architecture - DJS Consulting Linux Resources">xine
|
||||
RPMs for the x86_64 EL Architecture</router-link>
|
||||
</p>
|
||||
<p>
|
||||
» <a href="//hosted.djs-consulting.com/software" title="DJS Consulting Software Repository">DJS Consulting
|
||||
Software Repository</a>
|
||||
</p>
|
||||
<p>
|
||||
» <a href="//techblog.djs-consulting.com/category/linux" title="Linux - DJS Consulting Tech Blog">Linux
|
||||
posts</a> on the <a href="//techblog.djs-consulting.com" title="DJS Consulting Tech Blog">DJS Consulting Tech
|
||||
Blog</a>
|
||||
</p>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PageTitle from '@/components/PageTitle.vue'
|
||||
|
||||
export default {
|
||||
name: 'linux',
|
||||
data: function () {
|
||||
return {}
|
||||
},
|
||||
components: {
|
||||
PageTitle
|
||||
}
|
||||
}
|
||||
</script>
|
32
src/components/linux/XineRPMs.vue
Normal file
@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<article>
|
||||
<page-title title="xine RPMs « Linux Resources" />
|
||||
<h1>xine RPMs for EL / x86_64 Architecture</h1>
|
||||
<p>
|
||||
The xine RPMs are now distributed through the <a href="//techblog.djs-consulting.com">DJS Consulting Tech
|
||||
Blog</a>. Information about the RPMs can be found in the
|
||||
<a href="//techblog.djs-consulting.com/2005/about-the-xine-rpms.html" title="About the xine RPMs">About the xine
|
||||
RPMs</a> post there, including how you can use RSS or Atom feeds to be notified of updated builds.
|
||||
</p>
|
||||
<p>
|
||||
You can also
|
||||
<a href="//techblog.djs-consulting.com/category/hosted-64-bit-software/xine-rpms" title="xine RPMs">view the list
|
||||
of available RPMs</a> or simply <a href="//hosted.djs-consulting.com/software/xine" title="xine RPMs">browse the
|
||||
available xine files</a>.
|
||||
</p>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PageTitle from '@/components/PageTitle.vue'
|
||||
|
||||
export default {
|
||||
name: 'xine-rpms',
|
||||
data: function () {
|
||||
return {}
|
||||
},
|
||||
components: {
|
||||
PageTitle
|
||||
}
|
||||
}
|
||||
</script>
|
52
src/components/sidebar/AppSidebar.vue
Normal file
@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<aside>
|
||||
<sidebar-category v-for="category in cats" v-bind:category="category" v-bind:key="category.id" />
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppData from '../AppData.vue'
|
||||
import SidebarCategory from './SidebarCategory.vue'
|
||||
|
||||
export default {
|
||||
name: 'app-sidebar',
|
||||
data: function () {
|
||||
return { cats: AppData.categories }
|
||||
},
|
||||
components: {
|
||||
SidebarCategory
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
aside {
|
||||
width: 200px;
|
||||
float: right;
|
||||
font-size: 1em;
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
border: solid 2px navy;
|
||||
border-right: none;
|
||||
border-radius: 10px;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
margin-left:3px;
|
||||
margin-right: -15px;
|
||||
padding-left: 3px;
|
||||
padding-right: 3px;
|
||||
font-size: 80%;
|
||||
clear: both;
|
||||
}
|
||||
aside a {
|
||||
font-size: 10pt;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
.widget-projects hr {
|
||||
border-color: #3A1D00;
|
||||
}
|
||||
aside p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
</style>
|
34
src/components/sidebar/SidebarApp.vue
Normal file
@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<div>
|
||||
<p>
|
||||
<strong class="sidebar-name">{{ app.name }}</strong><br>
|
||||
<span v-if="!app.noAboutLink">
|
||||
<router-link :to="{ name: 'Application', params: { app: app.id } }">About</router-link> •
|
||||
</span>
|
||||
<a :title="app.name" :href="app.url">Visit</a>
|
||||
</p>
|
||||
<div class="sidebar-description" v-html="app.frontPageText"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'sidebar-app',
|
||||
props: ['app'],
|
||||
data: function () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.sidebar-description {
|
||||
font-style: italic;
|
||||
color: #555555;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
</style>
|
43
src/components/sidebar/SidebarCategory.vue
Normal file
@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<div>
|
||||
<p class="sidebar-head">
|
||||
{{ category.name }}
|
||||
</p>
|
||||
<sidebar-app v-for="app in appsForCat(category.id)" v-bind:app="app" v-bind:key="app.id" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppData from '../AppData.vue'
|
||||
import SidebarApp from './SidebarApp.vue'
|
||||
|
||||
export default {
|
||||
name: 'sidebar-category',
|
||||
props: ['category'],
|
||||
data: function () {
|
||||
return {
|
||||
appsForCat: function (catId) {
|
||||
return AppData.apps
|
||||
.filter(app => app.active && app.categoryId === catId)
|
||||
.sort((a, b) => a.frontPageOrder - b.frontPageOrder)
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
SidebarApp
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sidebar-head {
|
||||
font-family: "Play", "Segoe UI", Ubuntu, "DejaVu Sans", "Liberation Sans", Arial, sans-serif;
|
||||
font-weight: bold;
|
||||
color: maroon;
|
||||
margin: 10px 0;
|
||||
padding: 3px 0;
|
||||
display:block;
|
||||
border-top: solid 1px #3A1D00;
|
||||
border-bottom: solid 1px #3A1D00;
|
||||
}
|
||||
</style>
|
15
src/main.js
Normal file
@ -0,0 +1,15 @@
|
||||
// The Vue build version to load with the `import` command
|
||||
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
import router from './router'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
/* eslint-disable no-new */
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
template: '<App/>',
|
||||
components: { App }
|
||||
})
|
24
src/router/index.js
Normal file
@ -0,0 +1,24 @@
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
|
||||
import Home from '@/components/Home'
|
||||
import Application from '@/components/Application'
|
||||
import ApplicationList from '@/components/ApplicationList'
|
||||
|
||||
import Linux from '@/components/linux/Linux'
|
||||
import Averatec from '@/components/linux/Averatec'
|
||||
import XineRPMs from '@/components/linux/XineRPMs'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
mode: 'history',
|
||||
routes: [
|
||||
{ path: '/', name: 'Home', component: Home },
|
||||
{ path: '/applications/:app', name: 'Application', component: Application, props: true },
|
||||
{ path: '/applications', name: 'ApplicationList', component: ApplicationList },
|
||||
{ path: '/linux/installing-wbel4-rhel4-on-an-averatec-6200-laptop', name: 'Averatec', component: Averatec },
|
||||
{ path: '/linux/xine-rpms-for-el-x86_64-architecture', name: 'XineRPMs', component: XineRPMs },
|
||||
{ path: '/linux', name: 'Linux', component: Linux }
|
||||
]
|
||||
})
|
0
static/.gitkeep
Normal file
BIN
static/djs-consulting.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
static/favicon.ico
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
static/screenshots/bay-vista.png
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
static/screenshots/cassy-fiano.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
static/screenshots/dr-melissa-clouthier.png
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
static/screenshots/emerald-mountain-christian-school.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
static/screenshots/futility-closet.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
static/screenshots/hard-corps-wife.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
static/screenshots/liberty-pundits.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
static/screenshots/mindy-mackenzie.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
static/screenshots/nsx.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
static/screenshots/olivet-baptist.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
static/screenshots/photography-by-michelle.png
Normal file
After Width: | Height: | Size: 90 KiB |
BIN
static/screenshots/prayer-tracker.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
static/screenshots/riehl-world-news.png
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
static/screenshots/tcms.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
static/screenshots/tech-blog.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
static/screenshots/the-shark-tank.png
Normal file
After Width: | Height: | Size: 95 KiB |
BIN
static/screenshots/virtual-prayer-room.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
static/slogan.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
26
test/e2e/custom-assertions/elementCount.js
Normal file
@ -0,0 +1,26 @@
|
||||
// A custom Nightwatch assertion.
|
||||
// the name of the method is the filename.
|
||||
// can be used in tests like this:
|
||||
//
|
||||
// browser.assert.elementCount(selector, count)
|
||||
//
|
||||
// for how to write custom assertions see
|
||||
// http://nightwatchjs.org/guide#writing-custom-assertions
|
||||
exports.assertion = function (selector, count) {
|
||||
this.message = 'Testing if element <' + selector + '> has count: ' + count
|
||||
this.expected = count
|
||||
this.pass = function (val) {
|
||||
return val === this.expected
|
||||
}
|
||||
this.value = function (res) {
|
||||
return res.value
|
||||
}
|
||||
this.command = function (cb) {
|
||||
var self = this
|
||||
return this.api.execute(function (selector) {
|
||||
return document.querySelectorAll(selector).length
|
||||
}, [selector], function (res) {
|
||||
cb.call(self, res)
|
||||
})
|
||||
}
|
||||
}
|
46
test/e2e/nightwatch.conf.js
Normal file
@ -0,0 +1,46 @@
|
||||
require('babel-register')
|
||||
var config = require('../../config')
|
||||
|
||||
// http://nightwatchjs.org/gettingstarted#settings-file
|
||||
module.exports = {
|
||||
src_folders: ['test/e2e/specs'],
|
||||
output_folder: 'test/e2e/reports',
|
||||
custom_assertions_path: ['test/e2e/custom-assertions'],
|
||||
|
||||
selenium: {
|
||||
start_process: true,
|
||||
server_path: require('selenium-server').path,
|
||||
host: '127.0.0.1',
|
||||
port: 4444,
|
||||
cli_args: {
|
||||
'webdriver.chrome.driver': require('chromedriver').path
|
||||
}
|
||||
},
|
||||
|
||||
test_settings: {
|
||||
default: {
|
||||
selenium_port: 4444,
|
||||
selenium_host: 'localhost',
|
||||
silent: true,
|
||||
globals: {
|
||||
devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
|
||||
}
|
||||
},
|
||||
|
||||
chrome: {
|
||||
desiredCapabilities: {
|
||||
browserName: 'chrome',
|
||||
javascriptEnabled: true,
|
||||
acceptSslCerts: true
|
||||
}
|
||||
},
|
||||
|
||||
firefox: {
|
||||
desiredCapabilities: {
|
||||
browserName: 'firefox',
|
||||
javascriptEnabled: true,
|
||||
acceptSslCerts: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
33
test/e2e/runner.js
Normal file
@ -0,0 +1,33 @@
|
||||
// 1. start the dev server using production config
|
||||
process.env.NODE_ENV = 'testing'
|
||||
var server = require('../../build/dev-server.js')
|
||||
|
||||
server.ready.then(() => {
|
||||
// 2. run the nightwatch test suite against it
|
||||
// to run in additional browsers:
|
||||
// 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings"
|
||||
// 2. add it to the --env flag below
|
||||
// or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
|
||||
// For more information on Nightwatch's config file, see
|
||||
// http://nightwatchjs.org/guide#settings-file
|
||||
var opts = process.argv.slice(2)
|
||||
if (opts.indexOf('--config') === -1) {
|
||||
opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
|
||||
}
|
||||
if (opts.indexOf('--env') === -1) {
|
||||
opts = opts.concat(['--env', 'chrome'])
|
||||
}
|
||||
|
||||
var spawn = require('cross-spawn')
|
||||
var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
|
||||
|
||||
runner.on('exit', function (code) {
|
||||
server.close()
|
||||
process.exit(code)
|
||||
})
|
||||
|
||||
runner.on('error', function (err) {
|
||||
server.close()
|
||||
throw err
|
||||
})
|
||||
})
|
19
test/e2e/specs/test.js
Normal file
@ -0,0 +1,19 @@
|
||||
// For authoring Nightwatch tests, see
|
||||
// http://nightwatchjs.org/guide#usage
|
||||
|
||||
module.exports = {
|
||||
'default e2e tests': function (browser) {
|
||||
// automatically uses dev Server port from /config.index.js
|
||||
// default: http://localhost:8080
|
||||
// see nightwatch.conf.js
|
||||
const devServer = browser.globals.devServerURL
|
||||
|
||||
browser
|
||||
.url(devServer)
|
||||
.waitForElementVisible('#app', 5000)
|
||||
.assert.elementPresent('.hello')
|
||||
.assert.containsText('h1', 'Welcome to Your Vue.js App')
|
||||
.assert.elementCount('img', 1)
|
||||
.end()
|
||||
}
|
||||
}
|
9
test/unit/.eslintrc
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"globals": {
|
||||
"expect": true,
|
||||
"sinon": true
|
||||
}
|
||||
}
|
13
test/unit/index.js
Normal file
@ -0,0 +1,13 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
// require all test files (files that ends with .spec.js)
|
||||
const testsContext = require.context('./specs', true, /\.spec$/)
|
||||
testsContext.keys().forEach(testsContext)
|
||||
|
||||
// require all src files except main.js for coverage.
|
||||
// you can also change this to match only the subset of files that
|
||||
// you want coverage for.
|
||||
const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
|
||||
srcContext.keys().forEach(srcContext)
|
33
test/unit/karma.conf.js
Normal file
@ -0,0 +1,33 @@
|
||||
// This is a karma config file. For more details see
|
||||
// http://karma-runner.github.io/0.13/config/configuration-file.html
|
||||
// we are also using it with karma-webpack
|
||||
// https://github.com/webpack/karma-webpack
|
||||
|
||||
var webpackConfig = require('../../build/webpack.test.conf')
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
// to run in additional browsers:
|
||||
// 1. install corresponding karma launcher
|
||||
// http://karma-runner.github.io/0.13/config/browsers.html
|
||||
// 2. add it to the `browsers` array below.
|
||||
browsers: ['PhantomJS'],
|
||||
frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'],
|
||||
reporters: ['spec', 'coverage'],
|
||||
files: ['./index.js'],
|
||||
preprocessors: {
|
||||
'./index.js': ['webpack', 'sourcemap']
|
||||
},
|
||||
webpack: webpackConfig,
|
||||
webpackMiddleware: {
|
||||
noInfo: true
|
||||
},
|
||||
coverageReporter: {
|
||||
dir: './coverage',
|
||||
reporters: [
|
||||
{ type: 'lcov', subdir: '.' },
|
||||
{ type: 'text-summary' }
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|