Introduction to the Web Interface

Welcome to the first lesson of our course on building an image generation web application with PHP! In this course, you'll learn how to create a user-friendly web interface for an AI-powered image generation service using PHP as the backend. By the end of this course, you'll have built a complete web application that allows users to generate images based on text prompts and view their generation history.

In this first lesson, we'll focus on creating the HTML structure for our application. This structure will serve as the foundation for our user interface, providing the elements with which users will interact to generate images and view their history.

Our application will have two main sections:

  1. A "Generate Image" tab where users can enter prompts and customize their image generation.
  2. A "View History" tab where users can see their previously generated images.

Before we dive into the code, let's understand how PHP serves HTML templates. In a PHP application, HTML files are often written as .php files, allowing you to embed PHP code directly within your HTML.

Our backend will use the official Gemini API with the gemini-3.1-flash-image model to generate images from user-provided text prompts. The PHP Laravel backend will handle all communication with the Gemini API, and the results will be returned to the frontend for display.

Now, let's start building our HTML interface!

App File Structure

Before we start building the HTML for our image generation interface, let's take a moment to understand how our PHP application is organized. A clear file structure helps us stay organized as our project grows in complexity.

Here's a typical structure we'll be working with:

image-generator-app/
├── app
│   ├── Http
│   │   ├── Controllers
│   │   │   └── ImageGeneratorController.php  # Controller for handling image generation requests
│   ├── Models
│   │   ├── ImageManager.php   # Model for managing image data
│   │   ├── PromptManager.php  # Model for managing prompts
│   └── Services
│       └── ImageGeneratorService.php  # Service for generating images
├── public/                         # Publicly accessible files (entry point, assets)
│   ├── index.blade.php                   # Main entry point for the web app
|   ├── css/                        # CSS Styles
|   └── js/                         # JavaScript files
├── resources/
│   ├── data/
│   │   └── image_prompt_template.txt  #  LLM prompt template
│   └── views                          #  HTML Blade templates

With this structure in mind, you'll find it easier to understand where each part of the code lives as we build out the HTML and connect it to our PHP backend.

Creating the Basic HTML Document Structure

Every HTML document starts with a basic structure that includes the document type declaration, the HTML root element, and the head and body sections. In a PHP Laravel app, you can create this structure in a .blade.php file, which allows you to add HTML code.

Here's how you can set up the basic HTML structure for your image generator application in a PHP file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Event Banner Generator</title>
    <link rel="stylesheet" href="/css/style.css">
</head>
<body>
    <!-- Our content will go here -->
</body>
</html>

Let's break down what each part of this code does:

  • <!DOCTYPE html> tells the browser that this is an HTML5 document.
  • <html lang="en"> is the root element of the HTML document, with en specifying English as the language.
  • The <head> section contains metadata about the document:
    • <meta charset="UTF-8"> specifies the character encoding for the document.
    • <meta name="viewport" content="width=device-width, initial-scale=1.0"> ensures proper scaling on mobile devices.
    • <title>AI Event Banner Generator</title> sets the title that appears in the browser tab.
    • <link rel="stylesheet" href="/css/style.css"> links to our CSS file, which is located in the resources/css/ directory.

Now that we have our basic structure, let's add the content to our body section.

Building the Tab Navigation System

Our application will have two main tabs: one for generating images and another for viewing the history of generated images. Let's create the tab navigation system that will allow users to switch between these views.

<body>
    <div class="tabs">
        <button class="tab-button" onclick="openTab('generate')">Generate Image</button>
        <button class="tab-button" onclick="openTab('history')">View History</button>
    </div>

    <div id="generate" class="tab-content">
        <!-- Generate Image content will go here -->
    </div>

    <div id="history" class="tab-content" style="display:none;">
        <!-- View History content will go here -->
    </div>
</body>

In this code, we've added:

  • A <div> with the class tabs that contains two buttons, one for each tab.
  • Each button has an onclick attribute that calls a JavaScript function named openTab with the ID of the tab to open.
  • Two <div> elements with the class tab-content and IDs generate and history. These will contain the content for each tab.
  • The "history" tab content has style="display:none;" to hide it initially, showing only the "generate" tab when the page loads.

The openTab function will be defined in our JavaScript file, which we'll link at the end of our HTML document. This function will handle showing and hiding the appropriate tab content when a user clicks a tab button.

Now, let's fill in the content for each tab.

Designing the Image Generation Form

The "Generate Image" tab will contain a form where users can enter a prompt for the image they want to generate and select an aspect ratio. Let's create this form:

<div id="generate" class="tab-content">
    <div class="container">
        <h1>Event Banner Generator</h1>
        <input type="text" id="prompt" placeholder="Describe your event (e.g., Luxury Tech Conference 2025)">
        <label for="aspect-ratio">Aspect Ratio:</label>
        <select id="aspect-ratio">
            <option value="1:1">Square (1:1)</option>
            <option value="16:9">Widescreen (16:9)</option>
            <option value="4:3">Classic (4:3)</option>
            <option value="3:4">Portrait (3:4)</option>
        </select>
        <button id="generate-button" onclick="generateImage()">Generate Image</button>
        <p id="loading-message" style="display: none;">Generating image... Please wait.</p>
        <div id="image-container"></div>
    </div>
</div>

Let's examine the elements in our form:

  • A container <div> to hold all the form elements.
  • An <h1> heading that displays the title of our application.
  • An <input> field where users can enter their image description (prompt).
  • A dropdown <select> menu for choosing the aspect ratio of the generated image, with options for 1:1, 16:9, 4:3, and 3:4 formats.
  • A button that, when clicked, will call a JavaScript function named generateImage() to process the form and generate the image.
  • A loading message that will be displayed while the image is being generated. It's initially hidden with style="display: none;".
  • An empty <div> with the ID image-container where the generated image will be displayed.

The generateImage() function will be defined in our JavaScript file. It will collect the values from the form and send them to our PHP Laravel backend, which will call the Gemini API using the gemini-3.1-flash-image model to generate the image and return the result. The JavaScript function will then display the returned image in the image-container div.

Setting Up the History View

The "View History" tab will allow users to see their previously generated images. Let's create the history view for this tab:

<div id="history" class="tab-content" style="display:none;">
    <div class="container">
        <h1>Image History</h1>
        <button onclick="fetchHistory()">Load Previous Images</button>
        <div id="history-container"></div>
    </div>
</div>

The history view is simpler than the generation form:

  • A container <div> to hold all the elements.
  • An <h1> heading that displays "Image History".
  • A button that, when clicked, will call a JavaScript function named fetchHistory() to load the user's previously generated images.
  • An empty <div> with the ID history-container where the images will be displayed.

The fetchHistory() function will be defined in our JavaScript file. It will fetch the user's image history from our backend API and display the images in the history-container div.

Connecting Everything Together

Now that we have created all the necessary HTML elements, let's connect everything together by adding the <script> tag at the end of our body section:

<script src="/js/script.js"></script>

Here, we use a standard HTML path to link our JavaScript file, which is located in the resources/js/ directory.

Here's the complete HTML code for our image generator application:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI Event Banner Generator</title>
    <link rel="stylesheet" href="/css/style.css">
</head>
<body>
    <div class="tabs">
        <button class="tab-button" onclick="openTab('generate')">Generate Image</button>
        <button class="tab-button" onclick="openTab('history')">View History</button>
    </div>

    <div id="generate" class="tab-content">
        <div class="container">
            <h1>Event Banner Generator</h1>
            <input type="text" id="prompt" placeholder="Describe your event (e.g., Luxury Tech Conference 2025)">
            <label for="aspect-ratio">Aspect Ratio:</label>
            <select id="aspect-ratio">
                <option value="1:1">Square (1:1)</option>
                <option value="16:9">Widescreen (16:9)</option>
                <option value="4:3">Classic (4:3)</option>
                <option value="3:4">Portrait (3:4)</option>
            </select>
            <button id="generate-button" onclick="generateImage()">Generate Image</button>
            <p id="loading-message" style="display: none;">Generating image... Please wait.</p>
            <div id="image-container"></div>
        </div>
    </div>

    <div id="history" class="tab-content" style="display:none;">
        <div class="container">
            <h1>Image History</h1>
            <button onclick="fetchHistory()">Load Previous Images</button>
            <div id="history-container"></div>
        </div>
    </div>

    <script src="/js/script.js"></script>
</body>
</html>
Summary

In this lesson, we've created the HTML structure for our image generator application using PHP. We've set up a tab navigation system, designed a form for generating images, and created a view for displaying the image history. We've also linked our CSS and JavaScript files using standard HTML paths suitable for a PHP project.

Right now, our application doesn't look very appealing because we haven't added any styling yet. Additionally, the buttons don't do anything because we haven't implemented the JavaScript functions. In the next lesson, we'll add CSS to style our application and make it visually appealing.

After that, we'll implement the JavaScript functions to handle user interactions and communicate with our PHP Laravel backend, which uses the Gemini API with gemini-3.1-flash-image to generate images from user prompts.

The HTML structure we've created serves as the foundation for our application. It defines the elements with which users will interact and provides the structure that our CSS and JavaScript will build upon. By understanding this structure, you'll be better prepared to implement the styling and functionality in the upcoming lessons.

In the practice exercises that follow, you'll have the opportunity to modify this HTML structure and experiment with different elements to better understand how they work together. You'll also get to see how the HTML structure interacts with CSS and JavaScript to create a complete web application.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal