Recetario de cocina

Se requiere de un sitio web que genere recetas de cocina de manera dinámica convirtiéndolas a pdf para que se puedan ver en el sitio se puedan descagar o incluso imprimir.

Solución

Primero que nada lo vamos a realizar con html y javascript pero nos vamos apoyar con php para el manejo del índice en la página principal cada vez que se genere la receta.
Creamos el archivo recetacocina.php y escribimos lo siguiente:
 
  
   <!DOCTYPE html>
<html lang="es">

<head>
    <meta charset="UTF-8">
    <meta name="description" content="">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- The above 4 meta tags *must* come first in the head; any other head content must come *after* these tags -->

    <!-- Title -->
    <title>Comida deliciosa/Recetario</title>

    <!-- Favicon -->
    <link rel="icon" href="img/core-img/favicon.ico">

    <!-- Core Stylesheet -->
    <link rel="stylesheet" href="style2.css">

</head>

<body>
    <!-- Preloader -->
    <div id="preloader">
        <i class="circle-preloader"></i>
        <img src="img/core-img/salad.png" alt="">
    </div>

    <!-- Search Wrapper -->
    <div class="search-wrapper">
        <!-- Close Btn -->
        <div class="close-btn"><i class="fa fa-times" aria-hidden="true"></i></div>

        <div class="container">
            <div class="row">
                <div class="col-12">
                    <form action="#" method="post">
                        <input type="search" name="search" placeholder="Type any keywords...">
                        <button type="submit"><i class="fa fa-search" aria-hidden="true"></i></button>
                    </form>
                </div>
            </div>
        </div>
    </div>

    <!-- ##### Header Area Start ##### -->
    <header class="header-area">

        <!-- Top Header Area -->
        <div class="top-header-area">
            <div class="container h-100">
                <div class="row h-100 align-items-center justify-content-between">
                    <!-- Breaking News -->
                    <div class="col-12 col-sm-6">
                        <div class="breaking-news">
                            <div id="breakingNewsTicker" class="ticker">
                                <ul>
                                    <li><a href="#">Hola a todos</a></li>
                                    <li><a href="#">Genera tu receta</a></li>
                                   
                                </ul>
                            </div>
                        </div>
                    </div>

                    <!-- Top Social Info -->
                    
                </div>
            </div>
        </div>

        <!-- Navbar Area -->
        <div class="delicious-main-menu">
            <div class="classy-nav-container breakpoint-off">
                <div class="container">
                    <!-- Menu -->
                    <nav class="classy-navbar justify-content-between" id="deliciousNav">

                        <!-- Logo -->
                        <a class="nav-brand" href="index.html"><img src="img/core-img/logo.png" alt=""></a>

                        <!-- Navbar Toggler -->
                        <div class="classy-navbar-toggler">
                            <span class="navbarToggler"><span></span><span></span><span></span></span>
                        </div>

                        <!-- Menu -->
                        <div class="classy-menu">

                            <!-- close btn -->
                            <div class="classycloseIcon">
                                <div class="cross-wrap"><span class="top"></span><span class="bottom"></span></div>
                            </div>

                            <!-- Nav Start -->
                            <div class="classynav">
                                <ul>
                                    <li class="active"><a href="recetacocina.php">Home</a></li>
                                    <li><a href="#">Páginas</a>
                                        <ul class="dropdown">
                                            <li><a href="recetacocina.php">Home</a></li>
                                            <li><a href="generarreceta.html" target="_blank">Generar Receta</a></li>
                                            
                                        </ul>
                                    </li>
                                    
                                </ul>

                              

                            </div>
                            <!-- Nav End -->
                        </div>
                    </nav>
                </div>
            </div>
        </div>
    </header>
    <!-- ##### Header Area End ##### -->

    <!-- ##### Breadcumb Area Start ##### -->
    <div class="breadcumb-area bg-img bg-overlay" style="background-image: url(img/bg-img/breadcumb3.jpg);">
        <div class="container h-100">
            <div class="row h-100 align-items-center">
                <div class="col-12">
                    <div class="breadcumb-text text-center">
                        <h2>Recetas</h2>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- ##### Breadcumb Area End ##### -->

    <div style="align-content: center;">

      <h1> Lista de recetas  </h1>
      
<?php
     

$arc = fopen('receta.txt',"r");
while(! feof($arc))  {
    $linea = fgets($arc);
    $separada = explode("|", $linea);
    
    if (isset($separada[1])) {
        echo "<a href='recetas/".$separada[1]."' target='_blank'>".$separada[0]."</a><br>";
    }
    
   
}
fclose($arc);



