SSG就是页面静态化技术

静态站点生成 (Static-Site Generation,缩写为 SSG),也被称为预渲染,是另一种流行的构建快速网站的技术。如果用服务端渲染一个页面所需的数据对每个用户来说都是相同的,那么我们可以只渲染一次,提前在构建过程中完成,而不是每次请求进来都重新渲染页面。预渲染的页面生成后作为静态 HTML 文件被服务器托管。

SSG就是页面静态化技术,是门户网站、WordPress博客常用的Web优化手段之一。

SSR类似于PHP程序,每有一个HTTP请求到来就会被运行一次,渲染输出HTML字符串给前端。如果网站的内容没有实时性,我们可以把渲染输出的HTML字符串缓存一段时间,当有HTTP请求到来时,直接返回缓存给前端,而不是实时渲染输出。这就是页面静态化技术的核心思想。

参考

服务端渲染 (SSR)

Does Stopping a Docker Container Equate to Shutting Down a VirtualBox VM?

To clarify, stopping a running Docker container is not the same as pausing it. Stopping a container terminates the processes inside the container and releases associated resources (like CPU and memory), but the container’s filesystem and state remain intact, similar to how VirtualBox retains hard disk data after shutting down a VM. The container’s data stays unless explicitly deleted (using rm).

The Difference Between Stop and Pause:

  • Stop: Completely terminates all processes inside the container, similar to turning off the power. When the container is restarted, it begins from its configured entry process.
  • Pause: Freezes all processes inside the container, keeping their state intact, but without releasing resources. A paused container can be resumed, much like the Suspend feature in VirtualBox.

停止(注意不是暂停)运行docker容器是不是相当于VirtualBox的虚拟机关机?

具体来说,停止运行中的 Docker 容器会终止容器内部的进程,释放相关的资源(如 CPU 和内存),但容器的文件系统和状态会被保留,就像 VirtualBox 虚拟机关机后硬盘数据依然保存一样,除非进行删除(rm)操作。

停止和暂停的区别在于:

  • 停止(stop):完全终止容器内的进程,相当于电源关闭,容器在下次启动后会重新开始其配置的入口进程。
  • 暂停(pause):冻结容器内的所有进程,进程状态保持,但并不释放资源,暂停的容器可以恢复继续运行,类似于 VirtualBox 的暂停(Suspend)功能。

Methods for Website Internationalization (Providing Multi-language Content)

For websites that use server-side templating engines (e.g., Laravel’s Blade) to render HTML documents, the approach to localization (internationalization) is as follows: For common pages like login and registration, you can use the __() function to translate text based on the lang= query parameter passed from the frontend. For other pages, the language-specific views should be placed in directories like resources/views/{language_code} (for Laravel) or public/{language_code} (where “public” refers to the web root directory).

For fully decoupled applications, such as those where the frontend is developed using MVVM frameworks like Vue.js or React.js for SPAs, and the backend is built with Laravel to provide APIs, localization methods differ. In this case, you should add language-specific subdomains at the domain level, such as cn.vuejs.org for the Chinese Vue.js site, ja.vuejs.org for the Japanese site, with the default vuejs.org serving the English version. Additionally, the database should support language-specific partitioning, where each language code has its own set of tables or databases.

网站国际化(提供多国语言内容)的方法

对于前端使用服务器端模板引擎(例如Laravel的blade)渲染输出HTML文档的开发方式,本地化(国际化)的方法是,通用的页面,例如登陆注册,可以使用__()函数根据前端传过来的lang=语言代码查询参数翻译文本。其他不同用的页面应该放在resources/views/语言代码目录(对于Laravel)或public/语言代码目录(public代表web根目录)下。还有一种方法是在HTML文档中使用lang=’xxx’属性标记HTML元素的内容所使用的语言,再使用:lang伪类选择器根据前端传过来的lang=语言代码,选择显示特定语言的HTML元素(由服务器端模板引擎实现),其他语言的元素都不显示(由服务器端模板引擎设置display:none;)。例如:

<style>
/*显示中文内容*/
:lang(zh_CN){
    …
}
:lang(fr){
display:none;/*不显示法文内容*/
    …
}
</style>

<div lang='zh_CN'>中文内容……</div>
<div lang='fr'>法文内容……</div>

这种方法适用于内容比较简单的国际化网页。

对于前后端完全分离的应用程序,例如前端使用Vue.js、React.js等MVVM框架开发SPA,服务器端使用Laravel开发并提供API给前端调用,本地化(国际化)的方法是,在域名层面添加语言代码子域,例如cn.vuejs.org、ja.vuejs.org分别显示中文Vue.js官网和日文Vue.js官网,主站vuejs.org默认英文Vue.js官网。 数据库也应该根据语言代码分库分表。

