Compare commits
30 Commits
677b9c795b
...
ghost-impo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38af618fc1 | ||
|
|
df0fbfd1e2 | ||
|
|
bd0c9bb174 | ||
|
|
b52a691246 | ||
|
|
f45a90978a | ||
|
|
72a49ac52e | ||
|
|
5e8be866b4 | ||
|
|
03b73cbae5 | ||
|
|
daf10449e3 | ||
|
|
a37b8e68d3 | ||
|
|
0f5d81e59f | ||
|
|
5ebd808a20 | ||
|
|
c391cd96f0 | ||
|
|
65813f28f5 | ||
|
|
6b97640b61 | ||
|
|
f2606bbfc6 | ||
|
|
800f9b7c8e | ||
|
|
3900c58641 | ||
|
|
07c8038c6f | ||
|
|
c2cb27d0f0 | ||
|
|
af5c5ffde8 | ||
|
|
0f48194d81 | ||
|
|
fbfed95657 | ||
|
|
fc1d35edd7 | ||
|
|
2bdd8579ab | ||
|
|
19efd62543 | ||
|
|
56c4c1feb3 | ||
|
|
8a7187c803 | ||
|
|
843416ff27 | ||
|
|
9120b153fd |
22
.editorconfig
Normal file
@@ -0,0 +1,22 @@
|
||||
# Cross-platform formatting config
|
||||
# See https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
[{*.{js,json,css,scss,html,jsx},.babelrc}]
|
||||
# Set default charset
|
||||
charset = utf-8
|
||||
# 4 space indentation
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
3
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
/out/
|
||||
/node_modules/
|
||||
/node_modules/
|
||||
/_site/
|
||||
|
||||
53
README.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# WhenWe
|
||||
|
||||
Whenwe is dead. Long love Whenwe?
|
||||
|
||||
A "when-we" is a nostagic reminisce. This is an archive of when-wes, currently.
|
||||
|
||||
However, it may grow into a database of mini-biographies. Time will tell...
|
||||
|
||||
## Structure
|
||||
|
||||
- `src/` - the website content and templates
|
||||
- `bin/` - helper scripts
|
||||
|
||||
Everything in the top directory are configs and documentation, like this.
|
||||
|
||||
## Requirements
|
||||
|
||||
The site is built using [Eleventy][eleventy]. We assume you have Git, NodeJS and NPM installed.
|
||||
|
||||
## Installation for development or deployment
|
||||
|
||||
git clone $whenwe_repo_url
|
||||
cd whenwe
|
||||
npm install
|
||||
|
||||
## Development
|
||||
|
||||
npm run server
|
||||
|
||||
Now you should be able to visit the development site in your browser at http://localhost:8080
|
||||
|
||||
If you edit the content in `src/` - it should rebuild the site. Your browser should refresh automatically, but if not, refresh it manually.
|
||||
|
||||
See the [README.md](./src/) in `src/` for more information.
|
||||
|
||||
## Deployment
|
||||
|
||||
Currently the destination is configured in package.json, as part of the definition of the `deploy` run-script. To change the destination, change that.
|
||||
|
||||
`rsync` is used for deploying the site. Therefore you need to have that installed and on the path.
|
||||
|
||||
You will need `ssh` access to the destination. Setting that up is outside the scope of this document, but if you have your own web space, you will probably know about this already, and if not, you will need the assistance of someone who does. Setting up your ssh client depends on your OS - there are guides online.
|
||||
|
||||
But given that, the deploy process goes like this:
|
||||
|
||||
npm run build
|
||||
npm run deploy
|
||||
|
||||
## Issues and questions
|
||||
|
||||
These can be submitted via the issue tracker attached to this repository. You may need to create an account.
|
||||
|
||||
[eleventy]: https://www.11ty.dev/
|
||||
@@ -4,11 +4,17 @@
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "rm -rf _site && eleventy --pathprefix '~nick/whenwe/'",
|
||||
"deploy": "bin/deploy nick@mixian.noodlefactory.co.uk:public_html/whenwe/",
|
||||
"server": "eleventy --serve",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"node-html-markdown": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "^1.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
328
to-ghost.js
Normal file
@@ -0,0 +1,328 @@
|
||||
const data = require("./whenwe-tidied.json");
|
||||
const fs = require("fs");
|
||||
//const sh = require("sanitize-html");
|
||||
const {
|
||||
NodeHtmlMarkdown,
|
||||
NodeHtmlMarkdownOptions,
|
||||
} = require("node-html-markdown");
|
||||
const nhm = new NodeHtmlMarkdown({
|
||||
useLinkReferenceDefinitions: true,
|
||||
useInlineLinks: true,
|
||||
});
|
||||
function date(datestr) {
|
||||
if (datestr) {
|
||||
const [Y, M, D, h, m, s] = datestr.split(/[^0-9]/);
|
||||
return new Date(Date.UTC.call(null, Y, M - 1, D, h, m, s)).toISOString();
|
||||
} else return "";
|
||||
}
|
||||
|
||||
const tag_index = {
|
||||
// 1: { id: 1, name: "", slug: "" },
|
||||
};
|
||||
|
||||
const user_index = {
|
||||
"6975f732f0a00f00018346d1": {
|
||||
id: "6975f732f0a00f00018346d1",
|
||||
name: "Janet Woolley",
|
||||
slug: "janet",
|
||||
},
|
||||
};
|
||||
|
||||
const meta_index = {};
|
||||
|
||||
const author_index = {};
|
||||
|
||||
const ghost_data = {
|
||||
meta: {
|
||||
exported_on: new Date().valueOf(),
|
||||
version: "5.0.0", // Ghost version the import is valid for
|
||||
},
|
||||
data: {
|
||||
posts: [],
|
||||
// Optionally define post metadata
|
||||
posts_meta: [
|
||||
/*
|
||||
{
|
||||
post_id: "1234", // This must be the same as the post it references
|
||||
feature_image_alt: "A group of people waving at the camera",
|
||||
feature_image_caption: "The team says hello!",
|
||||
},
|
||||
*/
|
||||
],
|
||||
// Define the tags
|
||||
tags: [],
|
||||
// Relate posts to tags
|
||||
posts_tags: [],
|
||||
// Define the users
|
||||
/*
|
||||
users: [
|
||||
{
|
||||
id: "5678", // Unique ID for this author
|
||||
name: "Jo Bloggs",
|
||||
slug: "jo-blogs",
|
||||
email: "jo@example.com",
|
||||
profile_image: "/content/images/2025/scenic-background.jpg",
|
||||
roles: [
|
||||
"Contributor", // Contributor | Author| Editor | Administrator
|
||||
],
|
||||
},
|
||||
],
|
||||
*/
|
||||
// Relate posts to authors
|
||||
},
|
||||
};
|
||||
|
||||
function convertCase(
|
||||
str, //: string,
|
||||
format, // 'camel' | 'pascal' | 'snake' | 'kebab'
|
||||
) {
|
||||
const sanitiseString = (str) =>
|
||||
str
|
||||
.trim()
|
||||
.replace(/[^a-zA-Z0-9\s]/g, "")
|
||||
.replace(/\s+/g, " ");
|
||||
const formatted = sanitiseString(str);
|
||||
switch (format) {
|
||||
case "camel":
|
||||
return formatted
|
||||
.toLowerCase()
|
||||
.replace(/ (\\w)/g, (_, char) => char.toUpperCase());
|
||||
case "pascal":
|
||||
return formatted.replace(/(?:^| )(\w)/g, (_, char) => char.toUpperCase());
|
||||
case "snake":
|
||||
return formatted.toLowerCase().replace(/\s+/g, "_");
|
||||
case "kebab":
|
||||
return formatted.toLowerCase().replace(/\s+/g, "-");
|
||||
default:
|
||||
throw new Error("Unsupported format type");
|
||||
}
|
||||
}
|
||||
|
||||
function mk_tag(name, id, slug) {
|
||||
id ??= convertCase(name, "kebab");
|
||||
slug ??= id;
|
||||
tag_index[id] ??= { id, name, slug };
|
||||
return id;
|
||||
}
|
||||
|
||||
function mk_author(post_id, author_id) {
|
||||
author_index[post_id] = { post_id, author_id };
|
||||
}
|
||||
|
||||
function mk_meta(post_id, feature_image_caption, feature_image_alt) {
|
||||
if (feature_image_alt || feature_image_caption)
|
||||
meta_index[post_id] = {
|
||||
feature_image_alt,
|
||||
feature_image_caption,
|
||||
post_id,
|
||||
};
|
||||
}
|
||||
|
||||
function img_path(filename) {
|
||||
if (!filename) throw new Error("No filename");
|
||||
return "content/images/" + filename.trim();
|
||||
}
|
||||
|
||||
function img(filename, height, width, title, alt) {
|
||||
if (!filename) return undefined;
|
||||
if (typeof filename !== "string")
|
||||
throw new Error("not a string: " + filename);
|
||||
return {
|
||||
row: 0,
|
||||
src: img_path(filename),
|
||||
width: width ?? 100,
|
||||
height: height ?? 100,
|
||||
filename: filename,
|
||||
};
|
||||
}
|
||||
|
||||
function sanitize(body) {
|
||||
return nhm
|
||||
.translate(body)
|
||||
.replaceAll(/https?:\/[^"]*?\/public\//g, "content/images/2026/01/")
|
||||
.replaceAll(/[?]itok=[A-Za-z0-9_-]*/g, "");
|
||||
}
|
||||
|
||||
function sanitize_html(body) {
|
||||
return body
|
||||
.replaceAll(/https?:\/[^"]*?\/public\//g, "content/images/2026/01/")
|
||||
.replaceAll(/[?]itok=[^ ]*/g, "");
|
||||
}
|
||||
|
||||
for (const node of data) {
|
||||
let body = sanitize_html(node.body.und[0].safe_value);
|
||||
const id = Number(node.nid);
|
||||
const lexical = {
|
||||
root: {
|
||||
children: [],
|
||||
direction: "ltr",
|
||||
format: "",
|
||||
indent: 0,
|
||||
type: "root",
|
||||
version: 1,
|
||||
},
|
||||
};
|
||||
let author = node.field_original_author?.und?.[0]?.value;
|
||||
let feature_image = node.field_featured_image?.und?.[0]?.filename;
|
||||
|
||||
let tags = [];
|
||||
mk_meta(
|
||||
id,
|
||||
node.field_featured_image?.und?.[0]?.title,
|
||||
node.field_featured_image?.und?.[0]?.alt,
|
||||
);
|
||||
mk_author(id, "6975f732f0a00f00018346d1");
|
||||
|
||||
const category_id = node.field_category?.und?.[0]?.tid;
|
||||
if (category_id) {
|
||||
tags.push(
|
||||
mk_tag(
|
||||
"category-" + category_id,
|
||||
"Category " + category_id,
|
||||
"category-" + category_id,
|
||||
),
|
||||
);
|
||||
}
|
||||
/*
|
||||
lexical.root.children.push({
|
||||
children: [
|
||||
{
|
||||
type: "markdown",
|
||||
version: 1,
|
||||
markdown: sanitize(body),
|
||||
},
|
||||
],
|
||||
direction: "ltr",
|
||||
format: "",
|
||||
indent: 0,
|
||||
type: "paragraph",
|
||||
version: 1,
|
||||
});
|
||||
*/
|
||||
switch (node.type) {
|
||||
case "article":
|
||||
{
|
||||
tags.push(mk_tag("Story", "story", "story"));
|
||||
|
||||
let images = node.field_basic_image_image?.und;
|
||||
if (images) {
|
||||
// console.error(">>", images);
|
||||
/*
|
||||
images = images.map((image) =>
|
||||
img(image.filename, img.height, image.width, img.title, img.alt),
|
||||
);
|
||||
*/
|
||||
|
||||
images = images.map(
|
||||
(image) =>
|
||||
`
|
||||
<div class="kg-gallery-image">
|
||||
<img src="${img_path(image.filename)}" width="${image.width}" height="${image.height}" loading="lazy" alt="${image.alt}" title="${image.title}">
|
||||
</div>
|
||||
`,
|
||||
);
|
||||
|
||||
body += `
|
||||
<hr>
|
||||
<figure class="kg-card kg-gallery-card kg-width-wide">
|
||||
<div class="kg-gallery-container">
|
||||
<div class="kg-gallery-row">
|
||||
${images.join("")}
|
||||
</div>
|
||||
</div>
|
||||
<figcaption></figcaption>
|
||||
</figure>
|
||||
`;
|
||||
/*
|
||||
lexical.root.children.push({
|
||||
type: "gallery",
|
||||
version: 1,
|
||||
images,
|
||||
caption: "",
|
||||
});
|
||||
*/
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "person":
|
||||
{
|
||||
const surname_at_birth = node.field_surname_at_birth?.und?.[0]?.value;
|
||||
const other_surnames = node.field_other_surnames?.und?.[0]?.value;
|
||||
|
||||
tags.push(mk_tag("Person", "person", "person"));
|
||||
if (surname_at_birth) {
|
||||
tags.push(
|
||||
mk_tag(
|
||||
surname_at_birth,
|
||||
"surname-" + convertCase(surname_at_birth, "kebab"),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (other_surnames) {
|
||||
tags.push(
|
||||
mk_tag(
|
||||
other_surnames,
|
||||
"surname-" + convertCase(other_surnames, "kebab"),
|
||||
),
|
||||
);
|
||||
}
|
||||
/*
|
||||
forename_at_birth: node.field_forename_at_birth?.und?.[0]?.value,
|
||||
other_forenames: node.field_other_forenames?.und?.[0]?.value,
|
||||
title: node.field_title?.und?.[0]?.value,
|
||||
date_of_birth: date(node.field_date_of_birth?.und?.[0]?.value),
|
||||
date_of_death: date(node.field_date_of_death?.und?.[0]?.value),
|
||||
parent_of: node.field_parent_of?.und?.[0]?.value,
|
||||
child_of: node.field_child_of?.und?.[0]?.value,
|
||||
partner_of: node.field_partner_of?.und?.[0]?.value,
|
||||
// lifetime: node.field_lifetime?.und?.[0]?.value,
|
||||
*/
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (const tag_id of tags) {
|
||||
ghost_data.data.posts_tags.push({
|
||||
post_id: id,
|
||||
tag_id,
|
||||
});
|
||||
}
|
||||
|
||||
ghost_data.data.posts.push({
|
||||
id,
|
||||
type: "post",
|
||||
title: node.title,
|
||||
slug: node.path.alias.replace(/^.*[/]/, ""),
|
||||
html: body,
|
||||
feature_image: img(feature_image)?.src,
|
||||
created_at: new Date(Number(node.created) * 1000).toISOString(),
|
||||
updated_at: new Date(Number(node.changed) * 1000).toISOString(),
|
||||
status: "draft",
|
||||
});
|
||||
|
||||
// const author = node.field_original_author?.und?.[0]?.value;
|
||||
|
||||
/*
|
||||
{
|
||||
id: "1234", // The post ID, which is refered to in other places in this file
|
||||
title: "My Blog Post Title",
|
||||
slug: "my-blog-post-title",
|
||||
html: "<p>Hello world, this is an article</p>", // You could use `lexical` instead to to represent your content
|
||||
comment_id: "1234-old-cms-post-id", // The ID from the old CMS, which can be output in the theme
|
||||
feature_image: "/content/images/2024/waving.jpg",
|
||||
type: "post", // post | page
|
||||
status: "published", // published | draft
|
||||
visibility: "public", // public | members | paid
|
||||
created_at: "2025-06-30 15:31:36",
|
||||
updated_at: "2025-07-02 08:22:14",
|
||||
published_at: "2025-06-30 15:35:36",
|
||||
custom_excerpt: "My custom excerpt",
|
||||
},*/
|
||||
}
|
||||
|
||||
ghost_data.data.tags = Object.values(tag_index);
|
||||
ghost_data.data.posts_authors = Object.values(author_index);
|
||||
ghost_data.data.posts_meta = Object.values(meta_index);
|
||||
|
||||
console.log(JSON.stringify(ghost_data, null, 2));
|
||||
@@ -1,72 +0,0 @@
|
||||
const data = require('./whenwe.json');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { NodeHtmlMarkdown, NodeHtmlMarkdownOptions } = require('node-html-markdown');
|
||||
const nhm = new NodeHtmlMarkdown({
|
||||
useLinkReferenceDefinitions: true,
|
||||
useInlineLinks: true,
|
||||
});
|
||||
|
||||
function toYaml(data, body) {
|
||||
const frontmatter = Object.keys(data).sort().map(key => key+': '+(data[key] ?? '')).join("\n");
|
||||
return frontmatter + "\n---\n" + nhm.translate(body);
|
||||
}
|
||||
|
||||
function date(datestr) {
|
||||
if (datestr) {
|
||||
const [Y,M,D,h,m,s] = datestr.split(/[^0-9]/)
|
||||
return new Date(Date.UTC.call(null, Y,M-1,D,h,m,s)).toISOString();
|
||||
}
|
||||
else
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
data.forEach((node, ix) => {
|
||||
const lang = 'und';
|
||||
const filepath = path.join('out', node.type);
|
||||
const body = node.body.und[0].value;
|
||||
const filename = `${node.uuid}.yml`;
|
||||
|
||||
fs.mkdirSync(path.join(__dirname, filepath), { recursive: true });
|
||||
const item = {
|
||||
ix: ix,
|
||||
nid: Number(node.nid),
|
||||
type: node.type,
|
||||
title: node.title,
|
||||
uuid: node.uuid,
|
||||
created: new Date(Number(node.created)*1000).toISOString(),
|
||||
changed: new Date(Number(node.changed)*1000).toISOString(),
|
||||
path: node.path.alias,
|
||||
comment_count: node.comment_count,
|
||||
};
|
||||
switch(node.type) {
|
||||
case 'article':
|
||||
Object.assign(item, {
|
||||
original_author: node.field_original_author?.und?.[0]?.value,
|
||||
featured_image: node.field_featured_image?.und?.[0]?.filename,
|
||||
images: node.field_basic_image_image?.und?.map(item => item.filename),
|
||||
category: node.field_category?.und?.[0]?.tid,
|
||||
});
|
||||
break;
|
||||
|
||||
case 'person':
|
||||
Object.assign(item, {
|
||||
forename_at_birth: node.field_forename_at_birth?.und?.[0]?.value,
|
||||
surname_at_birth: node.field_surname_at_birth?.und?.[0]?.value,
|
||||
other_surnames: node.field_other_surnames?.und?.[0]?.value,
|
||||
other_forenames: node.field_other_forenames?.und?.[0]?.value,
|
||||
title: node.field_title?.und?.[0]?.value,
|
||||
date_of_birth: date(node.field_date_of_birth?.und?.[0]?.value),
|
||||
date_of_death: date(node.field_date_of_death?.und?.[0]?.value),
|
||||
parent_of: node.field_parent_of?.und?.[0]?.value,
|
||||
child_of: node.field_child_of?.und?.[0]?.value,
|
||||
partner_of: node.field_partner_of?.und?.[0]?.value,
|
||||
// lifetime: node.field_lifetime?.und?.[0]?.value,
|
||||
featured_image: node.field_featured_image?.und?.[0]?.filename,
|
||||
});
|
||||
break;
|
||||
}
|
||||
fs.writeFileSync(path.join(filepath, filename), toYaml(item, body));
|
||||
console.log(item.title);
|
||||
});
|
||||
14818
whenwe-tidied.json
Normal file
1159
zip/content.json
Normal file
BIN
zip/content/images/ Elsie about 1960.jpg
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
zip/content/images/000013.jpg
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
zip/content/images/001 ready to climb from base camp.jpg
Normal file
|
After Width: | Height: | Size: 829 KiB |
BIN
zip/content/images/002 looking up towards the peak.jpg
Normal file
|
After Width: | Height: | Size: 931 KiB |
|
After Width: | Height: | Size: 769 KiB |
|
After Width: | Height: | Size: 813 KiB |
BIN
zip/content/images/005 looking down from a high ridge.jpg
Normal file
|
After Width: | Height: | Size: 670 KiB |
BIN
zip/content/images/006 another view from above.jpg
Normal file
|
After Width: | Height: | Size: 802 KiB |
BIN
zip/content/images/007 at the top.jpg
Normal file
|
After Width: | Height: | Size: 693 KiB |
BIN
zip/content/images/008 crossing the glacier on the way down.jpg
Normal file
|
After Width: | Height: | Size: 631 KiB |
BIN
zip/content/images/009 making their way down.jpg
Normal file
|
After Width: | Height: | Size: 945 KiB |
BIN
zip/content/images/010 Stan arives home after his journey.jpg
Normal file
|
After Width: | Height: | Size: 840 KiB |
BIN
zip/content/images/1959 Christmas tree at Kagumo000001.jpg
Normal file
|
After Width: | Height: | Size: 662 KiB |
BIN
zip/content/images/1959 K&m with bike.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
zip/content/images/1959 Kathy and flower.jpg
Normal file
|
After Width: | Height: | Size: 866 KiB |
BIN
zip/content/images/1959 Kathy and sand castle.jpg
Normal file
|
After Width: | Height: | Size: 601 KiB |
BIN
zip/content/images/1959 Mike choing wood.jpg
Normal file
|
After Width: | Height: | Size: 581 KiB |
BIN
zip/content/images/1959 Mu and Kath in the sea.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
zip/content/images/1959 Mu and Kath on the beach.jpg
Normal file
|
After Width: | Height: | Size: 601 KiB |
BIN
zip/content/images/1959 Nandi flame at Kagumo.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
zip/content/images/1959 christmas blur.jpg
Normal file
|
After Width: | Height: | Size: 662 KiB |
BIN
zip/content/images/1959 coast Kath.jpg
Normal file
|
After Width: | Height: | Size: 908 KiB |
BIN
zip/content/images/1960 Diani.jpg
Normal file
|
After Width: | Height: | Size: 807 KiB |
BIN
zip/content/images/1960 Kathy on verandah.jpg
Normal file
|
After Width: | Height: | Size: 717 KiB |
BIN
zip/content/images/1960 Mike with boat.jpg
Normal file
|
After Width: | Height: | Size: 911 KiB |
BIN
zip/content/images/1960 Molly and Irene.jpg
Normal file
|
After Width: | Height: | Size: 627 KiB |
BIN
zip/content/images/1960 Mu and Jan on the reef.jpg
Normal file
|
After Width: | Height: | Size: 695 KiB |
BIN
zip/content/images/1960 Mu and chidren at low tide.jpg
Normal file
|
After Width: | Height: | Size: 625 KiB |
BIN
zip/content/images/1960 Wells bungalow.jpg
Normal file
|
After Width: | Height: | Size: 830 KiB |
BIN
zip/content/images/1960 bougainvillea.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
zip/content/images/1960 classic photo.jpg
Normal file
|
After Width: | Height: | Size: 943 KiB |
BIN
zip/content/images/1960 dusty road Nyeri.jpg
Normal file
|
After Width: | Height: | Size: 732 KiB |
BIN
zip/content/images/1960 eating mango.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
zip/content/images/1960 grass nests.jpg
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
zip/content/images/1960 jacaranda at Kagumo.jpg
Normal file
|
After Width: | Height: | Size: 994 KiB |
BIN
zip/content/images/1960 on the steps at Kagumo.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
zip/content/images/1960 shell sellers.jpg
Normal file
|
After Width: | Height: | Size: 732 KiB |
BIN
zip/content/images/1960 tree house on Open Day_1.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
zip/content/images/1960 view from bungalow.jpg
Normal file
|
After Width: | Height: | Size: 699 KiB |
BIN
zip/content/images/1960 view from our garden Kagummo.jpg
Normal file
|
After Width: | Height: | Size: 668 KiB |
BIN
zip/content/images/1960_.jpg
Normal file
|
After Width: | Height: | Size: 743 KiB |
BIN
zip/content/images/1960_also_at_redcar.jpg
Normal file
|
After Width: | Height: | Size: 614 KiB |
BIN
zip/content/images/1960_at_redcar.jpg
Normal file
|
After Width: | Height: | Size: 628 KiB |
BIN
zip/content/images/1960_boating_lake_at_bromley_2.jpg
Normal file
|
After Width: | Height: | Size: 985 KiB |
BIN
zip/content/images/1960_boating_lake_bromley.jpg
Normal file
|
After Width: | Height: | Size: 976 KiB |
BIN
zip/content/images/1960_bridge_over_uaso_niro_river.jpg
Normal file
|
After Width: | Height: | Size: 846 KiB |
BIN
zip/content/images/1960_children_in_elsies_garden.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
zip/content/images/1960_family_ay_redcar.jpg
Normal file
|
After Width: | Height: | Size: 829 KiB |
BIN
zip/content/images/1960_hadrians_wall.jpg
Normal file
|
After Width: | Height: | Size: 792 KiB |
BIN
zip/content/images/1960_jan_and_mike_at_archers_post.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
zip/content/images/1960_kath_at_elsies_.jpg
Normal file
|
After Width: | Height: | Size: 878 KiB |
BIN
zip/content/images/1960_mike_and_martin_at_elsies.jpg
Normal file
|
After Width: | Height: | Size: 741 KiB |
BIN
zip/content/images/1960_mm_shortlands.jpg
Normal file
|
After Width: | Height: | Size: 805 KiB |
BIN
zip/content/images/1960_mu_at_buffalo_springs.jpg
Normal file
|
After Width: | Height: | Size: 705 KiB |
BIN
zip/content/images/1960_mu_filming.jpg
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
zip/content/images/1960_mu_j_and_m_.jpg
Normal file
|
After Width: | Height: | Size: 730 KiB |
|
After Width: | Height: | Size: 896 KiB |
BIN
zip/content/images/1960_san_and_mike_at_buffalo_springs.jpg
Normal file
|
After Width: | Height: | Size: 999 KiB |
BIN
zip/content/images/1960_smithes_house_at_shortlands.jpg
Normal file
|
After Width: | Height: | Size: 826 KiB |
BIN
zip/content/images/1960_stokoes_at_tursdale.jpg
Normal file
|
After Width: | Height: | Size: 707 KiB |
BIN
zip/content/images/1960_the_children.jpg
Normal file
|
After Width: | Height: | Size: 651 KiB |
BIN
zip/content/images/1960_the_four_brothers_stokoe.jpg
Normal file
|
After Width: | Height: | Size: 996 KiB |
BIN
zip/content/images/1960_the_wives.jpg
Normal file
|
After Width: | Height: | Size: 673 KiB |
BIN
zip/content/images/1960_uaso_niro_river.jpg
Normal file
|
After Width: | Height: | Size: 855 KiB |
BIN
zip/content/images/1960_view_from_archers_post.jpg
Normal file
|
After Width: | Height: | Size: 1018 KiB |
BIN
zip/content/images/1960s Staff at Kagumo.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
zip/content/images/1961 Gordon at coast_1.jpg
Normal file
|
After Width: | Height: | Size: 980 KiB |
BIN
zip/content/images/1961 Jan and Moira.jpg
Normal file
|
After Width: | Height: | Size: 994 KiB |
BIN
zip/content/images/1961 Jan and Paula watching floods.jpg
Normal file
|
After Width: | Height: | Size: 938 KiB |
BIN
zip/content/images/1961 Kathy Mike Mart on steps.jpg
Normal file
|
After Width: | Height: | Size: 757 KiB |
BIN
zip/content/images/1961 Kathy and Guy Velzian.jpg
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
zip/content/images/1961 M&M up palm tree.jpg
Normal file
|
After Width: | Height: | Size: 831 KiB |
BIN
zip/content/images/1961 Mike dripping sand_1.jpg
Normal file
|
After Width: | Height: | Size: 563 KiB |
BIN
zip/content/images/1961 Nyeri Primary.jpg
Normal file
|
After Width: | Height: | Size: 651 KiB |
BIN
zip/content/images/1961 Watatu garden.jpg
Normal file
|
After Width: | Height: | Size: 821 KiB |
BIN
zip/content/images/1961 all swimming.jpg
Normal file
|
After Width: | Height: | Size: 562 KiB |
BIN
zip/content/images/1961 coast with cousins at xmas_1.jpg
Normal file
|
After Width: | Height: | Size: 431 KiB |
BIN
zip/content/images/1961 dessing up.jpg
Normal file
|
After Width: | Height: | Size: 801 KiB |
BIN
zip/content/images/1961 family and friends picnic.jpg
Normal file
|
After Width: | Height: | Size: 583 KiB |
BIN
zip/content/images/1961 flooded bridge.jpg
Normal file
|
After Width: | Height: | Size: 758 KiB |
BIN
zip/content/images/1961 flooding at Sagana bridge.jpg
Normal file
|
After Width: | Height: | Size: 745 KiB |
BIN
zip/content/images/1961 jan and paula_1.jpg
Normal file
|
After Width: | Height: | Size: 497 KiB |
BIN
zip/content/images/1961 making flower hats.jpg
Normal file
|
After Width: | Height: | Size: 776 KiB |
BIN
zip/content/images/1961 sports day at Kagumo.jpg
Normal file
|
After Width: | Height: | Size: 830 KiB |
BIN
zip/content/images/1961 steps at coast.jpg
Normal file
|
After Width: | Height: | Size: 797 KiB |
BIN
zip/content/images/1961 stuck in mudcoast0026.jpg
Normal file
|
After Width: | Height: | Size: 663 KiB |
BIN
zip/content/images/1961 waiting for the ferry at Kilindini.jpg
Normal file
|
After Width: | Height: | Size: 612 KiB |
BIN
zip/content/images/1961Jan and Martin sandcastle.jpg
Normal file
|
After Width: | Height: | Size: 618 KiB |
BIN
zip/content/images/1961_daphne_at_limuru.jpg
Normal file
|
After Width: | Height: | Size: 941 KiB |
BIN
zip/content/images/1961_hasani_cooking_at_uaso_niro.jpg
Normal file
|
After Width: | Height: | Size: 1001 KiB |
BIN
zip/content/images/1961_limuru_dam_steph_and_jill.jpg
Normal file
|
After Width: | Height: | Size: 670 KiB |
BIN
zip/content/images/1961_monkeys_at_mzima_springs.jpg
Normal file
|
After Width: | Height: | Size: 886 KiB |