Skip to content

Commit 413f270

Browse files
committed
ImageOptim site
1 parent 3a91a84 commit 413f270

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2054
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
public/*.css
3+
public/*.html
4+
public/*.gz

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# [ImageOptim.com](https://imageoptim.com) website generator
2+
3+
To try it out:
4+
5+
```sh
6+
npm install
7+
npm start
8+
```
9+
10+
it'll run the site live-reloaded under BrowserSync on localhost.
11+
12+
```sh
13+
gulp
14+
```
15+
16+
generates minified version of the site.
17+

gulpfile.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
'use strict';
2+
const gulp = require('gulp');
3+
const exec = require('child_process').exec;
4+
const browserSync = require('browser-sync').create();
5+
const each = require('gulp-each');
6+
const sass = require('gulp-sass');
7+
const autoprefixer = require('gulp-autoprefixer');
8+
const cleancss = require('gulp-clean-css');
9+
const zopfli = require('gulp-zopfli');
10+
const htmlmin = require('gulp-htmlmin');
11+
const nunjucks = require('nunjucks');
12+
const fs = require('fs');
13+
const yaml = require('js-yaml');
14+
15+
const defaultProps = yaml.safeLoad(fs.readFileSync('pages/_default.yaml'));
16+
defaultProps.dev = process.argv[2] == 'watch';
17+
18+
gulp.task('watch', ['css-browsersync', 'pages'], function() {
19+
if (!defaultProps.dev) throw Error("Misconfigured");
20+
21+
gulp.watch("gulpfile.js").on("change", () => process.exit(0));
22+
23+
browserSync.init({
24+
server: "./public"
25+
});
26+
27+
gulp.watch("style/*.scss", ['css-browsersync']);
28+
gulp.watch("pages/*.{html,yaml}", ['pages']);
29+
gulp.watch("public/*.html").on('change', browserSync.reload);
30+
});
31+
32+
gulp.task('css-browsersync', function() {
33+
return gulp.src(["style/[a-z]*.scss"])
34+
.pipe(sass().on('error', function (err) {
35+
console.error(err.message);
36+
browserSync.notify(err.message, 3000);
37+
this.emit('end');
38+
}))
39+
.pipe(gulp.dest("public/"))
40+
.pipe(browserSync.stream());
41+
});
42+
43+
gulp.task('css', function() {
44+
return gulp.src("style/[a-z]*.scss")
45+
.pipe(sass())
46+
.pipe(autoprefixer())
47+
.pipe(cleancss({
48+
rebase:false,
49+
}))
50+
.pipe(gulp.dest("public/"))
51+
});
52+
53+
gulp.task('compress', ['css', 'pages'], function() {
54+
return gulp.src(["public/style.css", "public/index.html"])
55+
.pipe(zopfli())
56+
.pipe(gulp.dest("public/"))
57+
});
58+
59+
gulp.task('pages', defaultProps.dev ? [] : ['css'], function() {
60+
let pageStream = gulp.src(["pages/[a-z]*.html"])
61+
.pipe(each((content, file, callback) => {
62+
const path = file.history[0];
63+
64+
const env = nunjucks.configure({
65+
throwOnUndefined: true,
66+
trimBlocks: true,
67+
});
68+
69+
const propsPath = path.replace(/html$/,'yaml');
70+
const props = fs.existsSync(propsPath) ? Object.assign({}, defaultProps, yaml.safeLoad(fs.readFileSync(propsPath))) : defaultProps;
71+
72+
if (!props.dev && props.inlineStyleFile) {
73+
props.inlineStyle = fs.readFileSync(`public/${props.inlineStyleFile}`);
74+
}
75+
76+
const txt = yaml.safeLoad(fs.readFileSync(`pages/_${props.lang}.yaml`));
77+
78+
env.addFilter('t', t => {
79+
const translated = txt[t];
80+
if ('string' === typeof translated) {
81+
return translated;
82+
}
83+
if (props.lang != 'en') console.error(`Untranslated '${t}'`);
84+
return t;
85+
});
86+
87+
env.renderString(content, props, {path}, (err, res) => {
88+
if (err) {
89+
console.error(err && err.stack || err);
90+
return callback(err, ''+err);
91+
}
92+
callback(null, ''+res);
93+
});
94+
}));
95+
if (!defaultProps.dev) {
96+
pageStream = pageStream.pipe(htmlmin({
97+
minifyCSS: true,
98+
minifyJS: true,
99+
collapseWhitespace: true,
100+
conservativeCollapse: true,
101+
collapseBooleanAttributes: true,
102+
decodeEntities: true,
103+
removeOptionalTags: true,
104+
removeAttributeQuotes: true,
105+
removeScriptTypeAttributes: true,
106+
removeStyleLinkTypeAttributes: true,
107+
sortAttributes: true,
108+
sortClassName: true,
109+
}));
110+
}
111+
return pageStream.pipe(gulp.dest("public/"));
112+
});
113+
114+
gulp.task('default', ['css', 'pages', 'compress']);

pages/_default.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
betaVersion: '1.6.1b1'
2+
lang: 'en'
3+
current: 'mac'

pages/_en.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
'Help translate it!': 'Help translate it!' # nbsp there
2+
Changelog: "What's new?"

pages/_layout.html

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
<!DOCTYPE html>
2+
<head lang="{{lang}}">
3+
<meta charset="utf8">
4+
<title>{{title}}</title>
5+
<meta name="viewport" content="width=device-width">
6+
{% set fontStylesheetHost = "https://fonts.googleapis.com" %}
7+
{% if fontExtended %}
8+
{% set fontStylesheetPath = "/css?family=Open+Sans|Roboto:300,500&subset=latin,latin-ext" %}
9+
{% else %}
10+
{% set fontStylesheetPath = "/css?family=Open+Sans|Roboto:300,500" %}
11+
{% endif %}
12+
<link rel="preload" as="style" href="{{fontStylesheetHost}}{{fontStylesheetPath}}">
13+
<link rel="preconnect" href="{{fontStylesheetHost}}">
14+
<script>
15+
document.documentElement.className = (/\b(?:Windows|Linux|Android|iPhone|iPad|iPod)\b/.test(navigator.userAgent) ? 'os-not-mac' : 'os-mac') + (/\bOS[_ ]X[_ ]10[._][3-7]\D/.test(navigator.userAgent) ? ' os-old-mac' : '');
16+
function ga(){ga.q.push(arguments)}
17+
ga.q=[];
18+
ga.l=+new Date;
19+
ga('create', 'UA-3088672-5', 'auto');
20+
ga('send', 'pageview');
21+
</script>
22+
{% block styles %}
23+
<link rel="stylesheet" href="style.css">
24+
{% endblock %}
25+
{% block extrastyles %}
26+
{% if inlineStyle %}
27+
<style>{{inlineStyle|safe}}</style>
28+
{% elif inlineStyleFile %}
29+
<link rel="stylesheet" href="{{inlineStyleFile}}">
30+
{% endif %}
31+
{% endblock %}
32+
{% block head %}{% endblock %}
33+
</head>
34+
{% macro contact(label) %} <!-- htmlmin:ignore --> <a
35+
class='email
36+
href="mailto:me"
37+
'
38+
href
39+
= '
40+
&#x20;&#x6d;&#97;i&#108;&#x74;o&#x3a;%20&#37;&#55;0o&#x72;&#110;&#x65;%&#x36;&#x63;&#x25;&#x34;&#x30;&#x70;&#37;6&#102;%7&#x32;&#x6e;e%&#x36;c&#37;2en&#x65;t?
41+
'>{{label}}</a><!-- htmlmin:ignore -->{% endmacro %}
42+
<body>
43+
44+
{% block header %}
45+
<header id="header" {% if 'mac' == current %}class="mac"{% endif %}>
46+
<nav>
47+
<h1><a href="/"><img src="/icon.png" srcset="/[email protected] 2x" width="32" height="32" alt=""> ImageOptim</a></h1>
48+
<a {% if 'mac' == current %}class="current"{% endif %} href="/mac">
49+
{% block topMacApp %}
50+
Mac <span>app</span>
51+
{% endblock %}
52+
</a>
53+
{% if 'other' == current %}
54+
<a class="current">Other <span>versions</span></a>
55+
{% else %}
56+
<a href="/mozjpeg"><span>MozJPEG</span> online</a>
57+
{% endif %}
58+
</nav>
59+
<div class="hero {% if not largeHeader %}compact{% endif %}"><div>
60+
<h2>
61+
{% block h2 %}
62+
{% if not largeHeader %}<a href="/mac">{% endif %}
63+
<span class="brand">ImageOptim</span> makes images load faster
64+
{% endblock %}
65+
{% if not largeHeader %}</a>{% endif %}
66+
</h2>
67+
<p class="sub">
68+
{% block h2sub %}
69+
Removes bloated metadata. Saves disk&nbsp;space &amp;&nbsp;bandwidth by compressing images without&nbsp;losing&nbsp;quality.
70+
{% endblock %}
71+
</p>
72+
{% if largeHeader %}
73+
<div class=download>
74+
<div>
75+
<a class="now" download href="/ImageOptim.tbz2" rel="nofollow">
76+
{% block downloadbutton %}
77+
Download for <span class="not-mac">Mac</span> <span class="mac-only">Free</span>
78+
{% endblock %}
79+
</a>
80+
<a href="/changelog.html">
81+
{% block otherbutton %}
82+
<span class="not-mac">See alternative</span>
83+
<span class="mac-only">Other</span> versions
84+
{% endblock %}
85+
</a>
86+
</div>
87+
<p class="notes">
88+
{% block requirements %}
89+
Requires OS X 10.8+. It's <a href="https://github.com/ImageOptim/ImageOptim">Free and Open Source</a>. <a href="/donate.html">Donate</a>.
90+
{% endblock %}
91+
</p>
92+
<p class="alternate not-mac">Not using a Mac? Check out <a href="https://trimage.org">Trimage</a></p>
93+
</div>
94+
{% endif %}
95+
{% if 'mac' == current %}
96+
{% if not largeHeader %}<a href="/mac">{% endif %}
97+
<img class="screenshot" width="514" height="166" src="ImageOptim.png" srcset="[email protected] 2x" alt="{{"Simple drag'n'drop interface"|t}}">
98+
{% if not largeHeader %}</a>{% endif %}
99+
{% endif %}
100+
</div></div>
101+
</header>
102+
{% endblock %}
103+
104+
{% block body %}{% endblock %}
105+
106+
<footer id="footer"><div>
107+
<p>{{"Created by"|t}} <a rel=author href="https://kornel.ski" class="kornel">Kornel Lesiński</a>. {{ contact("Contact"|t) }}. <a href="https://twitter.com/kornelski">{{"Follow on Twitter"|t}}</a>.
108+
{% block footerextra %}{% endblock %}
109+
</p>
110+
</div></footer>
111+
112+
<script>
113+
document.body.addEventListener('click', function(e) {
114+
var target = e.target;
115+
while(target && target.tagName != 'A') {
116+
target = target.parentNode;
117+
}
118+
if (!target) return;
119+
120+
if (target.hasAttribute('download')) {
121+
localStorage.downloaded = Date.now()+3600*1000;
122+
if (window.showThanks) {
123+
showThanks(true);
124+
setTimeout(function(){history.pushState({}, '', '/howto.html');}, 30000);
125+
}
126+
ga('send', 'pageview', '/download');
127+
ga('send', 'event', 'download', target.pathname);
128+
}
129+
}, false);
130+
</script>
131+
{% block bodyend %}{% endblock %}
132+
133+
<script async src='https://www.google-analytics.com/analytics.js'></script>
134+
<link rel="stylesheet" href="{{fontStylesheetHost}}{{fontStylesheetPath}}">
135+
</body>

pages/_newsletter.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(function(){
2+
if (location.hash == '#newsletter') {
3+
var newsletter = document.getElementById('newsletter');
4+
var c = document.getElementById('header');
5+
c.parentNode.insertBefore(newsletter, c.nextSibling);
6+
function makeNewsletterVisible(){newsletter.scrollIntoView(false);}
7+
makeNewsletterVisible();
8+
addEventListener('load', makeNewsletterVisible, false);
9+
}
10+
})();

pages/_pl.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
Version: Wersja
2+
'Available in:': 'Przetłumaczony na:'
3+
'Download': 'Pobierz'
4+
'Compatible with El Capitan': 'Działa ze El Capitanem'
5+
'Changelog': 'Co nowego?'
6+
'Bugs': 'Zgłoś błędy'
7+
'Source code': 'Kod źródłowy'
8+
'English': 'angielski'
9+
'French': 'francuski'
10+
'German': 'niemiecki'
11+
'Italian': 'włoski'
12+
'Dutch': 'holenderski'
13+
'Russian': 'rosyjski'
14+
'Spanish': 'hiszpański'
15+
'Norwegian': 'norweski'
16+
'Portugese': 'portugalski'
17+
'Belarussian': 'białoruski'
18+
'Danish': 'duński'
19+
'and Polish': 'i polski'
20+
'Donate': 'Wspomóż'
21+
'Portuguese': 'portugalski'
22+
'Swedish': 'szwedzki'
23+
'Japanese': 'japoński'
24+
'Chinese': 'chiński'
25+
'Korean': 'koreański'
26+
'Vietnamese': 'wietnamski'
27+
'Turkish': 'turecki'
28+
'Lithuanian': 'litewski'
29+
'Czech': 'czeski'
30+
'Help translate it!': 'Pomóż w tłumaczeniu!'
31+
"Simple drag'n'drop interface": "Prosty interfejs przeciągnij i upuść"
32+
"Contact": "Kontakt"
33+
"Created by": "Autor: "
34+
"Follow on Twitter": "Obserwuj na Twitterze"
35+
"Beta build": "Wersja beta"
36+
"Old Mac? Download for": "Stary Mac? Pobierz dla"

pages/_sidebar.html

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<aside id="sidebar">
2+
<a rel="nofollow" download itemprop="downloadURL" class="download {% if sidebarDownload %}now{% endif %}" href="/ImageOptim.tbz2">{{'Download'|t}}</a>
3+
<p class="download-info">
4+
{{"Version"|t}} 1.6.0
5+
<br /><span itemprop="requiredFeatures" title="{{'Compatible with El Capitan'|t}}" i18n:attributes="title">Mac OS X 10.8+</span>
6+
</p>
7+
8+
<ul class="links">
9+
<li><a download rel="nofollow" href="/ImageOptim{{betaVersion}}.tar.bz2" class="beta"><strong>{{'Beta build'|t}}</strong> {{betaVersion}}</span></a></li>
10+
<li><a href="/changelog.html" itemprop="versionChanges" class="changelog">{{'Changelog'|t}}</a></li>
11+
<li><a rel="nofollow" download href="/ImageOptim1.5.4.tar.bz2" class="older">{{'Old Mac? Download for'|t}} <strong>Snow Leopard &amp; Lion (10.6-7)</strong></span></a></li>
12+
<li><a href="https://github.com/ImageOptim/ImageOptim/issues" class="bugs">{{'Bugs'|t}}</a></li>
13+
<li><a href="https://github.com/ImageOptim/ImageOptim" class="source">{{'Source code'|t}}</a></li>
14+
<li><a href="/donate.html" class="donate">{{'Donate'|t}}</a></li>
15+
</ul>
16+
{% if sidebarLangs %}
17+
<p class="langs">
18+
<b>{{"Available in:"|t}}</b><br />
19+
<a href="/mac" rel="alternate" hreflang="en">{{'English'|t}}</a>,
20+
<a href="/fr.html" rel="alternate" hreflang="fr">{{'French'|t}}</a>,
21+
<a hreflang="de">{{'German'|t}}</a>,
22+
<a href="/es.html" rel="alternate" hreflang="es">{{'Spanish'|t}}</a>,
23+
<a href="/pt.html" rel="alternate" hreflang="pt">{{'Portuguese'|t}}</a>,
24+
<a href="/it.html" hreflang="it">{{'Italian'|t}}</a>,
25+
<a hreflang="nl">{{'Dutch'|t}}</a>,
26+
<a hreflang="no">{{'Norwegian'|t}}</a>,
27+
<a hreflang="sv">{{'Swedish'|t}}</a>,
28+
<a hreflang="da">{{'Danish'|t}}</a>,
29+
<a hreflang="ja">{{'Japanese'|t}}</a>,
30+
<a hreflang="zh-TW">{{'Chinese'|t}}</a>,
31+
<a hreflang="ko">{{'Korean'|t}}</a>,
32+
<a hreflang="ko">{{'Vietnamese'|t}}</a>,
33+
<a hreflang="tr">{{'Turkish'|t}}</a>,
34+
<a hreflang="ru">{{'Russian'|t}}</a>,
35+
<a hreflang="lt">{{'Lithuanian'|t}}</a>,
36+
<a hreflang="cs">{{'Czech'|t}}</a>
37+
<a href="/pl.html" rel="alternate" hreflang="pl">{{'and Polish'|t}}</a>.
38+
<a href="https://www.transifex.com/projects/p/imageoptim/" rel="nofollow">{{'Help translate it!'|t}}</a>
39+
</p>
40+
{% endif %}
41+
</aside>

pages/_subpage.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% extends "pages/_layout.html" %}
2+
{% block body %}
3+
<section class="sidebarcontainer">
4+
{% set sidebarDownload = true %}
5+
{% set sidebarLangs = false %}
6+
{% include "pages/_sidebar.html" %}
7+
<main>{% block main %}{% endblock %}</main>
8+
</section>
9+
{% endblock %}

0 commit comments

Comments
 (0)