Laravel’s DB Facade Doesn’t Trigger Eloquent ORM Model Events

When using the DB facade to perform database operations in Laravel, Eloquent ORM model events like saving, saved, etc., are not triggered.

If you want to avoid triggering model events in event listeners or queued tasks, aside from using Eloquent’s saveQuietly, deleteQuietly, and similar methods, you can directly use the DB facade to execute database operations.

This approach allows you to bypass Eloquent’s event handling when necessary.

Laravel使用DB façade执行数据库操作不会触发Eloquent ORM模型事件

使用DB façade执行数据库操作不会触发saving、saved等Eloquent ORM模型事件。当我们不想在事件监听器或队列任务中触发Eloquent ORM模型事件时,除了使用Eloquent ORM模型的saveQuietly、deleteQuietly等方法之外,还可以直接使用DB façade执行数据库操作。

在Eloquent ORM模型事件监听器和队列任务中,要避免使用Eloquent模型增删改查方法,例如create、update、save等。否则会陷入调用死循环 —— 模型事件监听器分发队列任务,队列任务触发模型事件,模型事件监听器再次分发队列任务,队列任务再次触发模型事件……死循环了。

Modify and Persist Model Instances in Laravel Using the saved Event, Not the saving Event

In Laravel, don’t call the save method on a model instance inside the saving event listener.

If you need to modify a model’s field and persist it within a model event listener, make sure you’re using the saved event, not the saving event. This is particularly important when your event listeners are queued for asynchronous execution.

The saving event occurs before the model is persisted to the database. If you try to modify a field and call save() within this listener, it won’t actually persist to the database, especially when the listener is queued for async execution. For example, modifying the slug field might not actually update in the database.

Instead, use the saved event listener and call saveQuietly to persist the changes, as shown in the example:

static::saved(queueable(function (Topic $topic) {
    // If the slug is empty, translate the title into a slug
    if (!$topic->slug) {
        $topic->slug = app(SlugTranslateHandler::class)->translate($topic->title);
        $topic->saveQuietly();
    }
}));

By using the saved event and saveQuietly, you ensure that your changes are made after the model is successfully persisted, avoiding any issues with asynchronous queue execution.

Laravel框架应该在saved而不是saving事件监听器中修改模型实例并持久化

不要在saving事件的监听器中运行模型实例的save方法。

要在模型事件的闭包监听器中修改模型实例的某个字段的值并持久化,当模型事件的闭包监听器作为队列任务异步执行时,不能监听saving事件,因为该事件表示模型实例还未持久化到数据库里,因此监听器作为队列任务异步执行的话,就会导致模型实例的某个字段(例如下例的slug字段)的值不能真正持久化到数据库里(记住,不应该在saving事件的监听器里调用模型实例的save方法)。应该在saved事件监听器里saveQuietly模型实例,例如:

static::saved(queueable(function (Topic $topic) {
    // 如果slug字段无内容,就使用翻译器对title字段进行翻译
    if (!$topic->slug) {
        $topic->slug = app(SlugTranslateHandler::class)->translate($topic->title);
        $topic->saveQuietly();
    }
}));

Learn a Marketable Skill

In your twenties, life can be tough. You might find yourself struggling in the workforce, dealing with PUA (Psychological Manipulation) from bosses, managers, or small business owners. You’re not making money, and you might blame your upbringing—coming from a poor family, lacking in material wealth, mental resources, and even knowledge. It’s not your fault, right?

But in your thirties or forties, if you’re still finding it hard to make ends meet, then the blame falls squarely on you. You’re not putting in enough effort, not being ruthless enough, and most importantly, you haven’t learned a skill that guarantees your survival. You’ve wasted too many years without picking up something practical.

By “skill,” I mean something that can be monetized—blue-collar jobs like welding, auto repair, hairdressing, cooking, forklift driving, or truck driving. Or white-collar jobs like programming, writing, sales, accounting, finance trading, or legal consulting. If you’re not a government official’s child or a rich heir, you’ll have to master at least one of these.

If you want both financial security and freedom—what people often call “making money while standing”—you need to acquire a marketable skill.

As a grassroots worker, if you depend on a specific boss, team, or organization to make a living, over time, you’ll develop an unhealthy dependency. You become their servant, at their mercy, afraid to even quit.

But if you’re living off a marketable skill, no one or organization can enslave you. Your skill is market-driven—if you’re unhappy with one company, you can quit and take a break. When you’re ready, you can join another company, or even start your own business.

Remember, happiness comes from freedom, and freedom comes from courage and perseverance.