mealie-recipes / mealie

Mealie is a self hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in Vue for a pleasant user experience for the whole family. Easily add recipes into your database by providing the url and mealie will automatically import the relevant data or add a family recipe with the UI editor
https://docs.mealie.io
GNU Affero General Public License v3.0
7.52k stars 753 forks source link

[v1.0.0b] [Task] - Export Recipes and Cookbooks to PDF #1306

Open hay-kot opened 2 years ago

hay-kot commented 2 years ago

What is the problem this task addresses?

Some users want to export Recipes into a standard format and/or capture recipes into a printable format.

Mealie should provide a way to

Proposed/Possible Solution(s)?

I have not looked into PDF libraries in Python

doctorjames commented 2 years ago

A suggestion for consideration: might targetting a well-supported, semantically rich format consumable by Pandoc be worthwhile? I can see PDF would be good for printing, but EPUB would be more useful for offline electronic reference.

In addition to those two, Pandoc would also enable conversion to more editable formats, for example if someone wanted to make more of a traditional recipe book by adding additional content around/between recipes.

I haven't tried it myself, but here's the kind of thing I was imagining: https://www.toptal.com/docker/pandoc-docker-publication-chain

stroodle96 commented 2 years ago

I really like the idea of being able to export as an epub or pdf.

Fufs commented 1 year ago

For PDF, won't Print to PDF function be enough? Printing directly from the recipe is already implemented and Print to PDF function is preinstalled for the vast majority of Windows and Android devices.

I don't know if it's available in Apple OSes and Linux Distros tho.

AnthonyHeide commented 1 year ago

Print to PDF might be fine for single recipes, but the idea here is to generate an entire cookbook with the recipes you selected. It could also be that exporting to PDF might format it better than just printing it out.

michael-genson commented 1 year ago

Print to PDF might be fine for single recipes, but the idea here is to generate an entire cookbook with the recipes you selected

Yup I think this is still a good feature to have, separate from individual recipes. We could also generate a nice cover page

It could also be that exporting to PDF might format it better than just printing it out.

I don't think there's much value in this unless vs making the standard print look nice. The main advantage of using the PDF format directly is for extra features (such as links, bookmarks, etc.) but I don't see it being worth the hassle. The only advantage I could see is being able to count pages for a ToC or something

Skiepp commented 1 year ago

IMHO this feature would be great for third party integration šŸ˜Š But access recipes to export as PDF / EPUB has to be done via API

As example I'm building a suite around PocketBook and Kindle. It would be great to manage recipes via web and have them synched into the ebook reader

In those sceanarios, "Print to PDF function" is not enought, unless performed with tools like cypress and selenium (which is not a good approach, nor a correct microservices integration)

Fufs commented 1 year ago

Hmmmmmm, true. In that case the download/export functionality should be able to support multiple formats with respective API functionality. I think other formats worth to implement, other than pdf or epub would be html, md, latex, and maybe doc(x) and odt?

I can start the work on the backend but someone else will have to play with the PDF as I'm a terrible graphic designer šŸ˜„

michael-genson commented 1 year ago

For the first iteration I'd recommend just serving the existing print view in each format. Later down the line we can enrich it

acorncom commented 1 year ago

I can start the work on the backend but someone else will have to play with the PDF as I'm a terrible graphic designer šŸ˜„

@Fufs I'm happy to help with the design. I'm not an amazing graphic designer, but I can make it look decent until someone else comes along to make it better šŸ˜„

wiltified commented 8 months ago

Hey guys! Any traction on this? I, the techy, love having mealie on my iPad for cooking. Where as my wife is a "old fashioned" book / print out person and would really benefit from this. Thanks!

diedrichg commented 6 months ago

I also need this feature. I would suggest there also be a toggle to include/exclude recipe images in the PDF as well as a toggle to place the image on the left or right of the title or below the recipe title. As mentioned above; printing a whole cookbook or selecting individual recipes to be included in the PDF would be ideal. EDIT: One more request - Print a page with the Category name prior to those included recipes.

