Mở terminal (Command Prompt, PowerShell, hoặc Terminal trên Linux/Mac). Dưới đây là hướng dẫn cho Windowns PowerShell.

1. Chuẩn bị môi trường phát triển

  • Đảm bảo bạn đã cài đặt JDK (phiên bản 8 hoặc cao hơn). Bạn có thể kiểm tra bằng lệnh java -version
  • Nếu chưa cài, tải và cài đặt JDK bạn có thể tham khảo bài viết về cách Cài đặt JDK 8 trên Windows tại đây .
  • Maven là công cụ quản lý dependency và build dự án Java. Tải và cài đặt Maven từ trang chính thức tại đây.
  • Kiểm tra cài đặt Maven bằng lệnh mvn -version
  • Xác định đường dẫn cài đặt MySQL
  • Mở File Explorer và tìm thư mục cài đặt MySQL:

Thông thường là: C:\Program Files\MySQL\MySQL Server 8.0\bin (phiên bản có thể khác, như 5.7, 8.0, v.v.).

Trong thư mục bin, bạn sẽ thấy tệp mysql.exe.

  • Ghi lại đường dẫn chính xác (ví dụ: C:\Program Files\MySQL\MySQL Server 8.0\bin).
  • Nhấn Win + S chọn "Edit the system environment variables".
  • Chọn Advaced, chọn Environment Variables.

Tìm biến Path, chọn nó và nhấp Edit....

Nhấp New, dán đường dẫn MySQL (ví dụ: C:\Program Files\MySQL\MySQL Server 8.0\bin), rồi nhấn OK.

  • Đóng và mở lại PowerShell (để áp dụng thay đổi).

Tạo database landing_page_db và bảng pages với các cột id, html, css, timestamp.

  • Chạy lệnh đăng nhập vào MySQL: mysql -u root -p
  • Khi PowerShell hiển thị dòng "Enter password:", gõ 123456 rồi nhấn Enter. (Thay 123456 bằng mật khẩu của bạn)
  • Tạo database: CREATE DATABASE landing_page_db; Điều này tạo một database mới có tên landing_page_db.
  • Tạo bảng pages với các cột:
id: Khóa chính, tự động tăng.html: Lưu nội dung HTML, không được để trống.css: Lưu nội dung CSS, không được để trống.timestamp: Thời gian lưu, mặc định là thời điểm hiện tại.
CREATE TABLE pages (
    id INT AUTO_INCREMENT PRIMARY KEY,
    html TEXT NOT NULL,
    css TEXT NOT NULL,
    timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
- Kiểm tra bảng vừa tạo: DESCRIBE pages; .
  • Thoát MySQL: EXIT; Quay lại giao diện PowerShell.

2. Thiết lập thư mục dự án và cài đặt phụ thuộc

  • Khởi tạo dự án: Tạo dự án với Maven, tạo file pom.xml và thêm các dependency sau
<dependencies>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>javax.persistence-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>com.tvd12</groupId>
            <artifactId>ezydata-jpa</artifactId>
            <version>1.2.9</version>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.tvd12</groupId>
            <artifactId>ezyhttp-server-boot</artifactId>
            <version>1.3.7</version>
        </dependency>
        <dependency>
            <groupId>com.tvd12</groupId>
            <artifactId>ezyhttp-server-core</artifactId>
            <version>1.3.7</version>
        </dependency>
</dependencies>
  • Cấu hình kết nối tới database có thể được đặt trong file application.properties
ezy.jpa.database=landing_page_db
ezy.jpa.data_source.driver_class_name=com.mysql.cj.jdbc.Driver
ezy.jpa.data_source.url=jdbc:mysql://localhost:3306/landing_page_db
ezy.jpa.data_source.username=root
ezy.jpa.data_source.password=123456
ezy.jpa.hibernate.ddl_auto=update
ezy.http.server.port=3000
- Tạo file src/main/java/com/ezygrapes/model/Page.java
package com.ezygrapes.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;

@Data
@Entity
@Table(name = "pages", schema = "landing_page_db")
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
public class Page implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "html", nullable = false, columnDefinition = "TEXT")
    private String html;

    @Column(name = "css", nullable = false, columnDefinition = "TEXT")
    private String css;

    @Column(name = "timestamp", columnDefinition = "DATETIME DEFAULT CURRENT_TIMESTAMP")
    private LocalDateTime timestamp;
}
- Tạo file src/main/java/com/ezygrapes/repository/PageRepository.java
package com.ezygrapes.repository;

import com.ezygrapes.model.Page;
import com.tvd12.ezydata.database.EzyDatabaseRepository;

public interface PageRepository extends EzyDatabaseRepository<Long, Page> {
}
- Tạo file src/main/java/com/ezygrapes/controller/PageController.java
package com.ezygrapes.controller;

import com.ezygrapes.model.Page;
import com.ezygrapes.repository.PageRepository;
import com.tvd12.ezyhttp.core.exception.HttpBadRequestException;
import com.tvd12.ezyhttp.server.core.annotation.Controller;
import com.tvd12.ezyhttp.server.core.annotation.DoPost;
import com.tvd12.ezyhttp.server.core.annotation.RequestBody;

@Controller("/api")
public class PageController {

    private final PageRepository pageRepository;

    public PageController(PageRepository pageRepository) {
        this.pageRepository = pageRepository;
    }

    @DoPost("/save")
    public String savePage(@RequestBody Page page) {
        try {
            if (page.getHtml() == null || page.getCss() == null) {
                throw new HttpBadRequestException("HTML và CSS không được để trống");
            }
            pageRepository.save(page);
            return "Đã lưu thành công";
        } catch (Exception e) {
            throw new HttpBadRequestException("Lỗi khi lưu: " + e.getMessage());
        }
    }
}
- Tạo file src/main/java/com/ezygrapes/Application.java
package com.ezygrapes;

import com.tvd12.ezyhttp.server.boot.EzyHttpApplicationBootstrap;
import com.tvd12.ezyhttp.server.core.asm.RequestHandlerImplementer;

public class Application {
    public static void main(String[] args) throws Exception {
        RequestHandlerImplementer.setDebug(true);
        EzyHttpApplicationBootstrap.start(Application.class);
    }
}
- Sửa lại scripts trong package.json
"scripts": {
  "lint": "eslint src",
  "v:patch": "npm version --no-git-tag-version patch",
  "build": "npm run v:patch && webpack --config webpack.prod.js && npm run build:css",
  "start": "concurrently "java -jar ./target/preset-webpage-1.0-SNAPSHOT-jar-with-dependencies.jar" "webpack serve --no-open --config webpack.dev.js" "npm run build:css -- -w"",
  "build:css": "node-sass src/scss/main.scss dist/ezygrapes-preset-webpage.min.css --output-style compressed"
}

3. Cập nhật index.html

<script>
document.addEventListener("DOMContentLoaded", function(event) { 
    var editor = ezygrapes.init({
        height: '100%',
        showOffsets: 1,
        noticeOnUnload: 0,
        cssIcons: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css',
        storageManager: { autoload: 0 },
        container: '#gjs',
        fromElement: true,
        plugins: ['gjs-preset-webpage'],
        pluginsOpts: {
            'gjs-preset-webpage': {}
        },
        i18n: {
            locale: 'vi',
            localeFallback: 'vi',
            detectLocale: false
        },
        canvas: {
            styles: [
                'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css',
                'https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css'
            ],
            scripts: [
                'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js',
                'https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/js/bootstrap.bundle.min.js'
            ]
        }
    });

    async function autoSave() {
    try {
        const html = editor.getHtml();
        const css = editor.getCss();
        const response = await fetch('http://localhost:3000/api/save', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ html, css }),
        });
        const result = await response.json();
        console.log('Đã lưu:', result);
    } catch (error) {
        console.error('Lỗi khi lưu:', error);
    }
}

    setInterval(autoSave, 60000); // 60 giây
});
</script>

4. Chạy dự án

  • Dùng lệnh cd ezygrapes/plugins/preset-webpage.
  • Chạy lệnh mvn clean package Maven sẽ tạo file JAR tại target/preset-webpage-1.0-SNAPSHOT-jar-with-dependencies.jar.
  • Chạy toàn bộ bằng: yarn start .
  • Kiểm tra:
  • Mở http://localhost:8081.
  • Console (F12 > Console) để xem dữ liệu tải/lưu.
  • MySQL
mysql -u root -pUSE landing_page_db;SELECT * FROM pages;

5. Tóm lại

Trên đây là cách để bạn có thể tự động lưu nội dung của HTML và CSS sau khi chỉnh sửa dự án EzyGrapes cùng với plugin preset-webpage. Hy vọng với những chia sẻ trên đây giúp bạn nắm được đặc điểm và ứng dụng.