?>
       

      
            

              

                
    </div>

    
    <!-- ##### Follow Us Instagram Area End ##### -->

    <!-- ##### Footer Area Start ##### -->
   
    <!-- ##### Footer Area Start ##### -->

    <!-- ##### All Javascript Files ##### -->
    <!-- jQuery-2.2.4 js -->
    <script src="js/jquery/jquery-2.2.4.min.js"></script>
    <!-- Popper js -->
    <script src="js/bootstrap/popper.min.js"></script>
    <!-- Bootstrap js -->
    <script src="js/bootstrap/bootstrap.min.js"></script>
    <!-- All Plugins js -->
    <script src="js/plugins/plugins.js"></script>
    <!-- Active js -->
    <script src="js/active.js"></script>
</body>

</html>
   
   
   
   
   
   
    
   
Donde generes el archivo php vas descriprimir el archivo directorios.zip y se van al nivel de archivo php mencionado anterior mente.
Ahora vamos con los estilos generamos el archivo style2.css Ahora generamos el archivo generarreceta.html
 
    
   <!DOCTYPE html>
<html lang="es">

<head>
    <meta charset="UTF-8">
    <meta name="description" content="">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- The above 4 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    
    <!-- Title -->
    <title>Comida deliciosa/Recetario</title>

    <!-- Favicon -->
    <link rel="icon" href="img/core-img/favicon.ico">

    <!-- Core Stylesheet -->
    <link rel="stylesheet" href="style2.css">
    <link href="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.snow.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.js"></script>
<link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css"
/>
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" />
</head>

<body>
    <!-- Preloader -->
    <div id="preloader">
        <i class="circle-preloader"></i>
        <img src="img/core-img/salad.png" alt="">
    </div>

    <!-- Search Wrapper -->
    <div class="search-wrapper">
        <!-- Close Btn -->
        <div class="close-btn"><i class="fa fa-times" aria-hidden="true"></i></div>

        <div class="container">
            <div class="row">
                <div class="col-12">
                    <form action="#" method="post">
                        <input type="search" name="search" placeholder="Type any keywords...">
                        <button type="submit"><i class="fa fa-search" aria-hidden="true"></i></button>
                    </form>
                </div>
            </div>
        </div>
    </div>

    <!-- ##### Header Area Start ##### -->
    <header class="header-area">

        <!-- Top Header Area -->
        <div class="top-header-area">
            <div class="container h-100">
                <div class="row h-100 align-items-center justify-content-between">
                    <!-- Breaking News -->
                    <div class="col-12 col-sm-6">
                        <div class="breaking-news">
                            <div id="breakingNewsTicker" class="ticker">
                                <ul>
                                    <li><a href="#">Hola a todos</a></li>
                                    <li><a href="#">Genera tu receta</a></li>
                                   
                                </ul>
                            </div>
                        </div>
                    </div>

                    <!-- Top Social Info -->
                    
                </div>
            </div>
        </div>

        <!-- Navbar Area -->
        <div class="delicious-main-menu">
            <div class="classy-nav-container breakpoint-off">
                <div class="container">
                    <!-- Menu -->
                    <nav class="classy-navbar justify-content-between" id="deliciousNav">

                        <!-- Logo -->
                        <a class="nav-brand" href="index.html"><img src="img/core-img/logo.png" alt=""></a>

                        <!-- Navbar Toggler -->
                        <div class="classy-navbar-toggler">
                            <span class="navbarToggler"><span></span><span></span><span></span></span>
                        </div>

                        <!-- Menu -->
                        <div class="classy-menu">

                            <!-- close btn -->
                            <div class="classycloseIcon">
                                <div class="cross-wrap"><span class="top"></span><span class="bottom"></span></div>
                            </div>

                            <!-- Nav Start -->
                            <div class="classynav">
                                <ul>
                                    <li class="active"><a href="generarreceta.html">Generar receta</a></li>
                                    <li><a href="#">Páginas</a>
                                        <ul class="dropdown">
                                            <li><a href="recetacocina.php">Home</a></li>
                                            <li><a href="generarreceta.html">Generar Receta</a></li>
                                            
                                        </ul>
                                    </li>
                                    
                                </ul>

                               

                            </div>
                            <!-- Nav End -->
                        </div>
                    </nav>
                </div>
            </div>
        </div>
    </header>
    <!-- ##### Header Area End ##### -->

    <!-- ##### Breadcumb Area Start ##### -->
    <div class="breadcumb-area bg-img bg-overlay" style="background-image: url(img/bg-img/breadcumb3.jpg);">
        <div class="container h-100">
            <div class="row h-100 align-items-center">
                <div class="col-12">
                    <div class="breadcumb-text text-center">
                        <h2>Generar receta</h2>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- ##### Breadcumb Area End ##### -->

 <div class="editor-layout">   
<div id="editor">
</div>  
<br><br>
Nombre Receta:<input type="text" id="filename-input" size="100" />

<br>
<input type="button" id="new-btn" value="Nueva receta" />
<input type="button" id="pdf-btn" value="Exportar a pdf" />
 
</div>  
    <!-- ##### All Javascript Files ##### -->
    <!-- jQuery-2.2.4 js -->
    <script src="js/jquery/jquery-2.2.4.min.js"></script>
    <!-- Popper js -->
    <script src="js/bootstrap/popper.min.js"></script>
    <!-- Bootstrap js -->
    <script src="js/bootstrap/bootstrap.min.js"></script>
    <!-- All Plugins js -->
    <script src="js/plugins/plugins.js"></script>
    <!-- Active js -->
    <script src="js/active.js"></script>
     <script src="htmltopdf.js"></script>
     <script src="script.js"></script>
    <script>
		
const toolbarOptions = [
  ['bold', 'italic', 'underline', 'strike'],        // toggled buttons
  ['blockquote', 'code-block'],
  ['link', 'image', 'video', 'formula'],

  [{ 'header': 1 }, { 'header': 2 }],               // custom button values
  [{ 'list': 'ordered'}, { 'list': 'bullet' }, { 'list': 'check' }],
  [{ 'script': 'sub'}, { 'script': 'super' }],      // superscript/subscript
  [{ 'indent': '-1'}, { 'indent': '+1' }],          // outdent/indent
  [{ 'direction': 'rtl' }],                         // text direction

  [{ 'size': ['small', false, 'large', 'huge'] }],  // custom dropdown
  [{ 'header': [1, 2, 3, 4, 5, 6, false] }],

  [{ 'color': [] }, { 'background': [] }],          // dropdown with defaults from theme
  [{ 'font': [] }],
  [{ 'align': [] }],

  ['clean']                                         // remove formatting button
];		
		
		
  const quill = new Quill('#editor', {
    modules: {
      
      toolbar: toolbarOptions
    },
    placeholder: 'Publica una resta épica...',
    theme: 'snow',
  });
</script>
</body>

</html>
   
      
   
Descargamos la librería htmltopdf.js para convertir de html a pdf Generamos el archivo script.js
 
    
  const editor = document.getElementById("editor")

const newBtn = document.querySelector("#new-btn")

const pdfBtn = document.querySelector("#pdf-btn")


const filename = document.getElementById("filename-input")





newBtn.addEventListener("click", () => {
   
    filename.value=""
})


pdfBtn.addEventListener('click', async () => {
	
	
	if (filename.value.trim() === '') {
    alert('No tiene nombre la receta');
    filename.focus(); // Enfoca el campo vacío
     // Evita que el formulario se envíe
   }
   
   
   let nombreArchivo = "receta-"+Date.now();
   
   
	
    const pdfComoBlob =  await html2pdf().from(editor).save(nombreArchivo).output('blob')
    const formData = new FormData();
        formData.append("pdf", pdfComoBlob);
        formData.append("nombre", nombreArchivo);
        formData.append("titulo",filename.value);
        
        //formData.append("otraVariable", "otroValor"); // En PHP la recuperamos como $_POST["otraVariable"]
        const respuestaHttp = await fetch("./upload.php", {
            body: formData,
            method: "POST",
        });
        const respuestaDelServidor = await respuestaHttp.text();
       
       
       
       
       
       
        alert("El servidor dice: " + respuestaDelServidor)
    
    
       window.location.href = "recetacocina.php"
    
 })
  
  
  
  
     
   
Creamos el archivo upload.php para agregar el pdf generado en el directorio recetas y escribir en receta.txt
 
   
	<?php

if (
    
    !isset($_POST["nombre"]) ||
    !isset($_POST["titulo"]) ||
    !isset($_FILES["pdf"])
    ) {
        exit("Faltan datos");
    }
    $archivoPdf = $_FILES["pdf"];
    $nombre = $_POST["nombre"];
    $nombreReceta = $_POST["titulo"];
    # Aquí podemos acceder a $_POST["nombre"], apellido, direccion
    $directorio = "recetas";
    if (!file_exists($directorio)) {
        mkdir($directorio);
    }
    $nombre = $nombre . ".pdf";
    $ubicacion = $directorio . DIRECTORY_SEPARATOR . $nombre;
    move_uploaded_file($archivoPdf["tmp_name"], $ubicacion);
    $file = 'receta.txt';
    
    // Open file in append mode
    $handle = fopen($file, 'a');
    
    // Data to append
    $data = $nombreReceta."|".$nombre."\n";
    
    // Write data to file
    fwrite($handle, $data);
    
    // Close the file
    fclose($handle);
    
    
    
    echo "OK";
 
 
  
	  
	  
	  
  
   
Por último creamos el archivo receta.txt que llevara el registro de las recetas generadas.

Probando