Gatsby → Astro (#829)
* basic astro setup, kick out all gatsby configs * move content folder * src/pages setup * more file reorg * more config updates * more reorgs * refactor * refactor * bump astro * refactor * svg icon build system, theme switch * remark plugin for lead paragraph, more refactor * make images work * post meta * custom Picture component * Pagination, More component, 404 fixes * linking fixes * add table of contents * post actions fixes * tag fixes * content changes * content changes: move media files to their posts * more content moving, remove media folder * refactor remark-lead-paragraph * link css file when defined in post frontmatter * move content up again * kbd post update * allow js * downloads solution * add astro check * redirect_from solution * githubLink solution * reorg * exif solution as prebuild step * exif solution on each post during build * isolate lead paragraph extraction to articles * restore Exif components * deploy script update * fix redirects * xml & json feeds * build fix * fix exif readout in production * head and seo tweaks, add feeds * tweak image display * archive pages with single layout * restore tags archive * sitemap setup * restore thanks page functionality * reorg * cleanup * parallel scripts during prebuild * restore jest setup * remove jest, switch to vitest as test runner * adapt CI * test refactor * typescript tweaks * avatar fixes * typings * restore search functionality * theme switch with nanostores * fixes * test fixes * restore changelog functionality * umami script * border color tweak * related posts with fuse.js * plawright e2e testing setup * search tweaks * simplify typekit loading * photo fix * e2e tests * related posts fix * fix tags archive * tweaks * tweaks * linux snapshots * fix header test * new symlink tactic * fix dev server in codespaces * fix yaml * ci fixes * changelog loading tweaks * e2e against dev server on ci * changelog tweaks * ci tweaks * ci tweaks * ci tweaks * docs updates * ci tweaks * refactor photo creation script * package updates * refactor search * ci tweak * ci tweaks * test tweaks, more unit tests * more unit tests * post creation script tweaks * refactor new scripts, test them for real life * more tests * refactor * codeclimate-action update * uses update * limit ci runs * fix theme toggle, test it * more tests * favicon files cleanup * icon components location change * type checking through ci * command fixes * ci fix * search tweaks * ci tweaks * revised favicons, write post draft about it * drafts filtering fix * lint fix, favicon fixes * copy changes * fix related search images * content updates * new codeblock styles, copy tweaks, fixes * package updates * typing fixes * lint fix * content updates * restore link posts * faster theme switching * split up astro utils * related posts fixes * fix * refactor * fixes * copy tweaks * fixes * picture tweaks * image fixes * feed fixes, adapt for json feed v1.1 * e2e test updates * layout tweaks * update snaphots * migrate to createMarkdownProcessor * ci cache tweaks * activate more browsers for e2e testing * switch to macos-13 images * build caching tweaks * markdown fix * set image quality * remove avif generation * picture tweaks * head fixes * add og:image:alt * create-icons test * new post: Favicon Generation with Astro
55
.config/astro.config.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { defineConfig } from 'astro/config'
|
||||
import remarkLeadParagraph from '../src/lib/remark-lead-paragraph'
|
||||
import remarkToc from '../src/lib/remark-toc'
|
||||
import react from '@astrojs/react'
|
||||
import sitemap from '@astrojs/sitemap'
|
||||
import expressiveCode from 'astro-expressive-code'
|
||||
import redirects from './redirects.json'
|
||||
import config from './blog.config'
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: config.siteUrl,
|
||||
output: 'static',
|
||||
cacheDir: '.astro',
|
||||
markdown: {
|
||||
remarkPlugins: [remarkLeadParagraph, remarkToc as any],
|
||||
shikiConfig: {
|
||||
// https://github.com/shikijs/shiki/blob/main/docs/themes.md
|
||||
theme: 'nord',
|
||||
langs: [],
|
||||
wrap: true
|
||||
}
|
||||
},
|
||||
server: { host: true },
|
||||
redirects,
|
||||
vite: {
|
||||
resolve: {
|
||||
// for making content -> src/content symlink work
|
||||
// https://www.eliostruyf.com/symlink-content-astro-portability/#fix-the-content-issues
|
||||
preserveSymlinks: true
|
||||
}
|
||||
},
|
||||
integrations: [
|
||||
react(),
|
||||
expressiveCode({
|
||||
theme: 'nord',
|
||||
// https://github.com/expressive-code/expressive-code/blob/ad08cf74095b30055e841d59497990fade634c86/packages/%40expressive-code/core/src/common/core-styles.ts
|
||||
styleOverrides: {
|
||||
borderRadius: 'var(--border-radius)',
|
||||
borderWidth: 'var(--border-width)',
|
||||
uiFontFamily: 'var(--font-family-monospace)',
|
||||
uiFontSize: 'var(--font-size-mini)',
|
||||
codeFontFamily: 'var(--font-family-monospace)',
|
||||
codeFontSize: '0.8rem'
|
||||
}
|
||||
}),
|
||||
sitemap({
|
||||
filter: (page) =>
|
||||
!page.includes('page/') &&
|
||||
!page.includes('tags/') &&
|
||||
!page.includes('archive/') &&
|
||||
!page.includes('404')
|
||||
})
|
||||
]
|
||||
})
|
74
.config/aws_redirects.xml
Normal file
@ -0,0 +1,74 @@
|
||||
<!--
|
||||
AWS S3 routing rules for old content
|
||||
needs to be manually added to S3 bucket
|
||||
-->
|
||||
<RoutingRules>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>lab/</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>lab.kremalicious.com</HostName>
|
||||
<ReplaceKeyWith></ReplaceKeyWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>lab</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>lab.kremalicious.com</HostName>
|
||||
<ReplaceKeyWith></ReplaceKeyWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>csspaperstack/</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>lab.kremalicious.com</HostName>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>csspaperstack</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>lab.kremalicious.com</HostName>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>download/</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<ReplaceKeyPrefixWith>media/</ReplaceKeyPrefixWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>feed/</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<ReplaceKeyPrefixWith>feed.xml</ReplaceKeyPrefixWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>portfolio/</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>matthiaskretschmann.com</HostName>
|
||||
<ReplaceKeyWith></ReplaceKeyWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>portfolio</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>matthiaskretschmann.com</HostName>
|
||||
<ReplaceKeyWith></ReplaceKeyWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
</RoutingRules>
|
@ -1,15 +1,11 @@
|
||||
export default {
|
||||
siteTitle: 'kremalicious',
|
||||
siteTitleShort: 'krlc',
|
||||
siteDescription: 'Blog of designer & developer Matthias Kretschmann',
|
||||
siteUrl: 'https://kremalicious.com',
|
||||
themeColor: '#e7eef4',
|
||||
backgroundColor: '#e7eef4',
|
||||
pathPrefix: null,
|
||||
author: {
|
||||
name: 'Matthias Kretschmann',
|
||||
email: 'm@kretschmann.io',
|
||||
uri: 'https://matthiaskretschmann.com',
|
||||
url: 'https://matthiaskretschmann.com',
|
||||
twitter: 'https://twitter.com/kremalicious',
|
||||
mastodon: 'https://mas.to/@krema',
|
||||
github: 'https://github.com/kremalicious',
|
||||
@ -18,7 +14,7 @@ export default {
|
||||
},
|
||||
rss: '/feed.xml',
|
||||
jsonfeed: '/feed.json',
|
||||
itemsPerPage: 24,
|
||||
itemsPerPage: 30,
|
||||
repoContentPath: 'https://github.com/kremalicious/blog/tree/main/content',
|
||||
menu: [
|
||||
{
|
||||
@ -31,7 +27,7 @@ export default {
|
||||
},
|
||||
{
|
||||
title: 'Goodies',
|
||||
link: '/archive/goodies'
|
||||
link: '/tags/goodies'
|
||||
},
|
||||
{
|
||||
title: 'Tags',
|
12
.env.sample
@ -1,7 +1,7 @@
|
||||
GITHUB_TOKEN=xxx
|
||||
GATSBY_MAPBOX_ACCESS_TOKEN=xxx
|
||||
GATSBY_TYPEKIT_ID=xxx
|
||||
GATSBY_UMAMI_SCRIPT_URL=xxx
|
||||
GATSBY_UMAMI_WEBSITE_ID=xxx
|
||||
GATSBY_INFURA_ID=xxx
|
||||
GATSBY_WALLETCONNECT_ID="xxx"
|
||||
PUBLIC_MAPBOX_ACCESS_TOKEN=xxx
|
||||
PUBLIC_TYPEKIT_ID=xxx
|
||||
PUBLIC_UMAMI_SCRIPT_URL=xxx
|
||||
PUBLIC_UMAMI_WEBSITE_ID=xxx
|
||||
PUBLIC_INFURA_ID=xxx
|
||||
PUBLIC_WALLETCONNECT_ID="xxx"
|
@ -1,25 +1,23 @@
|
||||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"es6": true,
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"es2020": true,
|
||||
"jest": true
|
||||
"node": true
|
||||
},
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": { "jsx": true },
|
||||
"project": "./tsconfig.json",
|
||||
"tsconfigRootDir": "./"
|
||||
},
|
||||
"plugins": ["@typescript-eslint", "react"],
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:jsx-a11y/recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:astro/recommended",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"rules": {
|
||||
@ -29,10 +27,23 @@
|
||||
"settings": { "react": { "version": "detect" } },
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"**/__tests__/**/*.[jt]s?(x)",
|
||||
"**/?(*.)+(spec|test).[jt]s?(x)"
|
||||
],
|
||||
// Define the configuration for `.astro` file.
|
||||
"files": ["*.astro"],
|
||||
// Allows Astro components to be parsed.
|
||||
"parser": "astro-eslint-parser",
|
||||
// Parse the script in `.astro` as TypeScript by adding the following configuration.
|
||||
// It's the setting you need when using TypeScript.
|
||||
"parserOptions": {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extraFileExtensions": [".astro"]
|
||||
},
|
||||
"rules": {
|
||||
// override/add rules settings here, such as:
|
||||
// "astro/no-set-html-directive": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["**/?(*.)+(spec|test).[jt]sx"],
|
||||
"extends": ["plugin:testing-library/react"],
|
||||
"rules": {
|
||||
"testing-library/no-node-access": "off",
|
149
.github/workflows/ci.yml
vendored
@ -8,88 +8,137 @@ on:
|
||||
branches:
|
||||
- '**'
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PUBLIC_TYPEKIT_ID: ${{ secrets.GATSBY_TYPEKIT_ID }}
|
||||
PUBLIC_MAPBOX_ACCESS_TOKEN: ${{ secrets.GATSBY_MAPBOX_ACCESS_TOKEN }}
|
||||
PUBLIC_UMAMI_SCRIPT_URL: ${{ secrets.GATSBY_UMAMI_SCRIPT_URL }}
|
||||
PUBLIC_UMAMI_WEBSITE_ID: ${{ secrets.GATSBY_UMAMI_WEBSITE_ID }}
|
||||
PUBLIC_INFURA_ID: ${{ secrets.GATSBY_INFURA_ID }}
|
||||
PUBLIC_WALLETCONNECT_ID: ${{ secrets.GATSBY_WALLETCONNECT_ID }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
lint:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-13]
|
||||
node: ['18']
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: ${{ runner.os }}-node-
|
||||
|
||||
- name: Cache Gatsby Cache Folder
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .cache
|
||||
key: ${{ runner.os }}-cache-gatsby
|
||||
restore-keys: ${{ runner.os }}-cache-gatsby
|
||||
|
||||
- name: Cache Gatsby Public Folder
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: public/
|
||||
key: ${{ runner.os }}-public-gatsby
|
||||
restore-keys: ${{ runner.os }}-public-gatsby
|
||||
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GATSBY_TYPEKIT_ID: ${{ secrets.GATSBY_TYPEKIT_ID }}
|
||||
GATSBY_MAPBOX_ACCESS_TOKEN: ${{ secrets.GATSBY_MAPBOX_ACCESS_TOKEN }}
|
||||
GATSBY_UMAMI_SCRIPT_URL: ${{ secrets.GATSBY_UMAMI_SCRIPT_URL }}
|
||||
GATSBY_UMAMI_WEBSITE_ID: ${{ secrets.GATSBY_UMAMI_WEBSITE_ID }}
|
||||
GATSBY_INFURA_ID: ${{ secrets.GATSBY_INFURA_ID }}
|
||||
- run: npm test
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GATSBY_TYPEKIT_ID: ${{ secrets.GATSBY_TYPEKIT_ID }}
|
||||
GATSBY_MAPBOX_ACCESS_TOKEN: ${{ secrets.GATSBY_MAPBOX_ACCESS_TOKEN }}
|
||||
GATSBY_UMAMI_SCRIPT_URL: ${{ secrets.GATSBY_UMAMI_SCRIPT_URL }}
|
||||
GATSBY_UMAMI_WEBSITE_ID: ${{ secrets.GATSBY_UMAMI_WEBSITE_ID }}
|
||||
GATSBY_INFURA_ID: ${{ secrets.GATSBY_INFURA_ID }}
|
||||
- run: npm run lint
|
||||
|
||||
typecheck:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-13]
|
||||
node: ['18']
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- run: npm run prebuild
|
||||
- run: npm run typecheck
|
||||
|
||||
test-unit:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-13]
|
||||
node: ['18']
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- run: npm run test:unit
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: coverage
|
||||
name: coverage-${{ matrix.os }}-${{ matrix.node }}
|
||||
path: coverage/
|
||||
|
||||
test-e2e:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node: ['18']
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- run: npx playwright install --with-deps
|
||||
- run: npm run test:e2e
|
||||
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-13]
|
||||
node: ['18']
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: 'npm'
|
||||
- name: Cache Astro build output
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ github.workspace }}/.astro
|
||||
key: ${{ matrix.os }}-${{ matrix.node }}-astro-build-${{ hashFiles('content/**/*.jpg', 'content/**/*.png') }}
|
||||
restore-keys: ${{ matrix.os }}-${{ matrix.node }}-astro-build-
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- uses: actions/upload-artifact@v1
|
||||
if: github.ref == 'refs/heads/main'
|
||||
with:
|
||||
name: public
|
||||
path: public
|
||||
name: dist-${{ matrix.os }}-${{ matrix.node }}
|
||||
path: dist
|
||||
|
||||
coverage:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test]
|
||||
needs: [test-unit]
|
||||
if: ${{ success() && github.actor != 'dependabot[bot]' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: coverage
|
||||
- uses: paambaati/codeclimate-action@v2.7.5
|
||||
name: coverage-ubuntu-latest-18
|
||||
- uses: paambaati/codeclimate-action@v5.0.0
|
||||
env:
|
||||
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
||||
|
||||
deploy:
|
||||
needs: test
|
||||
needs: [lint, typecheck, test-unit, test-e2e, build]
|
||||
if: success() && github.ref == 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/download-artifact@v1
|
||||
with:
|
||||
name: public
|
||||
name: dist-ubuntu-latest-18
|
||||
- name: Deploy to S3
|
||||
run: npm run deploy:s3
|
||||
env:
|
||||
|
2
.github/workflows/codeql-analysis.yml
vendored
@ -32,7 +32,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: ['javascript']
|
||||
language: ['javascript', 'typescript']
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||
|
||||
|
22
.gitignore
vendored
@ -1,10 +1,26 @@
|
||||
node_modules
|
||||
.yarnclean
|
||||
public
|
||||
.cache
|
||||
plugins/gatsby-redirect-from
|
||||
coverage
|
||||
.env
|
||||
.env.development
|
||||
.nova
|
||||
src/@types/Gatsby.d.ts
|
||||
|
||||
# build output
|
||||
dist/
|
||||
src/images/components/
|
||||
|
||||
# generated types
|
||||
.astro/
|
||||
|
||||
# autogenerated stuff
|
||||
public/get/
|
||||
src/content/
|
||||
src/content
|
||||
public/post-kbd.css
|
||||
.config/redirects.json
|
||||
test-results/
|
||||
playwright-report/
|
||||
playwright/.cache/
|
||||
**/tmp/
|
||||
public/theme.js
|
||||
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"avatar": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"childImageSharp": {
|
||||
"fixed": {
|
||||
"aspectRatio": 1,
|
||||
"width": 80,
|
||||
"height": 80,
|
||||
"src": "/static/b61a09d5f4cbd9d8b2844091590ddea4/fce1d/avatar.jpg",
|
||||
"srcSet": "/static/b61a09d5f4cbd9d8b2844091590ddea4/fce1d/avatar.jpg 1x,\n/static/b61a09d5f4cbd9d8b2844091590ddea4/c4de8/avatar.jpg 1.5x,\n/static/b61a09d5f4cbd9d8b2844091590ddea4/c3234/avatar.jpg 2x",
|
||||
"srcWebp": "/static/b61a09d5f4cbd9d8b2844091590ddea4/ad6b8/avatar.webp",
|
||||
"srcSetWebp": "/static/b61a09d5f4cbd9d8b2844091590ddea4/ad6b8/avatar.webp 1x,\n/static/b61a09d5f4cbd9d8b2844091590ddea4/5c322/avatar.webp 1.5x,\n/static/b61a09d5f4cbd9d8b2844091590ddea4/5bf6b/avatar.webp 2x",
|
||||
"originalName": "avatar.jpg"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,523 +0,0 @@
|
||||
{
|
||||
"latestArticles": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "108cdbf6-2442-54b5-887c-aad821fba6c2",
|
||||
"fileAbsolutePath": "/Users/m/Code/blog/content/articles/2020-05-22-gatsby-redirect-from/index.md",
|
||||
"frontmatter": {
|
||||
"title": "Redirect plugin for Markdown Pages in Gatsby",
|
||||
"linkurl": null,
|
||||
"updated": "2020-05-23T09:35:12.000Z",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/gatsby-redirect-from-teaser-0d31de44f593361b78d2af6a9c030de3.png"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 3,
|
||||
"src": "/static/0d31de44f593361b78d2af6a9c030de3/7547c/gatsby-redirect-from-teaser.png",
|
||||
"srcSet": "/static/0d31de44f593361b78d2af6a9c030de3/f353c/gatsby-redirect-from-teaser.png 105w,\n/static/0d31de44f593361b78d2af6a9c030de3/45430/gatsby-redirect-from-teaser.png 210w,\n/static/0d31de44f593361b78d2af6a9c030de3/7547c/gatsby-redirect-from-teaser.png 420w,\n/static/0d31de44f593361b78d2af6a9c030de3/4f753/gatsby-redirect-from-teaser.png 630w,\n/static/0d31de44f593361b78d2af6a9c030de3/60369/gatsby-redirect-from-teaser.png 840w,\n/static/0d31de44f593361b78d2af6a9c030de3/6364d/gatsby-redirect-from-teaser.png 1880w",
|
||||
"srcWebp": "/static/0d31de44f593361b78d2af6a9c030de3/8a0fd/gatsby-redirect-from-teaser.webp",
|
||||
"srcSetWebp": "/static/0d31de44f593361b78d2af6a9c030de3/2aec1/gatsby-redirect-from-teaser.webp 105w,\n/static/0d31de44f593361b78d2af6a9c030de3/74e55/gatsby-redirect-from-teaser.webp 210w,\n/static/0d31de44f593361b78d2af6a9c030de3/8a0fd/gatsby-redirect-from-teaser.webp 420w,\n/static/0d31de44f593361b78d2af6a9c030de3/70212/gatsby-redirect-from-teaser.webp 630w,\n/static/0d31de44f593361b78d2af6a9c030de3/a9b7e/gatsby-redirect-from-teaser.webp 840w,\n/static/0d31de44f593361b78d2af6a9c030de3/b6972/gatsby-redirect-from-teaser.webp 1880w",
|
||||
"sizes": "(max-width: 420px) 100vw, 420px"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": ["goodies", "gatsby", "development"]
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/gatsby-redirect-from",
|
||||
"date": "2020-05-22T14:08:00.367Z",
|
||||
"type": "article"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "cf701f60-bbb5-544f-bb13-97aa884b7ad7",
|
||||
"fileAbsolutePath": "/Users/m/Code/blog/content/articles/2020-05-08-uses/index.md",
|
||||
"frontmatter": {
|
||||
"title": "/uses",
|
||||
"linkurl": null,
|
||||
"updated": "2020-07-30T13:58:12.000Z",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/uses-teaser-dfb23ab7203b0f61b838c98f23ea7852.png"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 3,
|
||||
"src": "/static/dfb23ab7203b0f61b838c98f23ea7852/7547c/uses-teaser.png",
|
||||
"srcSet": "/static/dfb23ab7203b0f61b838c98f23ea7852/f353c/uses-teaser.png 105w,\n/static/dfb23ab7203b0f61b838c98f23ea7852/45430/uses-teaser.png 210w,\n/static/dfb23ab7203b0f61b838c98f23ea7852/7547c/uses-teaser.png 420w,\n/static/dfb23ab7203b0f61b838c98f23ea7852/4f753/uses-teaser.png 630w,\n/static/dfb23ab7203b0f61b838c98f23ea7852/60369/uses-teaser.png 840w,\n/static/dfb23ab7203b0f61b838c98f23ea7852/6364d/uses-teaser.png 1880w",
|
||||
"srcWebp": "/static/dfb23ab7203b0f61b838c98f23ea7852/8a0fd/uses-teaser.webp",
|
||||
"srcSetWebp": "/static/dfb23ab7203b0f61b838c98f23ea7852/2aec1/uses-teaser.webp 105w,\n/static/dfb23ab7203b0f61b838c98f23ea7852/74e55/uses-teaser.webp 210w,\n/static/dfb23ab7203b0f61b838c98f23ea7852/8a0fd/uses-teaser.webp 420w,\n/static/dfb23ab7203b0f61b838c98f23ea7852/70212/uses-teaser.webp 630w,\n/static/dfb23ab7203b0f61b838c98f23ea7852/a9b7e/uses-teaser.webp 840w,\n/static/dfb23ab7203b0f61b838c98f23ea7852/b6972/uses-teaser.webp 1880w",
|
||||
"sizes": "(max-width: 420px) 100vw, 420px"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"personal",
|
||||
"macos",
|
||||
"ios",
|
||||
"mac",
|
||||
"iphone",
|
||||
"design",
|
||||
"development"
|
||||
]
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/uses",
|
||||
"date": "2020-05-10T21:51:12.000Z",
|
||||
"type": "article"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "d7662b67-4a20-52af-a847-9c4debcf1cec",
|
||||
"fileAbsolutePath": "/Users/m/Code/blog/content/articles/2020-03-04-raspberry-pi-file-and-screen-sharing-macos-ios/index.md",
|
||||
"frontmatter": {
|
||||
"title": "Setup Raspberry Pi File and Screen Sharing for macOS & iOS",
|
||||
"linkurl": null,
|
||||
"updated": null,
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/raspberry-pi-file-and-screen-sharing-macos-ios-teaser-a5f639b239acd8c475ff7dd3844508e8.png"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 3,
|
||||
"src": "/static/a5f639b239acd8c475ff7dd3844508e8/7547c/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.png",
|
||||
"srcSet": "/static/a5f639b239acd8c475ff7dd3844508e8/f353c/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.png 105w,\n/static/a5f639b239acd8c475ff7dd3844508e8/45430/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.png 210w,\n/static/a5f639b239acd8c475ff7dd3844508e8/7547c/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.png 420w,\n/static/a5f639b239acd8c475ff7dd3844508e8/4f753/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.png 630w,\n/static/a5f639b239acd8c475ff7dd3844508e8/60369/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.png 840w,\n/static/a5f639b239acd8c475ff7dd3844508e8/6364d/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.png 1880w",
|
||||
"srcWebp": "/static/a5f639b239acd8c475ff7dd3844508e8/8a0fd/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.webp",
|
||||
"srcSetWebp": "/static/a5f639b239acd8c475ff7dd3844508e8/2aec1/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.webp 105w,\n/static/a5f639b239acd8c475ff7dd3844508e8/74e55/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.webp 210w,\n/static/a5f639b239acd8c475ff7dd3844508e8/8a0fd/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.webp 420w,\n/static/a5f639b239acd8c475ff7dd3844508e8/70212/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.webp 630w,\n/static/a5f639b239acd8c475ff7dd3844508e8/a9b7e/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.webp 840w,\n/static/a5f639b239acd8c475ff7dd3844508e8/b6972/raspberry-pi-file-and-screen-sharing-macos-ios-teaser.webp 1880w",
|
||||
"sizes": "(max-width: 420px) 100vw, 420px"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"macos",
|
||||
"ios",
|
||||
"linux",
|
||||
"raspberrypi",
|
||||
"ubuntu",
|
||||
"tutorial",
|
||||
"avahi"
|
||||
]
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/raspberry-pi-file-and-screen-sharing-macos-ios",
|
||||
"date": "2020-03-04T18:35:26.815Z",
|
||||
"type": "article"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "9acfbf40-a90a-56c3-ab08-b98be93bcd9a",
|
||||
"fileAbsolutePath": "/Users/m/Code/blog/content/articles/2019-10-24-ocean-protocol-and-ipfs-sitting-in-the-merkle-tree/index.md",
|
||||
"frontmatter": {
|
||||
"title": "Ocean Protocol and IPFS, Sitting In The Merkle Tree",
|
||||
"linkurl": null,
|
||||
"updated": null,
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser-f724bdaae38e81ec90b01ec6b8412cc8.png"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 3,
|
||||
"src": "/static/f724bdaae38e81ec90b01ec6b8412cc8/7547c/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.png",
|
||||
"srcSet": "/static/f724bdaae38e81ec90b01ec6b8412cc8/f353c/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.png 105w,\n/static/f724bdaae38e81ec90b01ec6b8412cc8/45430/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.png 210w,\n/static/f724bdaae38e81ec90b01ec6b8412cc8/7547c/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.png 420w,\n/static/f724bdaae38e81ec90b01ec6b8412cc8/4f753/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.png 630w,\n/static/f724bdaae38e81ec90b01ec6b8412cc8/60369/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.png 840w,\n/static/f724bdaae38e81ec90b01ec6b8412cc8/766ad/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.png 2000w",
|
||||
"srcWebp": "/static/f724bdaae38e81ec90b01ec6b8412cc8/8a0fd/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.webp",
|
||||
"srcSetWebp": "/static/f724bdaae38e81ec90b01ec6b8412cc8/2aec1/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.webp 105w,\n/static/f724bdaae38e81ec90b01ec6b8412cc8/74e55/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.webp 210w,\n/static/f724bdaae38e81ec90b01ec6b8412cc8/8a0fd/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.webp 420w,\n/static/f724bdaae38e81ec90b01ec6b8412cc8/70212/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.webp 630w,\n/static/f724bdaae38e81ec90b01ec6b8412cc8/a9b7e/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.webp 840w,\n/static/f724bdaae38e81ec90b01ec6b8412cc8/52dbc/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree-teaser.webp 2000w",
|
||||
"sizes": "(max-width: 420px) 100vw, 420px"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"oceanprotocol",
|
||||
"blockchain",
|
||||
"design",
|
||||
"development",
|
||||
"ipfs",
|
||||
"web3"
|
||||
]
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/ocean-protocol-and-ipfs-sitting-in-the-merkle-tree",
|
||||
"date": "2019-10-24T00:00:00.000Z",
|
||||
"type": "article"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "45d2cb0a-5f77-5726-86d7-72b38b6c8024",
|
||||
"fileAbsolutePath": "/Users/m/Code/blog/content/articles/2019-07-18-the-commons-marketplace-in-pacific-network/index.md",
|
||||
"frontmatter": {
|
||||
"title": "The Commons Marketplace in Pacific Network",
|
||||
"linkurl": null,
|
||||
"updated": null,
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/the-commons-marketplace-in-pacific-network-teaser-2db57438c9f98018d8b61d9224d3fb77.png"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 3,
|
||||
"src": "/static/2db57438c9f98018d8b61d9224d3fb77/7547c/the-commons-marketplace-in-pacific-network-teaser.png",
|
||||
"srcSet": "/static/2db57438c9f98018d8b61d9224d3fb77/f353c/the-commons-marketplace-in-pacific-network-teaser.png 105w,\n/static/2db57438c9f98018d8b61d9224d3fb77/45430/the-commons-marketplace-in-pacific-network-teaser.png 210w,\n/static/2db57438c9f98018d8b61d9224d3fb77/7547c/the-commons-marketplace-in-pacific-network-teaser.png 420w,\n/static/2db57438c9f98018d8b61d9224d3fb77/4f753/the-commons-marketplace-in-pacific-network-teaser.png 630w,\n/static/2db57438c9f98018d8b61d9224d3fb77/60369/the-commons-marketplace-in-pacific-network-teaser.png 840w,\n/static/2db57438c9f98018d8b61d9224d3fb77/fe119/the-commons-marketplace-in-pacific-network-teaser.png 2762w",
|
||||
"srcWebp": "/static/2db57438c9f98018d8b61d9224d3fb77/8a0fd/the-commons-marketplace-in-pacific-network-teaser.webp",
|
||||
"srcSetWebp": "/static/2db57438c9f98018d8b61d9224d3fb77/2aec1/the-commons-marketplace-in-pacific-network-teaser.webp 105w,\n/static/2db57438c9f98018d8b61d9224d3fb77/74e55/the-commons-marketplace-in-pacific-network-teaser.webp 210w,\n/static/2db57438c9f98018d8b61d9224d3fb77/8a0fd/the-commons-marketplace-in-pacific-network-teaser.webp 420w,\n/static/2db57438c9f98018d8b61d9224d3fb77/70212/the-commons-marketplace-in-pacific-network-teaser.webp 630w,\n/static/2db57438c9f98018d8b61d9224d3fb77/a9b7e/the-commons-marketplace-in-pacific-network-teaser.webp 840w,\n/static/2db57438c9f98018d8b61d9224d3fb77/dc0ca/the-commons-marketplace-in-pacific-network-teaser.webp 2762w",
|
||||
"sizes": "(max-width: 420px) 100vw, 420px"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
"oceanprotocol",
|
||||
"blockchain",
|
||||
"design",
|
||||
"development",
|
||||
"web3"
|
||||
]
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/the-commons-marketplace-in-pacific-network",
|
||||
"date": "2019-07-18T00:00:00.000Z",
|
||||
"type": "article"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"latestPhotos": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "5f4558ee-381e-5fb0-9c0e-b60115b6e22e",
|
||||
"frontmatter": {
|
||||
"title": "The Light That Never Goes Out",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2020-02-14-the-light-that-never-goes-out-a389a64d6f51e45fa8e0a7ea98f85fa4.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/a389a64d6f51e45fa8e0a7ea98f85fa4/0f41b/2020-02-14-the-light-that-never-goes-out.jpg",
|
||||
"srcSet": "/static/a389a64d6f51e45fa8e0a7ea98f85fa4/73124/2020-02-14-the-light-that-never-goes-out.jpg 75w,\n/static/a389a64d6f51e45fa8e0a7ea98f85fa4/712e7/2020-02-14-the-light-that-never-goes-out.jpg 150w,\n/static/a389a64d6f51e45fa8e0a7ea98f85fa4/0f41b/2020-02-14-the-light-that-never-goes-out.jpg 300w,\n/static/a389a64d6f51e45fa8e0a7ea98f85fa4/270e8/2020-02-14-the-light-that-never-goes-out.jpg 450w,\n/static/a389a64d6f51e45fa8e0a7ea98f85fa4/aa95b/2020-02-14-the-light-that-never-goes-out.jpg 600w,\n/static/a389a64d6f51e45fa8e0a7ea98f85fa4/37b83/2020-02-14-the-light-that-never-goes-out.jpg 2772w",
|
||||
"srcWebp": "/static/a389a64d6f51e45fa8e0a7ea98f85fa4/40e2f/2020-02-14-the-light-that-never-goes-out.webp",
|
||||
"srcSetWebp": "/static/a389a64d6f51e45fa8e0a7ea98f85fa4/37dc9/2020-02-14-the-light-that-never-goes-out.webp 75w,\n/static/a389a64d6f51e45fa8e0a7ea98f85fa4/37a2a/2020-02-14-the-light-that-never-goes-out.webp 150w,\n/static/a389a64d6f51e45fa8e0a7ea98f85fa4/40e2f/2020-02-14-the-light-that-never-goes-out.webp 300w,\n/static/a389a64d6f51e45fa8e0a7ea98f85fa4/6a707/2020-02-14-the-light-that-never-goes-out.webp 450w,\n/static/a389a64d6f51e45fa8e0a7ea98f85fa4/bf714/2020-02-14-the-light-that-never-goes-out.webp 600w,\n/static/a389a64d6f51e45fa8e0a7ea98f85fa4/0a795/2020-02-14-the-light-that-never-goes-out.webp 2772w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/the-light-that-never-goes-out",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "8c2d7d7e-3799-5f1e-8499-922d58a636ee",
|
||||
"frontmatter": {
|
||||
"title": "Balloon Dog",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2020-01-17-balloon-dog-28916b152705a4f518c85519b6c1822b.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/28916b152705a4f518c85519b6c1822b/0f41b/2020-01-17-balloon-dog.jpg",
|
||||
"srcSet": "/static/28916b152705a4f518c85519b6c1822b/73124/2020-01-17-balloon-dog.jpg 75w,\n/static/28916b152705a4f518c85519b6c1822b/712e7/2020-01-17-balloon-dog.jpg 150w,\n/static/28916b152705a4f518c85519b6c1822b/0f41b/2020-01-17-balloon-dog.jpg 300w,\n/static/28916b152705a4f518c85519b6c1822b/270e8/2020-01-17-balloon-dog.jpg 450w,\n/static/28916b152705a4f518c85519b6c1822b/aa95b/2020-01-17-balloon-dog.jpg 600w,\n/static/28916b152705a4f518c85519b6c1822b/d5887/2020-01-17-balloon-dog.jpg 2792w",
|
||||
"srcWebp": "/static/28916b152705a4f518c85519b6c1822b/40e2f/2020-01-17-balloon-dog.webp",
|
||||
"srcSetWebp": "/static/28916b152705a4f518c85519b6c1822b/37dc9/2020-01-17-balloon-dog.webp 75w,\n/static/28916b152705a4f518c85519b6c1822b/37a2a/2020-01-17-balloon-dog.webp 150w,\n/static/28916b152705a4f518c85519b6c1822b/40e2f/2020-01-17-balloon-dog.webp 300w,\n/static/28916b152705a4f518c85519b6c1822b/6a707/2020-01-17-balloon-dog.webp 450w,\n/static/28916b152705a4f518c85519b6c1822b/bf714/2020-01-17-balloon-dog.webp 600w,\n/static/28916b152705a4f518c85519b6c1822b/57701/2020-01-17-balloon-dog.webp 2792w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/balloon-dog",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "a1cd842c-4755-508e-9709-2daabeb783a4",
|
||||
"frontmatter": {
|
||||
"title": "Bremen Cathedral",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2020-01-17-bremen-cathedral-7203580f941ea9a9b0a27d6f41686724.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/7203580f941ea9a9b0a27d6f41686724/0f41b/2020-01-17-bremen-cathedral.jpg",
|
||||
"srcSet": "/static/7203580f941ea9a9b0a27d6f41686724/73124/2020-01-17-bremen-cathedral.jpg 75w,\n/static/7203580f941ea9a9b0a27d6f41686724/712e7/2020-01-17-bremen-cathedral.jpg 150w,\n/static/7203580f941ea9a9b0a27d6f41686724/0f41b/2020-01-17-bremen-cathedral.jpg 300w,\n/static/7203580f941ea9a9b0a27d6f41686724/270e8/2020-01-17-bremen-cathedral.jpg 450w,\n/static/7203580f941ea9a9b0a27d6f41686724/aa95b/2020-01-17-bremen-cathedral.jpg 600w,\n/static/7203580f941ea9a9b0a27d6f41686724/ffda5/2020-01-17-bremen-cathedral.jpg 3115w",
|
||||
"srcWebp": "/static/7203580f941ea9a9b0a27d6f41686724/40e2f/2020-01-17-bremen-cathedral.webp",
|
||||
"srcSetWebp": "/static/7203580f941ea9a9b0a27d6f41686724/37dc9/2020-01-17-bremen-cathedral.webp 75w,\n/static/7203580f941ea9a9b0a27d6f41686724/37a2a/2020-01-17-bremen-cathedral.webp 150w,\n/static/7203580f941ea9a9b0a27d6f41686724/40e2f/2020-01-17-bremen-cathedral.webp 300w,\n/static/7203580f941ea9a9b0a27d6f41686724/6a707/2020-01-17-bremen-cathedral.webp 450w,\n/static/7203580f941ea9a9b0a27d6f41686724/bf714/2020-01-17-bremen-cathedral.webp 600w,\n/static/7203580f941ea9a9b0a27d6f41686724/ba27b/2020-01-17-bremen-cathedral.webp 3115w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/bremen-cathedral",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "82a3ca09-ff38-5c2a-8b4f-6f5150d9448e",
|
||||
"frontmatter": {
|
||||
"title": "RAW Gelände",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2020-01-05-raw-gelande-6d40de77304f8a335d88447d16125e5a.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/6d40de77304f8a335d88447d16125e5a/0f41b/2020-01-05-raw-gelande.jpg",
|
||||
"srcSet": "/static/6d40de77304f8a335d88447d16125e5a/73124/2020-01-05-raw-gelande.jpg 75w,\n/static/6d40de77304f8a335d88447d16125e5a/712e7/2020-01-05-raw-gelande.jpg 150w,\n/static/6d40de77304f8a335d88447d16125e5a/0f41b/2020-01-05-raw-gelande.jpg 300w,\n/static/6d40de77304f8a335d88447d16125e5a/270e8/2020-01-05-raw-gelande.jpg 450w,\n/static/6d40de77304f8a335d88447d16125e5a/aa95b/2020-01-05-raw-gelande.jpg 600w,\n/static/6d40de77304f8a335d88447d16125e5a/30037/2020-01-05-raw-gelande.jpg 3024w",
|
||||
"srcWebp": "/static/6d40de77304f8a335d88447d16125e5a/40e2f/2020-01-05-raw-gelande.webp",
|
||||
"srcSetWebp": "/static/6d40de77304f8a335d88447d16125e5a/37dc9/2020-01-05-raw-gelande.webp 75w,\n/static/6d40de77304f8a335d88447d16125e5a/37a2a/2020-01-05-raw-gelande.webp 150w,\n/static/6d40de77304f8a335d88447d16125e5a/40e2f/2020-01-05-raw-gelande.webp 300w,\n/static/6d40de77304f8a335d88447d16125e5a/6a707/2020-01-05-raw-gelande.webp 450w,\n/static/6d40de77304f8a335d88447d16125e5a/bf714/2020-01-05-raw-gelande.webp 600w,\n/static/6d40de77304f8a335d88447d16125e5a/859d2/2020-01-05-raw-gelande.webp 3024w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/raw-gelande",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "7c499977-3837-54bd-a8e9-945fb0e5c04a",
|
||||
"frontmatter": {
|
||||
"title": "Helmut Newton Foundation",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2019-11-16-helmut-newton-foundation-d5cf288572434a487b055397b4cec51b.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/d5cf288572434a487b055397b4cec51b/0f41b/2019-11-16-helmut-newton-foundation.jpg",
|
||||
"srcSet": "/static/d5cf288572434a487b055397b4cec51b/73124/2019-11-16-helmut-newton-foundation.jpg 75w,\n/static/d5cf288572434a487b055397b4cec51b/712e7/2019-11-16-helmut-newton-foundation.jpg 150w,\n/static/d5cf288572434a487b055397b4cec51b/0f41b/2019-11-16-helmut-newton-foundation.jpg 300w,\n/static/d5cf288572434a487b055397b4cec51b/270e8/2019-11-16-helmut-newton-foundation.jpg 450w,\n/static/d5cf288572434a487b055397b4cec51b/aa95b/2019-11-16-helmut-newton-foundation.jpg 600w,\n/static/d5cf288572434a487b055397b4cec51b/d3f44/2019-11-16-helmut-newton-foundation.jpg 3620w",
|
||||
"srcWebp": "/static/d5cf288572434a487b055397b4cec51b/40e2f/2019-11-16-helmut-newton-foundation.webp",
|
||||
"srcSetWebp": "/static/d5cf288572434a487b055397b4cec51b/37dc9/2019-11-16-helmut-newton-foundation.webp 75w,\n/static/d5cf288572434a487b055397b4cec51b/37a2a/2019-11-16-helmut-newton-foundation.webp 150w,\n/static/d5cf288572434a487b055397b4cec51b/40e2f/2019-11-16-helmut-newton-foundation.webp 300w,\n/static/d5cf288572434a487b055397b4cec51b/6a707/2019-11-16-helmut-newton-foundation.webp 450w,\n/static/d5cf288572434a487b055397b4cec51b/bf714/2019-11-16-helmut-newton-foundation.webp 600w,\n/static/d5cf288572434a487b055397b4cec51b/40f07/2019-11-16-helmut-newton-foundation.webp 3620w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/helmut-newton-foundation",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "bbf028a7-0973-5d1e-8099-d6409936e73e",
|
||||
"frontmatter": {
|
||||
"title": "Országház III",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2019-11-03-orszaghaz-iii-7c4460abda635fd1de2856343196a260.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/7c4460abda635fd1de2856343196a260/0f41b/2019-11-03-orszaghaz-iii.jpg",
|
||||
"srcSet": "/static/7c4460abda635fd1de2856343196a260/73124/2019-11-03-orszaghaz-iii.jpg 75w,\n/static/7c4460abda635fd1de2856343196a260/712e7/2019-11-03-orszaghaz-iii.jpg 150w,\n/static/7c4460abda635fd1de2856343196a260/0f41b/2019-11-03-orszaghaz-iii.jpg 300w,\n/static/7c4460abda635fd1de2856343196a260/270e8/2019-11-03-orszaghaz-iii.jpg 450w,\n/static/7c4460abda635fd1de2856343196a260/aa95b/2019-11-03-orszaghaz-iii.jpg 600w,\n/static/7c4460abda635fd1de2856343196a260/9ce23/2019-11-03-orszaghaz-iii.jpg 3813w",
|
||||
"srcWebp": "/static/7c4460abda635fd1de2856343196a260/40e2f/2019-11-03-orszaghaz-iii.webp",
|
||||
"srcSetWebp": "/static/7c4460abda635fd1de2856343196a260/37dc9/2019-11-03-orszaghaz-iii.webp 75w,\n/static/7c4460abda635fd1de2856343196a260/37a2a/2019-11-03-orszaghaz-iii.webp 150w,\n/static/7c4460abda635fd1de2856343196a260/40e2f/2019-11-03-orszaghaz-iii.webp 300w,\n/static/7c4460abda635fd1de2856343196a260/6a707/2019-11-03-orszaghaz-iii.webp 450w,\n/static/7c4460abda635fd1de2856343196a260/bf714/2019-11-03-orszaghaz-iii.webp 600w,\n/static/7c4460abda635fd1de2856343196a260/e9670/2019-11-03-orszaghaz-iii.webp 3813w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/orszaghaz-iii",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "6effe45d-0884-527c-9fba-6f7f567979fd",
|
||||
"frontmatter": {
|
||||
"title": "Országház II",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2019-11-03-orszaghaz-ii-2dbcf257b4bdf625c24fede935d32425.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/2dbcf257b4bdf625c24fede935d32425/0f41b/2019-11-03-orszaghaz-ii.jpg",
|
||||
"srcSet": "/static/2dbcf257b4bdf625c24fede935d32425/73124/2019-11-03-orszaghaz-ii.jpg 75w,\n/static/2dbcf257b4bdf625c24fede935d32425/712e7/2019-11-03-orszaghaz-ii.jpg 150w,\n/static/2dbcf257b4bdf625c24fede935d32425/0f41b/2019-11-03-orszaghaz-ii.jpg 300w,\n/static/2dbcf257b4bdf625c24fede935d32425/270e8/2019-11-03-orszaghaz-ii.jpg 450w,\n/static/2dbcf257b4bdf625c24fede935d32425/aa95b/2019-11-03-orszaghaz-ii.jpg 600w,\n/static/2dbcf257b4bdf625c24fede935d32425/d1a04/2019-11-03-orszaghaz-ii.jpg 3793w",
|
||||
"srcWebp": "/static/2dbcf257b4bdf625c24fede935d32425/40e2f/2019-11-03-orszaghaz-ii.webp",
|
||||
"srcSetWebp": "/static/2dbcf257b4bdf625c24fede935d32425/37dc9/2019-11-03-orszaghaz-ii.webp 75w,\n/static/2dbcf257b4bdf625c24fede935d32425/37a2a/2019-11-03-orszaghaz-ii.webp 150w,\n/static/2dbcf257b4bdf625c24fede935d32425/40e2f/2019-11-03-orszaghaz-ii.webp 300w,\n/static/2dbcf257b4bdf625c24fede935d32425/6a707/2019-11-03-orszaghaz-ii.webp 450w,\n/static/2dbcf257b4bdf625c24fede935d32425/bf714/2019-11-03-orszaghaz-ii.webp 600w,\n/static/2dbcf257b4bdf625c24fede935d32425/90141/2019-11-03-orszaghaz-ii.webp 3793w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/orszaghaz-ii",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "c80697e5-681d-5fcc-9dab-c3a3821ff0b1",
|
||||
"frontmatter": {
|
||||
"title": "Országház I",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2019-11-02-orszaghaz-i-36d87329aeeda296ae923606e5a4a785.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/36d87329aeeda296ae923606e5a4a785/0f41b/2019-11-02-orszaghaz-i.jpg",
|
||||
"srcSet": "/static/36d87329aeeda296ae923606e5a4a785/73124/2019-11-02-orszaghaz-i.jpg 75w,\n/static/36d87329aeeda296ae923606e5a4a785/712e7/2019-11-02-orszaghaz-i.jpg 150w,\n/static/36d87329aeeda296ae923606e5a4a785/0f41b/2019-11-02-orszaghaz-i.jpg 300w,\n/static/36d87329aeeda296ae923606e5a4a785/270e8/2019-11-02-orszaghaz-i.jpg 450w,\n/static/36d87329aeeda296ae923606e5a4a785/aa95b/2019-11-02-orszaghaz-i.jpg 600w,\n/static/36d87329aeeda296ae923606e5a4a785/506d6/2019-11-02-orszaghaz-i.jpg 3708w",
|
||||
"srcWebp": "/static/36d87329aeeda296ae923606e5a4a785/40e2f/2019-11-02-orszaghaz-i.webp",
|
||||
"srcSetWebp": "/static/36d87329aeeda296ae923606e5a4a785/37dc9/2019-11-02-orszaghaz-i.webp 75w,\n/static/36d87329aeeda296ae923606e5a4a785/37a2a/2019-11-02-orszaghaz-i.webp 150w,\n/static/36d87329aeeda296ae923606e5a4a785/40e2f/2019-11-02-orszaghaz-i.webp 300w,\n/static/36d87329aeeda296ae923606e5a4a785/6a707/2019-11-02-orszaghaz-i.webp 450w,\n/static/36d87329aeeda296ae923606e5a4a785/bf714/2019-11-02-orszaghaz-i.webp 600w,\n/static/36d87329aeeda296ae923606e5a4a785/7fe6d/2019-11-02-orszaghaz-i.webp 3708w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/orszaghaz-i",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "0549d0c5-1c41-5cf6-b640-6fbc6ab778fb",
|
||||
"frontmatter": {
|
||||
"title": "Foro di Cesare",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2019-09-29-foro-di-cesare-00ba7297095683d32f490c1cf1a3ca2d.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/00ba7297095683d32f490c1cf1a3ca2d/0f41b/2019-09-29-foro-di-cesare.jpg",
|
||||
"srcSet": "/static/00ba7297095683d32f490c1cf1a3ca2d/73124/2019-09-29-foro-di-cesare.jpg 75w,\n/static/00ba7297095683d32f490c1cf1a3ca2d/712e7/2019-09-29-foro-di-cesare.jpg 150w,\n/static/00ba7297095683d32f490c1cf1a3ca2d/0f41b/2019-09-29-foro-di-cesare.jpg 300w,\n/static/00ba7297095683d32f490c1cf1a3ca2d/270e8/2019-09-29-foro-di-cesare.jpg 450w,\n/static/00ba7297095683d32f490c1cf1a3ca2d/aa95b/2019-09-29-foro-di-cesare.jpg 600w,\n/static/00ba7297095683d32f490c1cf1a3ca2d/9dbe2/2019-09-29-foro-di-cesare.jpg 2868w",
|
||||
"srcWebp": "/static/00ba7297095683d32f490c1cf1a3ca2d/40e2f/2019-09-29-foro-di-cesare.webp",
|
||||
"srcSetWebp": "/static/00ba7297095683d32f490c1cf1a3ca2d/37dc9/2019-09-29-foro-di-cesare.webp 75w,\n/static/00ba7297095683d32f490c1cf1a3ca2d/37a2a/2019-09-29-foro-di-cesare.webp 150w,\n/static/00ba7297095683d32f490c1cf1a3ca2d/40e2f/2019-09-29-foro-di-cesare.webp 300w,\n/static/00ba7297095683d32f490c1cf1a3ca2d/6a707/2019-09-29-foro-di-cesare.webp 450w,\n/static/00ba7297095683d32f490c1cf1a3ca2d/bf714/2019-09-29-foro-di-cesare.webp 600w,\n/static/00ba7297095683d32f490c1cf1a3ca2d/d8318/2019-09-29-foro-di-cesare.webp 2868w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/foro-di-cesare",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "fe3ed03e-3612-54cb-aceb-691938b4e3f3",
|
||||
"frontmatter": {
|
||||
"title": "Arco di Costantino",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2019-09-29-arco-di-costantino-8f7392d32a0a7746cbb712e4e4a8e2ef.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/8f7392d32a0a7746cbb712e4e4a8e2ef/0f41b/2019-09-29-arco-di-costantino.jpg",
|
||||
"srcSet": "/static/8f7392d32a0a7746cbb712e4e4a8e2ef/73124/2019-09-29-arco-di-costantino.jpg 75w,\n/static/8f7392d32a0a7746cbb712e4e4a8e2ef/712e7/2019-09-29-arco-di-costantino.jpg 150w,\n/static/8f7392d32a0a7746cbb712e4e4a8e2ef/0f41b/2019-09-29-arco-di-costantino.jpg 300w,\n/static/8f7392d32a0a7746cbb712e4e4a8e2ef/270e8/2019-09-29-arco-di-costantino.jpg 450w,\n/static/8f7392d32a0a7746cbb712e4e4a8e2ef/aa95b/2019-09-29-arco-di-costantino.jpg 600w,\n/static/8f7392d32a0a7746cbb712e4e4a8e2ef/30037/2019-09-29-arco-di-costantino.jpg 3024w",
|
||||
"srcWebp": "/static/8f7392d32a0a7746cbb712e4e4a8e2ef/40e2f/2019-09-29-arco-di-costantino.webp",
|
||||
"srcSetWebp": "/static/8f7392d32a0a7746cbb712e4e4a8e2ef/37dc9/2019-09-29-arco-di-costantino.webp 75w,\n/static/8f7392d32a0a7746cbb712e4e4a8e2ef/37a2a/2019-09-29-arco-di-costantino.webp 150w,\n/static/8f7392d32a0a7746cbb712e4e4a8e2ef/40e2f/2019-09-29-arco-di-costantino.webp 300w,\n/static/8f7392d32a0a7746cbb712e4e4a8e2ef/6a707/2019-09-29-arco-di-costantino.webp 450w,\n/static/8f7392d32a0a7746cbb712e4e4a8e2ef/bf714/2019-09-29-arco-di-costantino.webp 600w,\n/static/8f7392d32a0a7746cbb712e4e4a8e2ef/859d2/2019-09-29-arco-di-costantino.webp 3024w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/arco-di-costantino",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "2cc51eaa-e6c0-521e-8cea-00cf68688161",
|
||||
"frontmatter": {
|
||||
"title": "Vatican Museums",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2019-09-28-vatican-museums-9ffc375488247897643811d33d28edf9.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/9ffc375488247897643811d33d28edf9/0f41b/2019-09-28-vatican-museums.jpg",
|
||||
"srcSet": "/static/9ffc375488247897643811d33d28edf9/73124/2019-09-28-vatican-museums.jpg 75w,\n/static/9ffc375488247897643811d33d28edf9/712e7/2019-09-28-vatican-museums.jpg 150w,\n/static/9ffc375488247897643811d33d28edf9/0f41b/2019-09-28-vatican-museums.jpg 300w,\n/static/9ffc375488247897643811d33d28edf9/270e8/2019-09-28-vatican-museums.jpg 450w,\n/static/9ffc375488247897643811d33d28edf9/aa95b/2019-09-28-vatican-museums.jpg 600w,\n/static/9ffc375488247897643811d33d28edf9/179de/2019-09-28-vatican-museums.jpg 2978w",
|
||||
"srcWebp": "/static/9ffc375488247897643811d33d28edf9/40e2f/2019-09-28-vatican-museums.webp",
|
||||
"srcSetWebp": "/static/9ffc375488247897643811d33d28edf9/37dc9/2019-09-28-vatican-museums.webp 75w,\n/static/9ffc375488247897643811d33d28edf9/37a2a/2019-09-28-vatican-museums.webp 150w,\n/static/9ffc375488247897643811d33d28edf9/40e2f/2019-09-28-vatican-museums.webp 300w,\n/static/9ffc375488247897643811d33d28edf9/6a707/2019-09-28-vatican-museums.webp 450w,\n/static/9ffc375488247897643811d33d28edf9/bf714/2019-09-28-vatican-museums.webp 600w,\n/static/9ffc375488247897643811d33d28edf9/79bab/2019-09-28-vatican-museums.webp 2978w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/vatican-museums",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "9133fd25-1cb8-5660-be11-3532d4e18cae",
|
||||
"frontmatter": {
|
||||
"title": "German Chancellery II",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"original": {
|
||||
"src": "/static/2019-08-18-german-chancellery-ii-325bcee8ced12b150a2f3448ec1ae8cd.jpg"
|
||||
},
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/325bcee8ced12b150a2f3448ec1ae8cd/0f41b/2019-08-18-german-chancellery-ii.jpg",
|
||||
"srcSet": "/static/325bcee8ced12b150a2f3448ec1ae8cd/73124/2019-08-18-german-chancellery-ii.jpg 75w,\n/static/325bcee8ced12b150a2f3448ec1ae8cd/712e7/2019-08-18-german-chancellery-ii.jpg 150w,\n/static/325bcee8ced12b150a2f3448ec1ae8cd/0f41b/2019-08-18-german-chancellery-ii.jpg 300w,\n/static/325bcee8ced12b150a2f3448ec1ae8cd/270e8/2019-08-18-german-chancellery-ii.jpg 450w,\n/static/325bcee8ced12b150a2f3448ec1ae8cd/aa95b/2019-08-18-german-chancellery-ii.jpg 600w,\n/static/325bcee8ced12b150a2f3448ec1ae8cd/0e49e/2019-08-18-german-chancellery-ii.jpg 4032w",
|
||||
"srcWebp": "/static/325bcee8ced12b150a2f3448ec1ae8cd/40e2f/2019-08-18-german-chancellery-ii.webp",
|
||||
"srcSetWebp": "/static/325bcee8ced12b150a2f3448ec1ae8cd/37dc9/2019-08-18-german-chancellery-ii.webp 75w,\n/static/325bcee8ced12b150a2f3448ec1ae8cd/37a2a/2019-08-18-german-chancellery-ii.webp 150w,\n/static/325bcee8ced12b150a2f3448ec1ae8cd/40e2f/2019-08-18-german-chancellery-ii.webp 300w,\n/static/325bcee8ced12b150a2f3448ec1ae8cd/6a707/2019-08-18-german-chancellery-ii.webp 450w,\n/static/325bcee8ced12b150a2f3448ec1ae8cd/bf714/2019-08-18-german-chancellery-ii.webp 600w,\n/static/325bcee8ced12b150a2f3448ec1ae8cd/b3fb4/2019-08-18-german-chancellery-ii.webp 4032w",
|
||||
"sizes": "(max-width: 300px) 100vw, 300px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/german-chancellery-ii",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
{
|
||||
"post": {
|
||||
"html": "<p>An awesome creative idea for a blog post about Web-Design from Joshua Clanton:</p>\n<blockquote>\n<p>Leonardo Da Vinci was one of the greatest artists of the Renaissance, leaving behind a legacy that continues to inspire artists, scientists and others. Here are six things we can learn from him about web design.</p>\n</blockquote>",
|
||||
"excerpt": "An awesome creative idea for a blog post about Web-Design from Joshua Clanton: Leonardo Da Vinci was one of the greatest artists of the…",
|
||||
"frontmatter": {
|
||||
"title": "6 Web Design Tips from Leonardo da Vinci",
|
||||
"image": null,
|
||||
"toc": null,
|
||||
"author": "Matthias Kretschmann",
|
||||
"updated": null,
|
||||
"tags": ["design"],
|
||||
"linkurl": "http://designpepper.com/blog/6-web-design-tips-from-leonardo-da-vinci",
|
||||
"style": null,
|
||||
"changelog": null
|
||||
},
|
||||
"fields": {
|
||||
"type": "link",
|
||||
"slug": "/6-web-design-tips-from-leonardo-da-vinci",
|
||||
"date": "2008-04-04T18:43:05.000Z",
|
||||
"githubLink": "https://github.com/kremalicious/blog/tree/main/content/posts/2008-04-04-6-web-design-tips-from-leonardo-da-vinci.md"
|
||||
},
|
||||
"rawMarkdownBody": "\nAn awesome creative idea for a blog post about Web-Design from Joshua Clanton:\n\n> Leonardo Da Vinci was one of the greatest artists of the Renaissance, leaving behind a legacy that continues to inspire artists, scientists and others. Here are six things we can learn from him about web design.\n",
|
||||
"tableOfContents": ""
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
{
|
||||
"site": {
|
||||
"siteMetadata": {
|
||||
"siteTitle": "kremalicious",
|
||||
"siteTitleShort": "krlc",
|
||||
"siteDescription": "Blog of designer & developer Matthias Kretschmann",
|
||||
"siteUrl": "https://kremalicious.com",
|
||||
"author": {
|
||||
"name": "Matthias Kretschmann",
|
||||
"email": "m@kretschmann.io",
|
||||
"uri": "https://matthiaskretschmann.com",
|
||||
"twitter": "https://twitter.com/kremalicious",
|
||||
"mastodon": "https://mas.to/@krema",
|
||||
"github": "https://github.com/kremalicious",
|
||||
"facebook": "https://facebook.com/matthiaskretschmann",
|
||||
"bitcoin": "171qDmKEXm9YBgBLXyGjjPvopP5o9htQ1V",
|
||||
"ether": "0x339dbC44d39bf1961E385ed0Ae88FC6069b87Ea1"
|
||||
},
|
||||
"menu": [
|
||||
{
|
||||
"title": "Photos",
|
||||
"link": "/photos"
|
||||
},
|
||||
{
|
||||
"title": "Goodies",
|
||||
"link": "/tags/goodies"
|
||||
},
|
||||
{
|
||||
"title": "Tags",
|
||||
"link": "/tags"
|
||||
}
|
||||
],
|
||||
"rss": "/feed.xml",
|
||||
"jsonfeed": "/feed.json",
|
||||
"itemsPerPage": 20,
|
||||
"repoContentPath": "https://github.com/kremalicious/blog/tree/main/content",
|
||||
"ad": {
|
||||
"title": "",
|
||||
"link": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
{
|
||||
"allMarkdownRemark": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "6effe45d-0884-527c-9fba-6f7f567979fd",
|
||||
"frontmatter": {
|
||||
"title": "Országház II",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/2dbcf257b4bdf625c24fede935d32425/2423a/2019-11-03-orszaghaz-ii.jpg",
|
||||
"srcSet": "/static/2dbcf257b4bdf625c24fede935d32425/b7835/2019-11-03-orszaghaz-ii.jpg 100w,\n/static/2dbcf257b4bdf625c24fede935d32425/2de44/2019-11-03-orszaghaz-ii.jpg 200w,\n/static/2dbcf257b4bdf625c24fede935d32425/2423a/2019-11-03-orszaghaz-ii.jpg 400w,\n/static/2dbcf257b4bdf625c24fede935d32425/66039/2019-11-03-orszaghaz-ii.jpg 600w,\n/static/2dbcf257b4bdf625c24fede935d32425/ba820/2019-11-03-orszaghaz-ii.jpg 800w,\n/static/2dbcf257b4bdf625c24fede935d32425/d04d5/2019-11-03-orszaghaz-ii.jpg 3793w",
|
||||
"srcWebp": "/static/2dbcf257b4bdf625c24fede935d32425/33771/2019-11-03-orszaghaz-ii.webp",
|
||||
"srcSetWebp": "/static/2dbcf257b4bdf625c24fede935d32425/4f5da/2019-11-03-orszaghaz-ii.webp 100w,\n/static/2dbcf257b4bdf625c24fede935d32425/72345/2019-11-03-orszaghaz-ii.webp 200w,\n/static/2dbcf257b4bdf625c24fede935d32425/33771/2019-11-03-orszaghaz-ii.webp 400w,\n/static/2dbcf257b4bdf625c24fede935d32425/f12d8/2019-11-03-orszaghaz-ii.webp 600w,\n/static/2dbcf257b4bdf625c24fede935d32425/b975c/2019-11-03-orszaghaz-ii.webp 800w,\n/static/2dbcf257b4bdf625c24fede935d32425/f7332/2019-11-03-orszaghaz-ii.webp 3793w",
|
||||
"sizes": "(max-width: 400px) 100vw, 400px",
|
||||
"originalImg": "/static/2dbcf257b4bdf625c24fede935d32425/d04d5/2019-11-03-orszaghaz-ii.jpg",
|
||||
"originalName": "2019-11-03-orszaghaz-ii.jpg",
|
||||
"presentationWidth": 400,
|
||||
"presentationHeight": 300
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/orszaghaz-ii/",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "c80697e5-681d-5fcc-9dab-c3a3821ff0b1",
|
||||
"frontmatter": {
|
||||
"title": "Országház I",
|
||||
"image": {
|
||||
"childImageSharp": {
|
||||
"fluid": {
|
||||
"aspectRatio": 1,
|
||||
"src": "/static/36d87329aeeda296ae923606e5a4a785/2423a/2019-11-02-orszaghaz-i.jpg",
|
||||
"srcSet": "/static/36d87329aeeda296ae923606e5a4a785/b7835/2019-11-02-orszaghaz-i.jpg 100w,\n/static/36d87329aeeda296ae923606e5a4a785/2de44/2019-11-02-orszaghaz-i.jpg 200w,\n/static/36d87329aeeda296ae923606e5a4a785/2423a/2019-11-02-orszaghaz-i.jpg 400w,\n/static/36d87329aeeda296ae923606e5a4a785/66039/2019-11-02-orszaghaz-i.jpg 600w,\n/static/36d87329aeeda296ae923606e5a4a785/ba820/2019-11-02-orszaghaz-i.jpg 800w,\n/static/36d87329aeeda296ae923606e5a4a785/c9c86/2019-11-02-orszaghaz-i.jpg 3708w",
|
||||
"srcWebp": "/static/36d87329aeeda296ae923606e5a4a785/33771/2019-11-02-orszaghaz-i.webp",
|
||||
"srcSetWebp": "/static/36d87329aeeda296ae923606e5a4a785/4f5da/2019-11-02-orszaghaz-i.webp 100w,\n/static/36d87329aeeda296ae923606e5a4a785/72345/2019-11-02-orszaghaz-i.webp 200w,\n/static/36d87329aeeda296ae923606e5a4a785/33771/2019-11-02-orszaghaz-i.webp 400w,\n/static/36d87329aeeda296ae923606e5a4a785/f12d8/2019-11-02-orszaghaz-i.webp 600w,\n/static/36d87329aeeda296ae923606e5a4a785/b975c/2019-11-02-orszaghaz-i.webp 800w,\n/static/36d87329aeeda296ae923606e5a4a785/262c1/2019-11-02-orszaghaz-i.webp 3708w",
|
||||
"sizes": "(max-width: 400px) 100vw, 400px",
|
||||
"originalImg": "/static/36d87329aeeda296ae923606e5a4a785/c9c86/2019-11-02-orszaghaz-i.jpg",
|
||||
"originalName": "2019-11-02-orszaghaz-i.jpg",
|
||||
"presentationWidth": 400,
|
||||
"presentationHeight": 297
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/orszaghaz-i/",
|
||||
"type": "photo"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
module.exports = 'test-file-stub'
|
@ -1,29 +0,0 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
const React = require('react')
|
||||
const gatsby = jest.requireActual('gatsby')
|
||||
|
||||
module.exports = {
|
||||
...gatsby,
|
||||
graphql: jest.fn(),
|
||||
Link: jest.fn().mockImplementation(
|
||||
// these props are invalid for an `a` tag
|
||||
({
|
||||
activeClassName,
|
||||
activeStyle,
|
||||
getProps,
|
||||
innerRef,
|
||||
partiallyActive,
|
||||
ref,
|
||||
replace,
|
||||
to,
|
||||
...rest
|
||||
}) =>
|
||||
React.createElement('a', {
|
||||
...rest,
|
||||
href: to
|
||||
})
|
||||
),
|
||||
StaticQuery: jest.fn(),
|
||||
useStaticQuery: jest.fn()
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
const matchMediaMock = Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
value: jest
|
||||
.fn()
|
||||
.mockImplementationOnce((query) => ({
|
||||
matches: false,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: jest.fn(), // deprecated
|
||||
removeListener: jest.fn(), // deprecated
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
dispatchEvent: jest.fn()
|
||||
}))
|
||||
.mockImplementation((query) => ({
|
||||
matches: true,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: jest.fn(), // deprecated
|
||||
removeListener: jest.fn(), // deprecated
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
dispatchEvent: jest.fn()
|
||||
}))
|
||||
})
|
||||
|
||||
export default matchMediaMock
|
@ -1,6 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
export default 'SvgrURL'
|
||||
const SvgrMock = React.forwardRef((props, ref) => <span ref={ref} {...props} />)
|
||||
|
||||
export const ReactComponent = SvgrMock
|
@ -1,72 +0,0 @@
|
||||
import { chain as chainOrig } from 'wagmi'
|
||||
|
||||
export function useNetwork() {
|
||||
return {
|
||||
activeChain: {
|
||||
nativeCurrency: {
|
||||
symbol: 'ETH'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function useAccount() {
|
||||
return {
|
||||
data: {
|
||||
address: '0x0000000000000000000000000000000000000000'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function useSendTransaction() {
|
||||
return {
|
||||
data: {
|
||||
address: '0x0000000000000000000000000000000000000000'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function useEnsAvatar() {
|
||||
return {
|
||||
data: 'xxx.jpg'
|
||||
}
|
||||
}
|
||||
|
||||
export function useEnsName() {
|
||||
return {
|
||||
data: 'fguhifgvewtyifgwyufew.eth'
|
||||
}
|
||||
}
|
||||
|
||||
export function useBalance() {
|
||||
return {
|
||||
data: { formatted: '0.22', symbol: 'ETH' }
|
||||
}
|
||||
}
|
||||
|
||||
export function useConnect() {
|
||||
return {
|
||||
connect: jest.fn()
|
||||
}
|
||||
}
|
||||
|
||||
export function useDisconnect() {
|
||||
return {
|
||||
disconnect: jest.fn()
|
||||
}
|
||||
}
|
||||
|
||||
export function useProvider() {
|
||||
return {}
|
||||
}
|
||||
|
||||
export const chain = chainOrig
|
||||
|
||||
export function createClient() {
|
||||
return {
|
||||
queryClient: {
|
||||
mount: jest.fn(),
|
||||
unmount: jest.fn()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
// this file only exists for Jest
|
||||
module.exports = {
|
||||
presets: ['babel-preset-gatsby', '@babel/preset-typescript']
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
const esModules = [
|
||||
'unified',
|
||||
'vfile',
|
||||
'vfile-.+',
|
||||
'unist-.+',
|
||||
'bail',
|
||||
'is-plain-obj',
|
||||
'trough',
|
||||
'mdast-util-.+',
|
||||
'micromark',
|
||||
'micromark-.+',
|
||||
'parse-entities',
|
||||
'character-entities',
|
||||
'property-information',
|
||||
'comma-separated-tokens',
|
||||
'hast-.+',
|
||||
'remark-.+',
|
||||
'rehype-.+',
|
||||
'space-separated-tokens',
|
||||
'trim-lines',
|
||||
'decode-named-character-reference',
|
||||
'ccount',
|
||||
'escape-string-regexp',
|
||||
'markdown-table',
|
||||
'web-namespaces',
|
||||
'@rainbow-me/rainbowkit',
|
||||
'wagmi',
|
||||
'@wagmi/chains',
|
||||
'@wagmi/core',
|
||||
'@wagmi/connectors',
|
||||
'viem',
|
||||
'devlop'
|
||||
].join('|')
|
||||
|
||||
module.exports = {
|
||||
rootDir: '../',
|
||||
transform: {
|
||||
'^.+\\.[jt]sx?$': ['babel-jest', { configFile: './.jest/babel.config.js' }]
|
||||
},
|
||||
moduleNameMapper: {
|
||||
'.+\\.(css|styl|less|sass|scss)$': 'identity-obj-proxy',
|
||||
'.+\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
|
||||
'<rootDir>/.jest/__mocks__/file.js',
|
||||
'\\.svg': '<rootDir>/.jest/__mocks__/svgr.js',
|
||||
'^@reach/router(.*)': '<rootDir>/node_modules/@gatsbyjs/reach-router$1'
|
||||
},
|
||||
testPathIgnorePatterns: ['node_modules', '.cache', 'public', 'coverage'],
|
||||
transformIgnorePatterns: [
|
||||
`node_modules/(?!(gatsby|gatsby-link|gatsby-script|${esModules})/)`
|
||||
],
|
||||
globals: {
|
||||
__PATH_PREFIX__: ''
|
||||
},
|
||||
setupFiles: ['<rootDir>/.jest/loadershim.js'],
|
||||
setupFilesAfterEnv: ['<rootDir>/.jest/setup-test-env.ts'],
|
||||
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/@types/**/*'],
|
||||
testEnvironment: 'jsdom'
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
global.___loader = {
|
||||
enqueue: jest.fn()
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import * as Gatsby from 'gatsby'
|
||||
import '@testing-library/jest-dom'
|
||||
import avatar from './__fixtures__/avatar.json'
|
||||
import github from './__fixtures__/github.json'
|
||||
import meta from './__fixtures__/meta.json'
|
||||
import posts from './__fixtures__/posts.json'
|
||||
import './__mocks__/matchMedia'
|
||||
|
||||
// viem uses TextEncoder and TextDecoder which are not available with jsdom 16+
|
||||
import { TextEncoder, TextDecoder } from 'util'
|
||||
Object.assign(global, { TextDecoder, TextEncoder })
|
||||
|
||||
const useStaticQuery = jest.spyOn(Gatsby, 'useStaticQuery')
|
||||
|
||||
beforeAll(() => {
|
||||
useStaticQuery.mockImplementation(() => ({
|
||||
...meta,
|
||||
...avatar,
|
||||
logo: { edges: [{ node: { relativePath: 'apple-touch-icon.png' } }] },
|
||||
...posts,
|
||||
...github
|
||||
}))
|
||||
})
|
@ -1,12 +0,0 @@
|
||||
import { ReactElement } from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
|
||||
const testRender = (component: ReactElement): void => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(component)
|
||||
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
}
|
||||
|
||||
export default testRender
|
18
.prettierrc
@ -1,18 +0,0 @@
|
||||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 2,
|
||||
"endOfLine": "lf",
|
||||
"importOrder": [
|
||||
"^(react/(.*)$)|^(react$)",
|
||||
"^(gatsby/(.*)$)|^(gatsby$)",
|
||||
"<THIRD_PARTY_MODULES>",
|
||||
"^[./]"
|
||||
],
|
||||
"importOrderSeparation": false,
|
||||
"importOrderSortSpecifiers": true,
|
||||
"importOrderBuiltinModulesToTop": true,
|
||||
"importOrderMergeDuplicateImports": true,
|
||||
"importOrderCombineTypeAndValueImports": true
|
||||
}
|
14
.prettierrc.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 2,
|
||||
"endOfLine": "lf",
|
||||
"plugins": ["prettier-plugin-astro"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.astro",
|
||||
"options": { "parser": "astro" }
|
||||
}
|
||||
]
|
||||
}
|
161
README.md
@ -2,7 +2,7 @@
|
||||
<a href="https://kremalicious.com"><img src="https://raw.githubusercontent.com/kremalicious/portfolio/main/public/github-header.png" /></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<strong>🍭 My blog built with <a href="http://gatsbyjs.org">Gatsby</a> + TypeScript. Neat.</strong>
|
||||
<strong>🍭 My blog built with <a href="https://astro.build">Astro</a> + TypeScript. Neat.</strong>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://kremalicious.com">kremalicious.com</a>
|
||||
@ -16,20 +16,22 @@
|
||||
---
|
||||
|
||||
- [🎉 Features](#-features)
|
||||
- [🌅 Image handling](#-image-handling)
|
||||
- [🎆 EXIF extraction](#-exif-extraction)
|
||||
- [💰 Cryptocurrency donation via Web3/MetaMask](#-cryptocurrency-donation-via-web3metamask)
|
||||
- [🔍 Search](#-search)
|
||||
- [🕸 Related Posts](#-related-posts)
|
||||
- [📝 GitHub changelog rendering](#-github-changelog-rendering)
|
||||
- [🌗 Theme Switcher](#-theme-switcher)
|
||||
- [🏆 SEO component](#-seo-component)
|
||||
- [gatsby-redirect-from](#gatsby-redirect-from)
|
||||
- [💎 Importing SVG assets](#-importing-svg-assets)
|
||||
- [🍬 Typekit component](#-typekit-component)
|
||||
- [💎 SVG assets as components](#-svg-assets-as-components)
|
||||
- [`redirect_from`](#redirect_from)
|
||||
- [RSS \& JSON feeds](#rss--json-feeds)
|
||||
- [✨ Development](#-development)
|
||||
- [🔮 Linting](#-linting)
|
||||
- [🔮 Type Checking](#-type-checking)
|
||||
- [👩🔬 Testing](#-testing)
|
||||
- [🎈 Add a new post](#-add-a-new-post)
|
||||
- [🎈 Content creation helpers](#-content-creation-helpers)
|
||||
- [Add a new post](#add-a-new-post)
|
||||
- [🚚 Deployment](#-deployment)
|
||||
- [S3 Deployment](#s3-deployment)
|
||||
- [🏛 Licenses](#-licenses)
|
||||
@ -40,119 +42,120 @@
|
||||
|
||||
## 🎉 Features
|
||||
|
||||
The whole [blog](https://kremalicious.com) is a React-based Single Page App built with [Gatsby v2](https://www.gatsbyjs.org).
|
||||
The whole [blog](https://kremalicious.com) is a statically exported site built with [Astro](https://astro.build) and TypeScript. Almost all components are Astro or native Web Components, with some React components loaded client-side.
|
||||
|
||||
Styling happens through a combination of basic global styles and on components level either through CSS modules or CSS in `<style>` tags within Astro components.
|
||||
|
||||
Content lives under `content/` and Astro creates a content collection for each subfolder, which are then queried in components. Every post is a folder with a markdown file and all respective post assets colocated inside.
|
||||
|
||||
Retrieving content collections will enrich every post's frontmatter metadata, like extracting date and slug from the post folder name, or exif extraction for photos.
|
||||
|
||||
### 🌅 Image handling
|
||||
|
||||
Uses Astro's native `astro:assets` feature, all required image sizes are automatically generated from source images, working in combination with my own custom `<picture>` component. Making heavy use of Astro's `getImage()` and custom markup results in full image sizing control and properly `object-fit` images with varying aspect ratios.
|
||||
|
||||
Teaser images are all defined in a post's frontmatter `image` key, which is then passed to the `<Picture />` component for display.
|
||||
|
||||
If you want to know how this works, have a look at the respective files:
|
||||
|
||||
- [`src/components/Picture/index.astro`](src/components/Picture/index.astro)
|
||||
- [`src/components/Picture/index.module.css`](src/components/Picture/index.module.css)
|
||||
|
||||
### 🎆 EXIF extraction
|
||||
|
||||
Automatically extracts EXIF & IPTC metadata from my photos on build time. For minimal overhead, [fast-exif](https://github.com/titarenko/fast-exif) & [node-iptc](https://github.com/derekbaron/node-iptc) parse every JPG file upon Gatsby file node creation and add the extracted data as node fields.
|
||||
|
||||
This way, EXIF data is only extracted at build time and can be simply queried with GraphQL at run time.
|
||||
Automatically extracts EXIF & IPTC metadata from my photos and adds it to markdown frontmatter of respective photo posts. For minimal overhead, [fast-exif](https://github.com/titarenko/fast-exif) & [node-iptc](https://github.com/derekbaron/node-iptc) is used to parse every JPG file whenever a content collection is accessed.
|
||||
|
||||
In the end looks like this, including location display with [pigeon-maps](https://github.com/mariusandra/pigeon-maps):
|
||||
|
||||
<img width="1098" alt="screen shot 2018-10-14 at 20 27 39" src="https://user-images.githubusercontent.com/90316/46920507-9d6b7a00-cfef-11e8-84c8-a1997f471cae.png">
|
||||
|
||||
If you want to know how this works, have a look at the respective component under
|
||||
If you want to know how this works, have a look at the respective files:
|
||||
|
||||
- [`src/components/atoms/Exif.jsx`](src/components/atoms/Exif.jsx)
|
||||
- the EXIF node fields creation [`gatsby/createExif.js`](gatsby/createExif.js) running in [`gatsby-node.js`](gatsby-node.js)
|
||||
- EXIF extraction with `readOutExif()` helper in [`src/lib/exif/index.ts`](src/lib/exif/index.ts)
|
||||
- the `loadAndFormatCollection()` helper in [`src/lib/astro.ts`](src/lib/astro.ts)
|
||||
- output through [`src/components/Exif/`](src/components/Exif/)
|
||||
|
||||
### 💰 Cryptocurrency donation via Web3/MetaMask
|
||||
|
||||
Lets visitors say thanks with Bitcoin or Ether. Uses [web3.js](https://github.com/ethereum/web3.js) for sending Ether transactions via MetaMask, Brave or Mist. Component listens to account & network changes and adapts accordingly.
|
||||
|
||||
As a fallback, QR codes are generated with [react-qr-svg](https://github.com/no23reason/react-qr-svg) from the addresses defined in [`config.js`](config.js).
|
||||
Lets visitors say thanks with Bitcoin or Ether. Uses [RainbowKit](https://www.rainbowkit.com) for wallet connection & [wagmi](https://wagmi.sh) for sending transactions via browser wallets.
|
||||
|
||||
<img width="700" alt="screen shot 2018-10-14 at 22 03 57" src="https://user-images.githubusercontent.com/90316/46921544-1a512080-cffd-11e8-919f-d3e86dbd5cc5.png" />
|
||||
|
||||
If you want to know how this works, have a look at the respective components under
|
||||
|
||||
- [`src/components/molecules/Web3Donation/index.jsx`](src/components/molecules/Web3Donation/index.jsx)
|
||||
- [`src/components/molecules/Web3Donation/Account.jsx`](src/components/molecules/Web3Donation/Account.jsx)
|
||||
- [`src/components/molecules/Web3Donation/InputGroup.jsx`](src/components/molecules/Web3Donation/InputGroup.jsx)
|
||||
- [`src/components/molecules/Web3Donation/Conversion.jsx`](src/components/molecules/Web3Donation/Conversion.jsx)
|
||||
- [`src/components/molecules/Web3Donation/Alerts.jsx`](src/components/molecules/Web3Donation/Alerts.jsx)
|
||||
- [`src/components/molecules/Web3Donation/utils.jsx`](src/components/molecules/Web3Donation/utils.jsx)
|
||||
- [`src/components/atoms/Qr.jsx`](src/components/atoms/Qr.jsx)
|
||||
- [`src/components/Donation/`](src/components/Donation/)
|
||||
|
||||
### 🔍 Search
|
||||
|
||||
A global search is provided with [gatsby-plugin-lunr](https://github.com/humanseelabs/gatsby-plugin-lunr). That plugin creates a [Lunr](https://lunrjs.com) search index file of all posts on build time which is then queried against when the search field is used.
|
||||
A global search is provided with fuse.js. Whenever search is opened, all posts metadata is fetched, which is then queried against when the search field is used. This prevents a huge search index from being bundled in the site build.
|
||||
|
||||
<img width="700" alt="screen shot 2018-11-18 at 19 44 30" src="https://user-images.githubusercontent.com/90316/48676679-634f4400-eb6a-11e8-936d-293505d5c5d9.png">
|
||||
|
||||
If you want to know how this works, have a look at the respective components under
|
||||
|
||||
- [`src/components/molecules/Search/Search.jsx`](src/components/molecules/Search/Search.jsx)
|
||||
- [`src/components/molecules/Search/SearchResults.jsx`](src/components/molecules/Search/SearchResults.jsx)
|
||||
- more in [`src/components/molecules/Search/`](src/components/molecules/Search/)
|
||||
- [`src/components/Search/`](src/components/Search/)
|
||||
|
||||
### 🕸 Related Posts
|
||||
|
||||
Under each post a list of related posts is displayed which are based on the tags of the currently viewed post. Also allows loading more related posts in place.
|
||||
Under each post a list of related posts is displayed which are based on the tags and other metadata of the currently viewed post, also done with fuse.js.
|
||||
|
||||
<img width="700" alt="screen shot 2018-10-11 at 21 03 03" src="https://user-images.githubusercontent.com/90316/46827531-14f39c00-cd99-11e8-84aa-0e851c32c89c.png" />
|
||||
|
||||
If you want to know how this works, have a look at the respective component under
|
||||
|
||||
- [`src/components/molecules/RelatedPosts.jsx`](src/components/molecules/RelatedPosts.jsx)
|
||||
- [`src/components/RelatedPosts/`](src/components/RelatedPosts/)
|
||||
|
||||
### 📝 GitHub changelog rendering
|
||||
|
||||
Adds ability to show contents of a changelog, rendered from a `CHANGELOG.md` on GitHub from the given repository. The use case is to enhance release posts about projects hosted on GitHub. Makes use of the GitHub GraphQL API via [gatsby-source-graphql](https://www.gatsbyjs.org/packages/gatsby-source-graphql/).
|
||||
Adds ability to show contents of a changelog, rendered from a `CHANGELOG.md` on GitHub from the given repository. The use case is to enhance release posts about projects hosted on GitHub. Makes use of the GitHub GraphQL API.
|
||||
|
||||
Adding this to a post's YAML frontmatter:
|
||||
|
||||
```yaml
|
||||
changelog: gatsby-plugin-matomo
|
||||
changelog: kremalicious/gatsby-plugin-matomo
|
||||
```
|
||||
|
||||
will render this at the end of the post:
|
||||
|
||||
<img width="700" alt="screen shot 2018-11-21 at 23 03 38" src="https://user-images.githubusercontent.com/90316/48870593-bc74dd00-ede1-11e8-9051-df55ab7b48d1.png">
|
||||
|
||||
See it live on [Matomo plugin for Gatsby](https://kremalicious.com/gatsby-plugin-matomo#changelog).
|
||||
See it live e.g. on [Matomo plugin for Gatsby](https://kremalicious.com/gatsby-plugin-matomo#changelog).
|
||||
|
||||
If you want to know how this works, have a look at the respective component under
|
||||
|
||||
- [`src/components/atoms/Changelog.jsx`](src/components/atoms/Changelog.jsx)
|
||||
- [`src/components/Changelog/`](src/components/Changelog/)
|
||||
- the `getRepo()` helper in [`src/lib/github.ts`](src/lib/github.ts)
|
||||
|
||||
### 🌗 Theme Switcher
|
||||
|
||||
Includes a theme switcher which allows user to toggle between a light and a dark theme. Switching between them also happens automatically based on user's system preferences utilizing [use-dark-mode](https://github.com/donavon/use-dark-mode).
|
||||
Includes a theme switcher which allows user to toggle between a light and a dark theme. Switching between them also happens automatically based on user's system preferences. Uses [nanostores](https://github.com/nanostores/nanostores) to share its state between components/frameworks.
|
||||
|
||||
If you want to know how, have a look at the respective components:
|
||||
|
||||
- [`src/components/molecules/ThemeSwitch.jsx`](src/components/molecules/ThemeSwitch.jsx)
|
||||
- [`src/components/ThemeSwitch/`](src/components/ThemeSwitch/)
|
||||
- [`src/stores/theme.ts`](src/stores/theme.ts)
|
||||
|
||||
### 🏆 SEO component
|
||||
### 💎 SVG assets as components
|
||||
|
||||
Includes a SEO component which automatically switches all required `meta` tags for search engines, Twitter Cards, and Facebook OpenGraph tags based on the browsed route/page.
|
||||
All SVG assets under `src/images/` and from select iconset dependencies are converted to Astro components before building the site. Compiled components are placed under `src/images/components/` and all include the cleaned SVGs as inline HTML.
|
||||
|
||||
If you want to know how this works, have a look at the respective component under
|
||||
All SVGs can then be imported from `@images/components` in all Astro components.
|
||||
|
||||
- [`src/components/atoms/SEO.jsx`](src/components/atoms/SEO.jsx)
|
||||
If you want to know how this works, have a look at the respective files:
|
||||
|
||||
### gatsby-redirect-from
|
||||
- [`scripts/create-icons/`](scripts/create-icons/)
|
||||
|
||||
- [gatsby-redirect-from](https://github.com/kremalicious/gatsby-redirect-from)
|
||||
### `redirect_from`
|
||||
|
||||
### 💎 Importing SVG assets
|
||||
Still a remnant of the old [Jekyll](https://jekyllrb.com) days, which survived in [gatsby-redirect-from](/gatsby-redirect-from/) and now works in Astro. For all post slugs defined in a `redirect_from` frontmatter key, redirects will be put in place by Astro.
|
||||
|
||||
All SVG assets under `src/images/` will be converted to React components with the help of [gatsby-plugin-svgr](https://github.com/zabute/gatsby-plugin-svgr). Makes use of [SVGR](https://github.com/smooth-code/svgr) so SVG assets can be imported like so:
|
||||
Before building the site, a script scans all markdown files and creates a json file under `.config/redirects.json`. This file is then imported into `astro.config.ts` under its `redirects` option.
|
||||
|
||||
```jsx
|
||||
import { ReactComponent as Logo } from './components/svg/Logo'
|
||||
;<Logo />
|
||||
```
|
||||
If you want to know how, have a look at the respective files:
|
||||
|
||||
### 🍬 Typekit component
|
||||
- [`scripts/redirect-from.ts`](scripts/redirect-from.ts)
|
||||
|
||||
Includes a component for adding the Typekit snippet.
|
||||
|
||||
If you want to know how this works, have a look at the respective component under
|
||||
|
||||
- [`src/components/atoms/Typekit.jsx`](src/components/atoms/Typekit.jsx)
|
||||
### RSS & JSON feeds
|
||||
|
||||
## ✨ Development
|
||||
|
||||
@ -160,7 +163,7 @@ If you want to know how this works, have a look at the respective component unde
|
||||
git clone git@github.com:kremalicious/blog.git
|
||||
cd blog/
|
||||
|
||||
# GATSBY_GITHUB_TOKEN is required for some parts
|
||||
# required env vars
|
||||
cp .env.sample .env
|
||||
vi .env
|
||||
|
||||
@ -180,22 +183,45 @@ To automatically format all code files:
|
||||
|
||||
```bash
|
||||
npm run format
|
||||
npm run format:css
|
||||
```
|
||||
|
||||
### 🔮 Type Checking
|
||||
|
||||
Type checking can be invoked to check all TypeScript code, including within .astro files:
|
||||
|
||||
```bash
|
||||
npm run typecheck
|
||||
```
|
||||
|
||||
### 👩🔬 Testing
|
||||
|
||||
Test suite is setup with [Jest](https://jestjs.io) and [react-testing-library](https://github.com/kentcdodds/react-testing-library).
|
||||
Test suite is setup with [Vitest](https://vitest.dev), [react-testing-library](https://github.com/kentcdodds/react-testing-library), and [Playwright](https://playwright.dev).
|
||||
|
||||
To run all tests, including all linting tests:
|
||||
All unit test files live beside the respective component with naming pattern `*.test.ts(x)`. Integration test files live under `./test/e2e/` exclusively, with naming pattern `*.spec.ts`.
|
||||
|
||||
Testing setup, fixtures, and mocks shared between unit & integration tests can be found in `./test` folder.
|
||||
|
||||
To run all unit tests:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
npm run test:unit
|
||||
```
|
||||
|
||||
All test files live beside the respective component. Testing setup, fixtures, and mocks can be found in `./jest.config.js` and `./jest` folder.
|
||||
For End-to-End integration testing, ideally run against the production build:
|
||||
|
||||
### 🎈 Add a new post
|
||||
```bash
|
||||
npm run build && npm run preview
|
||||
|
||||
# mapping `playwright` command
|
||||
npm run test:e2e
|
||||
npm run test:e2e -- --ui
|
||||
npm run test:e2e -- path/to/file.spec.ts.
|
||||
npm run test:e2e -- --update-snapshots
|
||||
```
|
||||
|
||||
## 🎈 Content creation helpers
|
||||
|
||||
### Add a new post
|
||||
|
||||
```bash
|
||||
npm run new "Hello World"
|
||||
@ -206,22 +232,21 @@ Create a new photo post with date, title & description pre-filled from EXIF/IPTC
|
||||
|
||||
```bash
|
||||
npm run new photo /path/to/photo.jpg
|
||||
npm run new photo /path/to/photo.jpg "Hello Photo Post"
|
||||
```
|
||||
|
||||
- [`scripts/new.js`](scripts/new.js)
|
||||
- [`scripts/new-article.md`](scripts/new-article.md)
|
||||
- [`scripts/new-photo.md`](scripts/new-photo.md)
|
||||
- [`scripts/new/`](scripts/new/)
|
||||
|
||||
## 🚚 Deployment
|
||||
|
||||
Every branch or Pull Request is automatically deployed by [Vercel](https://vercel.com) with their GitHub integration. A link to a preview deployment will appear under each Pull Request. Because of Vercel's maximum cache size of 500MB, Vercel is not used for the production deployment.
|
||||
Every branch or Pull Request is automatically deployed by [Vercel](https://vercel.com) with their GitHub integration. A link to a preview deployment will appear under each Pull Request. Vercel is not used for the production deployment.
|
||||
|
||||
### S3 Deployment
|
||||
|
||||
The latest deployment of the `main` branch is automatically deployed to S3 from the GitHub Action as the production deployment, aliased to `kremalicious.com`. The deploy command simply calls the [`scripts/deploy-s3.sh`](scripts/deploy-s3.sh) script, syncing the contents of the `public/` folder to S3:
|
||||
The latest deployment of the `main` branch is automatically deployed to S3 from the GitHub Action as the production deployment, aliased to `kremalicious.com`. The deploy command simply calls the [`scripts/deploy-s3.sh`](scripts/deploy-s3.sh) script, syncing the contents of the `dist/` folder to S3:
|
||||
|
||||
```bash
|
||||
npm run deploy
|
||||
npm run deploy:s3
|
||||
```
|
||||
|
||||
## 🏛 Licenses
|
||||
@ -234,12 +259,12 @@ EXCEPT FOR:
|
||||
|
||||
[![Creative Commons License](https://i.creativecommons.org/l/by-nc-sa/4.0/80x15.png)](http://creativecommons.org/licenses/by-nc-sa/4.0/)
|
||||
|
||||
All post content under `./content/posts` is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-nc-sa/4.0/).
|
||||
All post content under `./content/articles` & `./content/links` is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-nc-sa/4.0/).
|
||||
|
||||
### Photos & images
|
||||
|
||||
All photos & image assets are plain ol' copyright.
|
||||
|
||||
Copyright (c) 2008–2018 Matthias Kretschmann
|
||||
Copyright (c) 2008–2023 Matthias Kretschmann
|
||||
|
||||
Don't care if you fork & play with it, but you're not allowed to publish anything from it as a whole without my written permission. Also please be aware, the combination of typography, colors & layout makes up my brand identity. So please don't just clone everything, but rather do a remix!
|
||||
|
@ -1,70 +0,0 @@
|
||||
<RoutingRules>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>lab/</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>lab.kremalicious.com</HostName>
|
||||
<ReplaceKeyWith></ReplaceKeyWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>lab</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>lab.kremalicious.com</HostName>
|
||||
<ReplaceKeyWith></ReplaceKeyWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>csspaperstack/</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>lab.kremalicious.com</HostName>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>csspaperstack</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>lab.kremalicious.com</HostName>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>download/</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<ReplaceKeyPrefixWith>media/</ReplaceKeyPrefixWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>feed/</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<ReplaceKeyPrefixWith>feed.xml</ReplaceKeyPrefixWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>portfolio/</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>matthiaskretschmann.com</HostName>
|
||||
<ReplaceKeyWith></ReplaceKeyWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
<RoutingRule>
|
||||
<Condition>
|
||||
<KeyPrefixEquals>portfolio</KeyPrefixEquals>
|
||||
</Condition>
|
||||
<Redirect>
|
||||
<HostName>matthiaskretschmann.com</HostName>
|
||||
<ReplaceKeyWith></ReplaceKeyWith>
|
||||
</Redirect>
|
||||
</RoutingRule>
|
||||
</RoutingRules>
|
71
content/_schemas.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import { z, type ImageFunction } from 'astro:content'
|
||||
|
||||
const schemaShared = {
|
||||
title: z.string(),
|
||||
date: z
|
||||
.string()
|
||||
.or(z.date())
|
||||
.optional()
|
||||
// Transform string to Date object
|
||||
.transform((val: string | Date | undefined) =>
|
||||
val ? new Date(val) : undefined
|
||||
),
|
||||
updated: z
|
||||
.string()
|
||||
.or(z.date())
|
||||
.optional()
|
||||
.transform((val: string | Date | undefined) =>
|
||||
val ? new Date(val) : undefined
|
||||
),
|
||||
tags: z.array(z.string()).optional(),
|
||||
draft: z.boolean().optional(),
|
||||
redirect_from: z.array(z.string()).optional(),
|
||||
author: z.string().optional(),
|
||||
featured: z.boolean().optional(),
|
||||
style: z.string().optional(),
|
||||
toc: z.boolean().optional(),
|
||||
githubLink: z.string().optional(),
|
||||
changelog: z.string().optional(),
|
||||
lead: z.string().optional()
|
||||
}
|
||||
|
||||
export const schemaArticles = (image: ImageFunction) =>
|
||||
z
|
||||
.object({
|
||||
...schemaShared,
|
||||
image: image()
|
||||
// .refine((img) => img.width >= 1040, {
|
||||
// message: 'Cover image must be at least 1040 pixels wide!'
|
||||
// })
|
||||
.optional(),
|
||||
download: z.string().optional(),
|
||||
changelog: z.string().optional()
|
||||
})
|
||||
.strict()
|
||||
|
||||
export const schemaLinks = z
|
||||
.object({
|
||||
...schemaShared,
|
||||
linkurl: z.string()
|
||||
})
|
||||
.strict()
|
||||
|
||||
export const schemaPhotos = (image: ImageFunction) =>
|
||||
z
|
||||
.object({
|
||||
...schemaShared,
|
||||
image: image(),
|
||||
// .refine((img) => img.width >= 1040, {
|
||||
// message: 'Cover image must be at least 1040 pixels wide!'
|
||||
// })
|
||||
exif: z.object({}).optional()
|
||||
})
|
||||
.strict()
|
||||
|
||||
// export type ArticleFrontmatter = z.infer<typeof schemaArticles>
|
||||
// export type LinkFrontmatter = z.infer<typeof schemaLinks>
|
||||
// export type PhotoFrontmatter = z.infer<typeof schemaPhotos>
|
||||
// export type PostFrontmatter =
|
||||
// | ArticleFrontmatter
|
||||
// | LinkFrontmatter
|
||||
// | PhotoFrontmatter
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: 'Finally... a universal scanner driver for the Canon CanoScan LiDE 500F for Intel Macs'
|
||||
image: ../media/canoscanlide500f.jpg
|
||||
image: ./canoscanlide500f.jpg
|
||||
date: 2007-06-11 18:44:28+00:00
|
||||
|
||||
tags:
|
||||
@ -30,15 +30,15 @@ So I called the Canon Support two months ago but they could only say sorry and a
|
||||
|
||||
After choosing the scanner in the dropdown-menu and clicking on "Drivers & Software" you will come to a popup-window where you can find the driver called "LiDE 500F Scanner Driver Ver. 11.2.4.0X (Mac OS X)" in the middle of the site:
|
||||
|
||||
![image](../media/canon1.png)
|
||||
![image](./canon1.png)
|
||||
|
||||
And after installing (and rebooting the system) you can use the scanner with Photoshop CS3 on Intel-Macs. The scanner appears in Photoshop under File > Import > CanoScan LiDE 500f.
|
||||
|
||||
![image](../media/canon2.png)
|
||||
![image](./canon2.png)
|
||||
|
||||
![image](../media/canon3.png)And don't forget to take a look in the preferences-dialog in the scan-window to set your color-management under the tab "Color Settings"
|
||||
![image](./canon3.png)And don't forget to take a look in the preferences-dialog in the scan-window to set your color-management under the tab "Color Settings"
|
||||
|
||||
![image](../media/canon4.png)Another important setting is enabling 16bit per channel scanning under the tab "Scan".
|
||||
![image](./canon4.png)Another important setting is enabling 16bit per channel scanning under the tab "Scan".
|
||||
|
||||
The only problem that remains is that Photoshop really uses 50% of my CPU-Power (2GHz Intel Core2Duo) just when the scan-window is open. But now after six months of waiting i can finally scan my analog photography in acceptable quality. Thanks to Canon for nothing!
|
||||
|
@ -8,9 +8,9 @@ tags:
|
||||
- design
|
||||
---
|
||||
|
||||
![parallax](../media/parallax.png)If you resize your browser window while you are browsing this website you can see the black polaroids in my header fly and move at different speed on three layers. Pretty cool, huh?
|
||||
If you resize your browser window while you are browsing this website you can see the black polaroids in my header fly and move at different speed on three layers. Pretty cool, huh?
|
||||
|
||||
<!-- more -->
|
||||
![parallax](./parallax.png)
|
||||
|
||||
I implemented the header effect of those flying black polaroids on kremalicious.com following the original idea by the folks of [clearleft](http://clearleft.com/) on [their silverback teaser page](http://www.silverbackapp.com/)
|
||||
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
@ -1,7 +1,7 @@
|
||||
---
|
||||
title: Aperture File Types
|
||||
image: ../media/Teaser-Aperture-File-Types.jpg
|
||||
download: ../media/aperturefiletypes_by_kremalicious.zip
|
||||
image: ./Teaser-Aperture-File-Types.jpg
|
||||
download: /get/aperturefiletypes_by_kremalicious.zip
|
||||
author: Matthias Kretschmann
|
||||
date: 2008-04-04T01:55:54.000Z
|
||||
|
||||
@ -29,7 +29,7 @@ These icons are free for your personal use and include icons for all file types
|
||||
Get them and have fun.
|
||||
|
||||
<p class="content-download">
|
||||
<a class="icon-download btn btn-primary" href="../media/aperturefiletypes_by_kremalicious.zip">Download</a>
|
||||
<a class="icon-download btn btn-primary" href="/get/aperturefiletypes_by_kremalicious.zip">Download</a>
|
||||
</p>
|
||||
|
||||
And don't forget to read my article about [how to change the generic image icons in Mac OS X Leopard](/changing-the-image-icons-in-mac-os-x-leopard/).
|
@ -8,11 +8,9 @@ tags:
|
||||
- photography
|
||||
---
|
||||
|
||||
![Pulitzer Price](../media/pulitzer.png)
|
||||
|
||||
The Columbia University has announced the winners for 2008 of the 92nd annual Pulitzer Price. The Pulitzer Price itself is often cited as the highest honor for american journalists. Among the various categories there are two winning entries for [Breaking News Photography](http://www.pulitzer.org/year/2008/breaking-news-photography) and [Feature Photography](http://www.pulitzer.org/year/2008/feature-photography).
|
||||
|
||||
<!-- more -->
|
||||
![Pulitzer Price](./pulitzer.png)
|
||||
|
||||
In the Breaking News Photography the price was won by Adrees Latif of Reuters [for his picture of the japanese videographer Kenji Nagai shot down during riots in Myanmar in 2007](http://www.pulitzer.org/year/2008/breaking-news-photography/works/).
|
||||
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
@ -15,35 +15,41 @@ redirect_from:
|
||||
- /2008/04/changing-the-image-icons-in-mac-os-x-leopard/
|
||||
---
|
||||
|
||||
[![Aperture File Types](../media/aperturefiletypes.png)](../media/aperturefiletypes.png)
|
||||
After i released my [Aperture File Types icon set](http://www.kremalicious.com/goodies) many of you asked how they can really use these icons for displaying the icons of images on your Mac system.
|
||||
|
||||
After i released my [Aperture File Types icon set](http://www.kremalicious.com/goodies) many of you asked how they can really use these icons for displaying the icons of images on your Mac system. Sadly this isn't as easy as dropping them in [Candybar](http://www.panic.com/candybar) into a well for image icons cause there isn't any well for them. So using other icons as standard file type icons for images is a bit tricky. I discovered two ways of doing it, which involves overwriting resources of Preview.app and Photoshop. So before doing anything I mention in this post, you should make a backup copy of them.
|
||||
![Aperture File Types](./aperturefiletypes.png)
|
||||
|
||||
<!-- more -->
|
||||
Sadly this isn't as easy as dropping them in [Candybar](http://www.panic.com/candybar) into a well for image icons cause there isn't any well for them. So using other icons as standard file type icons for images is a bit tricky. I discovered two ways of doing it, which involves overwriting resources of Preview.app and Photoshop. So before doing anything I mention in this post, you should make a backup copy of them.
|
||||
|
||||
## Changing Preview.app icons
|
||||
|
||||
[![Open with Preview](../media/openwithpreview.png)](../media/openwithpreview.png)Image icons in Mac OS X doesn't really belong to the system icons. Instead they come from [Preview.app](http://www.apple.com/macosx/features/300.html%23preview) which is the factory default application for viewing images on Mac OS X.
|
||||
![Open with Preview](./openwithpreview.png)
|
||||
|
||||
Image icons in Mac OS X don't really belong to the system icons. Instead they come from [Preview.app](http://www.apple.com/macosx/features/300.html%23preview) which is the factory default application for viewing images on Mac OS X.
|
||||
|
||||
And since Preview.app is used to show the icons we can find all file type icons for images in Preview.app > Contents > Resources. You get there by right clicking on Preview in your Applications folder and choosing Show Package Contents from the context menu. There you'll find icons in icns-format for bmp, dng, eps, fax, fpx, gif, icns, ico,jp2, jpeg, openexr, pdf, pict, png, pntg, ps, psd, qtif, radiance, raw, sgi, tga, tiff, xbm.
|
||||
|
||||
You can just rename the desired icons from my icon pack in icns-format and replace them in the contents > resources of Preview.app.
|
||||
|
||||
![path Preview](../media/pathpreview.png)
|
||||
![path Preview](./pathpreview.png)
|
||||
|
||||
But, as you can see, Preview doesn’t have an unique icon for all RAW file types. Instead it uses just a generic RAW-icon named RAW.icns.
|
||||
|
||||
[![RAW](../media/raw.png)](../media/raw.png)So here’s what you can do: Grab your desired RAW-file icon from my icon package in icns-format. Rename it as RAW.icns. Copy it over to Preview.app > Contents > Resources and overwrite the standard icon. Making a backup copy of Preview.app before doing that is a wise thing here.
|
||||
![RAW](./raw.png)
|
||||
|
||||
So here’s what you can do: Grab your desired RAW-file icon from my icon package in icns-format. Rename it as RAW.icns. Copy it over to Preview.app > Contents > Resources and overwrite the standard icon. Making a backup copy of Preview.app before doing that is a wise thing here.
|
||||
|
||||
The problem is that from now on every RAW-file is represented by this icon, which is ok if you just use one RAW-format. But it's a problem if you use more than one RAW format.
|
||||
|
||||
## Changing the file type icons of Photoshop
|
||||
|
||||
[![Photoshop CR2](../media/PS_CR2FileIcon.png)](../media/PS_CR2FileIcon.png)A solution to this mess is Photoshop. So this solution just works if you have Photoshop installed. Photoshop does have a unique icon for every RAW-format out there. To confirm that you can choose Adobe Photoshop as Standard Application in the Get Info window and the icon of the file should change instantly.
|
||||
![Photoshop CR2](./PS_CR2FileIcon.png)
|
||||
|
||||
A solution to this mess is Photoshop. So this solution just works if you have Photoshop installed. Photoshop does have a unique icon for every RAW-format out there. To confirm that you can choose Adobe Photoshop as Standard Application in the Get Info window and the icon of the file should change instantly.
|
||||
|
||||
So here's the trick: The icons from Photoshop are stored in Adobe Photoshop CS3.app > Contents > Resources. the icon e.g. for .cr2-icons is named PS_CR2FileIcon.icns. Just rename the icons in my pack in the naming scheme used in the Photoshop Resources and replace them.
|
||||
|
||||
![Path Photoshop](../media/pathphotoshop.png)
|
||||
![Path Photoshop](./pathphotoshop.png)
|
||||
|
||||
Hope this helps you although it's very tricky. But changing icons for images in Mac OS X is a bit out of my control since i don't develop Mac OS X.
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
@ -9,11 +9,11 @@ tags:
|
||||
- aperture
|
||||
---
|
||||
|
||||
![Aperture Assistent](../media/apassis.png)
|
||||
Panoramic photographer [Ian Wood](http://www.ianjameswood.co.uk/) has released an automation helper for Apple's Aperture called [Aperture Assistant](http://aperture-assistant.com) as a first beta version (build 49).
|
||||
|
||||
Panoramic photographer [Ian Wood](http://www.ianjameswood.co.uk/) has released an automation helper for Apple's Aperture called [Aperture Assistant](http://aperture-assistant.com) as a first beta version (build 49). Aperture Assistent allows you to setup and automate complex tasks for Apple's Aperture beyond the Apple delivered Automator actions in Mac OS X. The setup of these workflows is as easy as dragging around visual flowcharts.
|
||||
![Aperture Assistent](./apassis.png)
|
||||
|
||||
<!-- more -->
|
||||
Aperture Assistent allows you to setup and automate complex tasks for Apple's Aperture beyond the Apple delivered Automator actions in Mac OS X. The setup of these workflows is as easy as dragging around visual flowcharts.
|
||||
|
||||
Although the interface looks and feels a bit buggy (dude, it's a beta!) it looks very promising.
|
||||
|
@ -10,11 +10,11 @@ tags:
|
||||
- css
|
||||
---
|
||||
|
||||
![WebKit](../media/webkit.png)
|
||||
Writing right now on a longer article about text-shadow and it's implementation in WebKit, the rendering engine which powers Safari and Konqueror.
|
||||
|
||||
Writing right now on a longer article about text-shadow and it's implementation in WebKit, the rendering engine which powers Safari and Konqueror. But now this exciting news popped up from Surfin' Safari, the blog of the WebKit development team:
|
||||
![WebKit](./webkit.png)
|
||||
|
||||
<!-- more -->
|
||||
But now this exciting news popped up from Surfin' Safari, the blog of the WebKit development team:
|
||||
|
||||
> WebKit now supports gradients specified in CSS. There are two types of gradients: linear gradients and radial gradients.
|
||||
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -12,9 +12,9 @@ redirect_from:
|
||||
- /2008/04/make-cool-and-clever-text-effects-with-css-text-shadow/
|
||||
---
|
||||
|
||||
![CSS](../media/css.png)The aim of this article is to give you a quick introduction of a css property named text-shadow which was first included in CSS2 (but it's not implemented in all browsers yet). Nevertheless you can make some cool effects with it, which could only be done before by photoshopping text and rendering it as an image.
|
||||
The aim of this article is to give you a quick introduction of a css property named text-shadow which was first included in CSS2 (but it's not implemented in all browsers yet). Nevertheless you can make some cool effects with it, which could only be done before by photoshopping text and rendering it as an image.
|
||||
|
||||
<!-- more -->
|
||||
![CSS](./css.png)
|
||||
|
||||
Because it's included in Safari since version 1.1(!) Mac users should be aware of various effects done by this property. In fact, most companys and persons with mac users as their main target audience use this effect on their websites.
|
||||
|
||||
@ -32,11 +32,11 @@ Here's an overview of the headlines in this article. As you can see it's rather
|
||||
|
||||
## 1. What text-shadow is good for
|
||||
|
||||
![kremalicious navbar](../media/navbar-kremalicious.png 'subtle glow in my navigation')
|
||||
![kremalicious navbar](./navbar-kremalicious.png 'subtle glow in my navigation')
|
||||
|
||||
The main goal of this property is to give designers and css coders a tool to make text effects, which could only be done before by rendering text as images with all the side effects. Text rendered as an image isn't searchable and therefore very undelicious for search engines. Another side effect is the fact that images can be way more bigger as one small line of code in terms of file size. As you may know most css-files, which contain the whole layout of a website, are smaller than one image on most websites. So it's really clever to use a css function instead of images for reducing unnecessary traffic.
|
||||
|
||||
![text-shadow used on apple.com](../media/textshadow-apple.png 'text-shadow on apple.com')
|
||||
![text-shadow used on apple.com](./textshadow-apple.png 'text-shadow on apple.com')
|
||||
|
||||
Utilizing text-shadow to simulate engraved or stenciled text is widely used on websites. Apple did it everywhere in Mac OS X not just since Leopard (just look at the titlebars). So if you design a website for Mac users you can increase the sexyness of your website, because this particular usage of text-shadow integrates very well with the overall look of Mac OS X. I will explain how to achieve this engraved-text-on-metal effect later on in this article.
|
||||
|
||||
@ -107,7 +107,7 @@ text-shadow: 2px 2px 3px #000;
|
||||
|
||||
<p style="color: #000;background: #fff;text-shadow: 2px 2px 3px #000;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.3em">I'm a text with a smooth shadow</p>
|
||||
|
||||
![image](../media/text-shadow-1.png)
|
||||
![image](./text-shadow-1.png)
|
||||
|
||||
Or you can make it not so smooth but also good looking by ignoring the blur radius and setting a lighter color for the shadow:
|
||||
|
||||
@ -119,7 +119,7 @@ text-shadow: 2px 2px #000;
|
||||
|
||||
<p style="color: #000;background: #fff;text-shadow: 2px 2px #000;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.3em">I'm a text with no smooth shadow</p>
|
||||
|
||||
![image](../media/text-shadow-2.png)
|
||||
![image](./text-shadow-2.png)
|
||||
|
||||
Using some negative values you can make the shadow look like it's lightsource is placed below the text:
|
||||
|
||||
@ -133,7 +133,7 @@ text-shadow: 2px -2px 3px #000;
|
||||
background: #fff;
|
||||
text-shadow: 2px -2px 3px #000;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.3em">I'm a text with a smooth shadow</p>
|
||||
|
||||
![image](../media/text-shadow-3.png)
|
||||
![image](./text-shadow-3.png)
|
||||
|
||||
Of course you can make it more funky and horrible to read:
|
||||
|
||||
@ -147,7 +147,7 @@ text-shadow: 2px 2px 2px #ff3300;
|
||||
background: #fff;
|
||||
text-shadow: 2px 2px 2px #ff3300;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.3em">I'm funky colored text</p>
|
||||
|
||||
![image](../media/text-shadow-4.png)
|
||||
![image](./text-shadow-4.png)
|
||||
|
||||
## 5.2 Apple style (engraved text on metal)
|
||||
|
||||
@ -163,7 +163,7 @@ text-shadow: 0px 1px 1px #fff;
|
||||
background: #666;
|
||||
text-shadow: 0px 1px 1px #fff;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:bold;padding:0.3em">I'm engraved text</p>
|
||||
|
||||
![image](../media/text-shadow-5.png)
|
||||
![image](./text-shadow-5.png)
|
||||
|
||||
This even works the other way around on a black background with grey text by adjusting only the color values:
|
||||
|
||||
@ -177,7 +177,7 @@ text-shadow: 0px 1px 0px #ccc;
|
||||
background: #000;
|
||||
text-shadow: 0px 1px 0px #ccc;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:bold;padding:0.3em">I'm engraved text on black</p>
|
||||
|
||||
![image](../media/text-shadow-6.png)
|
||||
![image](./text-shadow-6.png)
|
||||
|
||||
Or you can make this one which looks like the text stands out from the background:
|
||||
|
||||
@ -191,7 +191,7 @@ text-shadow: 0px 1px 1px #000;
|
||||
background: #666;
|
||||
text-shadow: 0px 1px 1px #000;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.3em">I'm on top of the background</p>
|
||||
|
||||
![image](../media/text-shadow-7.png)
|
||||
![image](./text-shadow-7.png)
|
||||
|
||||
## 5.3 Make your text glow
|
||||
|
||||
@ -207,7 +207,7 @@ text-shadow: 1px 1px 6px #fff;
|
||||
background: #000;
|
||||
text-shadow: 1px 1px 6px #fff;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.3em">I'm subtle glowing text</p>
|
||||
|
||||
![image](../media/text-shadow-8.png)
|
||||
![image](./text-shadow-8.png)
|
||||
|
||||
You can also make the whole text blurry by using the same color for text and shadow with no offset:
|
||||
|
||||
@ -221,7 +221,7 @@ text-shadow: 0px 0px 3px #fff;
|
||||
background: #666;
|
||||
text-shadow: 0px 0px 3px #fff;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.3em">I'm also glowing but more blurry</p>
|
||||
|
||||
![image](../media/text-shadow-9.png)
|
||||
![image](./text-shadow-9.png)
|
||||
|
||||
We can make it quite mysterious by using the same color for text and background and make the text just visible through text-shadow. Remember that the same color for text and background can be bad for usability...:
|
||||
|
||||
@ -235,7 +235,7 @@ text-shadow: 1px 1px 4px #fff;
|
||||
background: #000;
|
||||
text-shadow: 1px 1px 4px #fff;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.3em">I'm pretty mysterious looking text</p>
|
||||
|
||||
![image](../media/text-shadow-10.png)
|
||||
![image](./text-shadow-10.png)
|
||||
|
||||
Or the other way around to make it look light and... milky:
|
||||
|
||||
@ -249,7 +249,7 @@ text-shadow: 1px 1px 4px#000;
|
||||
background: #fff;
|
||||
text-shadow: 1px 1px 4px#000;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.3em">I'm pretty milky looking text</p>
|
||||
|
||||
![image](../media/text-shadow-11.png)
|
||||
![image](./text-shadow-11.png)
|
||||
|
||||
## 5.4 Duplicate your text
|
||||
|
||||
@ -265,7 +265,7 @@ text-shadow: 0px 20px #000;
|
||||
background: #fff;
|
||||
text-shadow: 0px 20px #000;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.3em">Which line is text, which is shadow?</p>
|
||||
|
||||
![image](../media/text-shadow-13.png)
|
||||
![image](./text-shadow-13.png)
|
||||
|
||||
## 5.5 Multiple shadows
|
||||
|
||||
@ -274,26 +274,32 @@ Sadly Safari 3 isn't able to render more than one shadow on one element. It just
|
||||
```css
|
||||
color: #000;
|
||||
background: #000;
|
||||
text-shadow: 0 0 4px #ccc, 0 -5px 4px #ff3, 2px -10px 6px #fd3, -2px -15px 11px
|
||||
#f80, 2px -18px 18px #f20;
|
||||
text-shadow:
|
||||
0 0 4px #ccc,
|
||||
0 -5px 4px #ff3,
|
||||
2px -10px 6px #fd3,
|
||||
-2px -15px 11px #f80,
|
||||
2px -18px 18px #f20;
|
||||
```
|
||||
|
||||
<p style="color: #000;
|
||||
background: #000;
|
||||
text-shadow: 0 0 4px #ccc, 0 -5px 4px #ff3, 2px -10px 6px #fd3, -2px -15px 11px #f80, 2px -18px 18px #f20;text-align:center;font-size:24px;font-family:Helvetica,sans-serif;font-weight:300;padding:0.5em">Isn't this awesome?</p>
|
||||
|
||||
![image](../media/text-shadow-12.png)
|
||||
![image](./text-shadow-12.png)
|
||||
|
||||
## 6. Hack: Avoid jagged light-on-dark text rendering in Safari
|
||||
|
||||
[![sub-pixel rendering](../media/text-shadow-15.png)](../media/text-shadow-hack.png)
|
||||
![sub-pixel rendering](./text-shadow-hack.png)
|
||||
|
||||
More than a hack than an effect but it addresses the poor light-on-dark text rendering in Safari. This is caused by the [sub-pixel rendering](http://en.wikipedia.org/wiki/Subpixel_rendering) of OS X's Quartz 2D layer as a part of the Core Graphics framework. Also Safari 3.1 on Windows uses sub pixel rendering instead of plain anti-aliasing.
|
||||
|
||||
[![anti-alias rendering through text-shadow](../media/text-shadow-14.png)](../media/text-shadow-hack.png)
|
||||
![sub-pixel rendering](./text-shadow-15.png)
|
||||
|
||||
In most situations this improves the legibility and smoothness of all 2D-text rendered throughout the Mac OS X interface which makes everything look so gorgeous. But it has some [rough problems with light text on dark backgrounds in Safari](http://equinox-of-insanity.com/2007/08/osx-text-rendering/) This problem doesn't exist when using anti-aliasing.
|
||||
|
||||
![anti-aliasing rendering](./text-shadow-14.png)
|
||||
|
||||
And since [24ways'](http://24ways.org/2006/knockout-type) and [Cameron's discovery](http://cameron.io/photo/id:1055) we know that Safari renders all text-shadow-styled text with plain anti-aliasing instead of sub-pixels. So we can add a text-shadow with an offset of 0px to the desired text style:
|
||||
|
||||
```css
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@ -1,17 +0,0 @@
|
||||
---
|
||||
title: Apple releases plugin-SDK for Aperture 2.1
|
||||
date: 2008-04-22 05:58:41+00:00
|
||||
|
||||
tags:
|
||||
- photography
|
||||
- aperture
|
||||
- apple
|
||||
---
|
||||
|
||||
![Aperture](../media/aperture97.png)Just right after [Tiffen and Digital Film Tools announced](http://www.kremalicious.com/2008/04/first-aperture-adjustment-plugins-have-arrived/) their new image editing plugins for Aperture 2.1 Apple has released the Software Development Kit (SDK) for coding Aperture 2.1 plugins. It's available [from Apple's Developer Connection](https://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?bundleID=20044) for registered members (registering is free). You can grab the Aperture 2.1 plugin-SDK (3D9) as a 595KB download from there and start coding.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
If you want to know what exactly you can do with it as a programmer you should [read those lines from Apple](http://developer.apple.com/appleapplications/aperturesdk.html).
|
||||
|
||||
So it should be just a matter of time before we see another bunch of plugins popping out.
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
@ -0,0 +1,19 @@
|
||||
---
|
||||
title: Apple releases plugin-SDK for Aperture 2.1
|
||||
date: 2008-04-22 05:58:41+00:00
|
||||
|
||||
tags:
|
||||
- photography
|
||||
- aperture
|
||||
- apple
|
||||
---
|
||||
|
||||
Just right after [Tiffen and Digital Film Tools announced](http://www.kremalicious.com/2008/04/first-aperture-adjustment-plugins-have-arrived/) their new image editing plugins for Aperture 2.1, Apple has released the Software Development Kit (SDK) for coding Aperture 2.1 plugins.
|
||||
|
||||
![Aperture](./aperture97.png)
|
||||
|
||||
It's available [from Apple's Developer Connection](https://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?bundleID=20044) for registered members (registering is free). You can grab the Aperture 2.1 plugin-SDK (3D9) as a 595KB download from there and start coding.
|
||||
|
||||
If you want to know what exactly you can do with it as a programmer you should [read those lines from Apple](http://developer.apple.com/appleapplications/aperturesdk.html).
|
||||
|
||||
So it should be just a matter of time before we see another bunch of plugins popping out.
|
@ -9,9 +9,9 @@ tags:
|
||||
- css
|
||||
---
|
||||
|
||||
![WebKit](../media/webkit.png)They won't stop with their cutting edge love. After having [text-shadow](http://www.kremalicious.com/2008/04/make-cool-and-clever-text-effects-with-css-text-shadow/) implemented since many years and having a bunch of other cool stuff implemented like CSS gradients or CSS box-shadow the WebKit team freshly announced a new cool feature: CSS alpha masks.
|
||||
They won't stop with their cutting edge love. After having [text-shadow](http://www.kremalicious.com/2008/04/make-cool-and-clever-text-effects-with-css-text-shadow/) implemented since many years and having a bunch of other cool stuff implemented like CSS gradients or CSS box-shadow the WebKit team freshly announced a new cool feature: CSS alpha masks.
|
||||
|
||||
<!-- more -->
|
||||
![WebKit](./webkit.png)
|
||||
|
||||
From the Surfin' Safari Blog:
|
||||
|
After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 57 KiB |
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Using the CanoScan LiDE 500F scanner with Mac OS X Leopard
|
||||
image: ../media/canoscanlide500f.jpg
|
||||
image: ./canoscanlide500f.jpg
|
||||
|
||||
date: 2008-05-04 16:04:48+00:00
|
||||
|
||||
@ -27,7 +27,7 @@ The changelog says:
|
||||
|
||||
So this sounds just right. You can download the new universal scanner driver from [Canon USA](http://www.usa.canon.com/consumer/controller?act=ModelInfoAct&tabact=SupportDetailTabAct&fcategoryid=235&modelid=11011#DownloadDetailAct) or [Canon Asia](http://support-asia.canon-asia.com/contents/ASIA/EN/0900321901.html). Following these links takes you right to the driver download page for this scanner.
|
||||
|
||||
![Driver package contents](../media/canondrivercontents.png)
|
||||
![Driver package contents](./canondrivercontents.png)
|
||||
|
||||
You will get a file named lide500fosx11250en.dmg in your downloads folder. Just mount it and double click the package installer inside of the image. If you have a previous version of the driver installed you should remove all parts of it from the system and make a restart to avoid any problems. You can follow my screenshot on the right which shows the contents of the installer package to find all components on your system.
|
||||
|
||||
@ -39,7 +39,7 @@ After a restart you should be able to use the scanner as a TWAIN device all over
|
||||
|
||||
### Preview / Image Capture
|
||||
|
||||
![Scan window Preview](../media/scanwindow_preview.png)
|
||||
![Scan window Preview](./scanwindow_preview.png)
|
||||
|
||||
Leopard included a new version of Preview, the pdf and image-viewing application by Apple and also a new version of Image Capture. To use it with your scanner just plug in the scanner, open Preview and choose File > Import Image or just open the Image Capture application. A new scan window should open doing an automatic overview scan. In the scan window you have some minor options like resolution, scaling etc. You can even make simple but powerful image corrections down at the bottom (set it to manual).
|
||||
|
||||
@ -47,7 +47,7 @@ But the best thing with the new Image Capture is the feature of setting the bit
|
||||
|
||||
### Scanning right into Apple Aperture
|
||||
|
||||
![Aperture Scanning](../media/aperturescan.png)
|
||||
![Aperture Scanning](./aperturescan.png)
|
||||
|
||||
Wouldn't that be great? Although the scanner is shown as a source in the import dialogue you can't import images with it directly from Aperture. Maybe someone will code a generic scanning plugin for Aperture like VueScan for Aperture or something like that. But I guess this is something just Canon is able to do that and they won't.
|
||||
|
||||
@ -55,11 +55,11 @@ But using Preview/Image Capture and Automator you can bypass this limitation. If
|
||||
|
||||
### Adobe Photoshop CS3
|
||||
|
||||
![ScanGear Scan Window](../media/scangearwindow.png)
|
||||
![ScanGear Scan Window](./scangearwindow.png)
|
||||
|
||||
Just like with Creative Suite 2 you can use Photoshop to import images with your Scanner by using the Canon ScanGear software which indeed is just the scan window in Photoshop. Just chose File > Import > CanoScan LiDE 500F in Photoshop. If you have installed the driver for the first time the scan window in Photoshop defaults to Simple Mode. But if you want it simple you better chose a Preview/Image Capture workflow. So in Photoshop you should head over to Advanced Mode and check the preferences button down at the bottom first.
|
||||
|
||||
![ScanGear Color Settings](../media/scangear_color.png)
|
||||
![ScanGear Color Settings](./scangear_color.png)
|
||||
|
||||
Under the Color Settings tab you should set your preferred color management options.
|
||||
|
||||
@ -69,6 +69,6 @@ Another task you should do before scanning the first time with this driver is ca
|
||||
|
||||
Now you can set your scanning preferences and start scanning into Photoshop. Don't forget to chose Color(48Bit) in the Color Mode dropdown menu for 16 bit scanning.
|
||||
|
||||
![Color Mode](../media/scangear48bit.png)
|
||||
![Color Mode](./scangear48bit.png)
|
||||
|
||||
The advantage of this last workflow with Photoshop and ScanGear is more control over the scanner and therefore more control of the way your images will look right after the scan. If you want simplicity do it the OSX way by using Preview/Image Capture and simply automate it with Automator to serve your scanned images to your preferred application.
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
@ -1,38 +0,0 @@
|
||||
---
|
||||
title: Scan images directly into Apple Aperture
|
||||
author: Matthias Kretschmann
|
||||
image: ../media/aperturescan.png
|
||||
|
||||
date: 2008-05-05 04:15:11+00:00
|
||||
|
||||
tags:
|
||||
- photography
|
||||
- aperture
|
||||
- tutorial
|
||||
- macos
|
||||
- apple
|
||||
|
||||
toc: true
|
||||
---
|
||||
|
||||
Wouldn't that be great? Hook up your scanner, fire up Aperture, click on Import and the images coming directly from your scanner plate? Although my scanner is shown as a source in the import dialogue you can't import images with it directly from Aperture. But using Preview/Image Capture and Automator you can bypass this limitation. So here's what you can do to scan directly into Aperture in 3 simple steps.
|
||||
|
||||
In the Image Capture scan window you can define an automatic task which will follow the scan process. It defaults to Preview meaning that the scanned image will open as a new Preview document after the scan. But we can make the images import to Aperture after the scan just with tools which are build into Mac OS X and come with every Mac (besides Aperture).
|
||||
|
||||
## 1. Make an Automator action
|
||||
|
||||
![Automator](../media/automator.png)Open up Automator and click on the photos library item. Find the Aperture action "Import Photos" and drag and drop it on the workflow field. Then you can chose your desired project or a new project for the scanned images to appear. I have a project for all new images called @Review so I chose that one as my target project. You can set a referenced import or the deletion of your source images as well. If you want to chose the desired project or any of the other preferences every time you're scanning you have to activate "Show this action when the workflow runs" in the Options of this action.
|
||||
|
||||
To make it a bit cooler we can assign one or more keywords to our scanned images automatically. Just drag and drop the "Assign keywords to images" action and add a keyword like "Scan" or something like that. Finally we can set some usual IPTC-tags with the "Set IPTC Tags" action. In the end you should have something like this (click to zoom):
|
||||
|
||||
[![Aperture Import Workflow](../media/apertureimport_automator.png)](../media/apertureimport_automator.png)
|
||||
|
||||
## 2. Save it as a plug-in for Image Capture
|
||||
|
||||
[![Aperture Import Workflow2](../media/apertureimportplugin.png)](../media/apertureimportplugin.png)Now we're going to save the whole workflow we clicked together. But instead of saving it as a general workflow chose File > Save as Plug-in. Type in a name like "Import to Aperture" and chose Image Capture from the dropdown menu and click save. Now your workflow has become a freshly new plug-in of the Image Capture application. If you ever want to delete, edit or just backup your Image Capture Plugins you can find them in your user folder library under /Workflows/Applications/Image Capture.
|
||||
|
||||
## 3. Scanning and have fun
|
||||
|
||||
[![Aperture Import Workflow3](../media/apertureimport_automatic.png)](../media/apertureimport_automatic.png)Plug in your scanner and open up Image Capture. A new scan window should open with your connected scanner as source. Now we have to define our freshly created plug-in as a task which will run after the image was scanned. Just chose your freshly created workflow from the Automatic Task dropdown menu and there you have it. So after you hit the scan button our freshly created workflow will run after the scan.
|
||||
|
||||
Just be creative with Automator. You can set up a lot of workflows for every thinkable scanning task and you can even backup your scanned images before or after importing them to Aperture by copying them into a new burn folder or make an archive from them which also could be automatically saved to a web server and so on...
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 30 KiB |