SimonSomlai commented 4 months ago

I ran into this problem as well and solved it with a puppeteer script;

const puppeteer = require("puppeteer");

(async () => {
  // Launch a new browser session.
  const browser = await puppeteer.launch({ headless: false });
  // Open a new page.
  const page = await browser.newPage();
  // Navigate to the specified URL.
  await page.goto("http://IP_ADDRESS:9000/g/home/");

  // Wait for all divs with className "v-lazy" to be rendered.
  await page.waitForSelector(".v-lazy");
  await page.setViewport({ width: 1920, height: 1080 });

  // Extract hrefs from all links under each div with className "v-lazy".
  const hrefs = await page.evaluate(() => {
    const divs = Array.from(document.querySelectorAll(".v-lazy"));
    const links = divs.flatMap((div) => Array.from(div.querySelectorAll("a")));
    return links.map((link) => link.href);
  });

  // Open and print each page to PDF with default settings.
  for (const href of hrefs) {
    // Open a new page for each href.
    const newPage = await browser.newPage();
    // Navigate to the href.
    await newPage.goto(href);
    await new Promise((resolve) => setTimeout(resolve, 1000));
    // Generate a PDF of the page with default settings and padding.
    const title = await newPage.title();
    const pdfPath = `./${title}.pdf`;
    await newPage.pdf({
      path: pdfPath,
      margin: { top: "60px", right: "60px", bottom: "60px", left: "60px" },
    });
    await new Promise((resolve) => setTimeout(resolve, 1000));
    // Close the new page.
    await newPage.close();
  }

  // Close the browser session.
  await browser.close();
})();
diedrichg commented 4 months ago

solved it with a puppeteer script

How does the average user running Mealie in a Unraid Docker implement this?

TinyJas commented 4 months ago

solved it with a puppeteer script

How does the average user running Mealie in a Unraid Docker implement this?

Any traction here? Iā€™m running Mealie in Portainer. Would love to have this functionality. Alas, my programming skills are lowly SAS & SQL. Haha.

taegge commented 3 months ago

https://github.com/patrickelam/mealie_cookbook_generator

This has been solved! We need to work with @patrickelam to get this integrated upstream :)

patrickelam commented 3 months ago

https://github.com/patrickelam/mealie_cookbook_generator

This has been solved! We need to work with @patrickelam to get this integrated upstream :)

Thanks for the shout-out @taegge. It makes me happy somebody's gotten some use out of it!

Iirc, I've spoken with @hay-kot about this, there was hesitation about bringing jinja2 in as a dependency from a security perspective, and we felt that it was just easier to leave my generator script as a separate tool. If there's a strong desire to get it integrated, I think I'd be interested in discussing how it would fit with the architecture and make a PR. I'd need to re-write my script into something that would actually resemble production-ready code.

One thing to consider would be the level of customization supported via the web ui. Do we set up infrastructure to allow for custom templates / css? Feels like it could get complicated pretty quickly, while never really satisfying the designer (which I am NOT) who would really love to tweak things. The benefit of leaving my script as a separate project is that it allows someone to jump in and modify everything at-will (and with the docker container option, you don't even need to deal with dependencies).

oncleben31 commented 2 months ago

So, if I understand well, this part of the documentation (in FAQ) is false:

Some users of static-site generator applications like ChowDown have expressed concerns about their data being stuck in a database. Considering this is a new project, it is a valid concern to be worried about your data. Mealie specifically addresses this concern by providing automatic daily backups that export your data in json, plain-text markdown files, and/or custom Jinja2 templates. This puts you in control of how your data is represented when exported from Mealie, which means you can easily migrate to any other service provided Mealie doesn't work for you.

I'm in a situation testing a new solution for managing my receipes. Without this feature, I feel stuck. JSON export is not so easy allow reuse in other solutions

BurkenDev commented 3 weeks ago

Yes, add cookbook PDF export. That's a MUST.