Skip to content

Commit

Permalink
Merge pull request #3 from buzcarter/feature/cli_arguments
Browse files Browse the repository at this point in the history
Feature/cli arguments
  • Loading branch information
buzcarter authored Oct 23, 2023
2 parents a78520d + 617a18b commit 724e8de
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 10 deletions.
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This is based on Jeff Thompson's [recipes PHP project](https://github.com/jeffTh

[Live Recipe Book Demo](https://buzcarter.github.io/recipes-nodejs/)

This project generates static HTML. You may view locally just by dragging one of the output files into your browser, loading onto your webserver, or by using a utility such as [http-server (node)](https://github.com/http-party/http-server).
This project generates static HTML. You may view locally just by dragging one of the output files into your browser, or load them onto your website, or zip up the output and share with a friend.

#### The "Recipe Book" Index

Expand Down Expand Up @@ -45,7 +45,10 @@ Create your own... ummm, I owe y'all some documentation here, don't I? Soon... A
### Features:

* Recipes are written in plain text using the intuitive-ish [Markdown format](https://daringfireball.net/projects/markdown).
* Publishes a recipe index, including on-page links to more easily locate a recipe.
* Publishes an easy to read recipe index
* use alphabetical index at page top;
* filter (search) with partial matches (for example, filtering "ap pi" might filters out all but "Deep Dish Apple Pie")
* pick how you want to view your recipes: compact (names only), names with thumbnails, or if you're more visual, choose "recipe cards" featuring large images.
* Template driven layout, customize or use the provided template
* Customize with themes -- color and minor layout settings. Plus, each recipe may choose its own theme.
* No more overlooked ingredients or skipped Steps as recipe pages allow you to flag your current step and mark-off those you've already done. In the Ingredients and Steps sections:
Expand All @@ -72,7 +75,9 @@ EXAMPLE: below a recipe with a few ingredients "ticked" off (indicating they've

## Installation

After cloning this repo:
This requires Node16 or later.

After cloning this repo or downloading the zip file from github simply install, add your recipes, and build:

```sh
npm install
Expand Down Expand Up @@ -202,7 +207,19 @@ The `recipe.html` template file also includes some more options you can customiz
* `autoUrlSections`: list of sections in the recepe template where you want raw URLs (ex: www.instagram.com) to be turned into real links. Great for the `Based On` section but not so good if you want to include Markdown-formatted links in other sections
* `shortenUrls`: turns a super-long url into just the main domain name (link will still work as normal, just less cluttered). Off by default but exists if you want it

## Advanced customizations

### Command Line Arguments

If you'd prefer _not_ editing `config.js` (perhaps you maintain a couple recipe collections, or, like me: just want to keep personal recipes separate from this repo) you may specify the image, recipe, and output directories via command line.

(examples show paths for a Mac)

```sh
npm run build imageDir="~/documents/recipes/images" recipeDir="~/documents/recipes/recipes" outputDir="~/websites/recipes/html"
```

(I keep my personal recipes outside this which makes keeping this app's code up-to-date easy, just a `git pull` away)

## Colophon & Thank Yous

Expand Down
30 changes: 29 additions & 1 deletion build.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,31 @@ function makeThumbnails(outputPath, images) {
});
}

/**
* Intended for, well, me: makes it easier to have my own private directory of images outside
* of this git repo. For example, on a Mac you might use:
*
* ```sh
* npm run build imageDir="~/documents/recipes/images" recipeDir="~/documents/recipes/recipes" outputDir="~/websites/recipes/html"
* ```
*/
function getCommanLineOverrides(args) {
const cmdArgs = args
?.filter((z, index) => index > 1)
.reduce((acc, arg) => {
const [key, value] = arg.split('=');
if (key && value) {
acc[key] = value;
}
return acc;
}, {});

if (cmdArgs && Object.keys(cmdArgs).length) {
console.log(`Using command line overrides: ${JSON.stringify(cmdArgs, null, 3)}`);
}
return cmdArgs;
}

function main(configs) {
const startTime = new Date();
const imagesPath = resolve(__dirname, configs.imageDir);
Expand Down Expand Up @@ -90,4 +115,7 @@ function main(configs) {
});
}

main(configs);
main({
...configs,
...getCommanLineOverrides(process.argv),
});
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "recipes-nodejs",
"version": "1.0.2",
"version": "1.0.3",
"description": "NodeJS recipe publisher, converts markdown/text recipe files into well formatted HTML.",
"main": "build.js",
"scripts": {
Expand Down
40 changes: 40 additions & 0 deletions src/static/scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,43 @@
init,
});
})();

(() => {
const Styles = {
HIDDEN: 'recipe-list__item--hidden',
};

const Selectors = {
RECIPE_ITEMS: '.recipe-list li',
SEARCH: '#filter'
};

const scrub = value => value
.trim()
.toLowerCase()
.replace(/\W/g, '')
.replace(/\s+/g, ' ');

function filter(filterText) {
const words = filterText.split(/\s+/).map(w => scrub(w)).filter(Boolean);

document.querySelectorAll(Selectors.RECIPE_ITEMS)
.forEach((item) => {
if (!filterText) {
item.classList.remove(Styles.HIDDEN);
}
const { searchText } = item.dataset || '';
const isMatch = words.reduce((isMatch, word) => isMatch && searchText.includes(word), true);
item.classList.toggle(Styles.HIDDEN, !isMatch);
});
}

function init() {
document.querySelectorAll(Selectors.RECIPE_ITEMS).forEach(item => item.dataset.searchText = scrub(item.innerText));
document.querySelector(Selectors.SEARCH).addEventListener('keyup', function () {
filter(this.value);
});
}

init();
})();
29 changes: 26 additions & 3 deletions src/static/styles/recipesIndex.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@

/* View radio buttons */
.view--content {}

.view--compact-list {}

.view--grid {}

.nav-view {}
Expand Down Expand Up @@ -76,6 +78,26 @@ html body .nav-view__item {
fill: var(--color-view-svg-selected);
}

/* Filter/Search */
.filter__wrap {
float: right;
}

.filter__terms {
border-radius: 4px;
padding: .4em;
border: solid gray 1px;
font-size: inherit;
}

.recipe-list__photo {
display: none;
}

body .recipe-list .recipe-list__item--hidden {
display: none;
}

/* THE Recipe List */
.recipe-list {
margin-top: 1em;
Expand Down Expand Up @@ -132,21 +154,21 @@ html body .nav-view__item {
}

/* view: Grid */
.view--grid .recipe-list__item {
.view--grid .recipe-list__item {
display: inline-block;
width: 260px;
margin: 0;
margin: 0 15px 15px 0;
}

.view--grid .recipe-list__item a {
.view--grid .recipe-list__item a {
height: 260px;
border: solid 1px transparent;
border-radius: 6px;
overflow: hidden;
}

.view--grid .recipe-list__item a:hover {
.view--grid .recipe-list__item a:hover {
border-color: black;
}

Expand Down Expand Up @@ -192,6 +214,7 @@ html body .nav-view__item {

/* larger screen: ingredients and steps as two columns */
@media screen and (min-width: 820px) {

.view--content .recipe-list,
.view--compact-list .recipe-list {
column-count: 2;
Expand Down
6 changes: 6 additions & 0 deletions src/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ <h1 class="mainTitle">Recipe Book</h1>
<nav class="navigation">
{{__letters-index__}}
</nav>
<div class="filter__wrap">
<label>
<span class="sr-only">Filter</span>
<input id="filter" class="filter__terms" autocomplete="off">
</label>
</div>
<div class="nav-view">
<ul role="radiogroup" class="nav-view__list">
<li class="nav-view__item">
Expand Down

0 comments on commit 724e8de

Please sign in to comment.