This article is published under a SIGNATURE 4.0 International (CC BY 4.0) license. Signature 4.0 International (CC BY 4.0)
Author: Su Yang
Creation time: January 19, 2020 statistical word count: 6643 words reading time: 14 minutes to read this article links: soulteary.com/2020/01/19/…
Fix Ghost Chinese input method BUG
Last year, I wrote an article called “The Story behind Moving Ghost to Hugo” that described the main problems Ghost currently has with non-English users.
One of the most notorious is the editor for CJK three language input method “eat word” BUG, this problem affects Ghost from 2.x to the current 3.x version. The reason for the problem is that the core editor component 0.11.1-0.12.x version of the input method events did not carry out logical coverage, maintainers and Ghost officials still have not made any changes up to now, no matter how many users raised “IME BUG” for help and PR.
A recent project needs a document editor, so consider “tinkering” it to see if it works.
About this BUG that has been going on for two years
- In 2018, someone submitted a PRGithub.com/bustle/mobi…, the use of
event.isIME()
The method fixed the problem, but was challenged by a non-standard implementation, and the problem was subsequently suspended for two years. - In late 2019, a new PR was submittedGithub.com/TryGhost/mo…, the use of
event.isComposing()
The method was used to correct the problem, but whether it was simply because the CI test failed or because of customer discrimination, the PR was also shelved.
Lead to
This article relies on some software or prior knowledge. If you don’t know much about it, you can refer to previous articles.
- Docker, docker-compose is required
- Optional traefik
The use of Traefik
For details on Traefik, you can refer to previous articles, such as: Use service discovery to improve development experience, a more perfect Docker + Traefik usage scheme, etc., for more content, you can look at the historical content of the label, here is not more details.
It is enough for this article to focus on the Labels and Networks field configuration in the choreographer file. For networks fields of different container services, the declaration contains the same content, so that different applications live on the same network.
networks:
- traefik
Copy the code
The above declaration, for example, puts container services in a network environment called Traefik.
Early fixes
At the beginning of last year, when I could not bear the BUG, I put forward a solution in an IME BUG ISSUE in the official main warehouse. Tell everyone to replace @tryghost/mobiledoc-kit in package.json for Ghost at the time with @bugfix/mobiledoc-kit and rebuild the resource to fix the problem. This comment still gets a few likes today.
Github.com/TryGhost/Gh…
By the second half of last year, however, the solution had fallen by the way due to an official design change, which made it difficult to follow up with the official BugFix version, which was too cumbersome and inflexible.
Current fixes
The problem to be solved is mainly the scripts running on the client side. The solution to both the symptoms and the root causes is to patch the problematic scripts and rebuild the project so that the page can load new script resources.
However, the design of the official compiled project is not environmentally friendly and green. The splitting design of the project is not very reasonable. There are a lot of build scripts tricks and hard coding, and the use of Grunt and Git submoudle is very bad for debug. You also need to install a bunch of build tools globally, lock Node to run on an older version, and compile infamously slowly…
In order to avoid the subsequent waste of more time in the problem of the project architecture, here we consider the container compilation environment of the customized software, by the higher performance of the server to compile, and extract the compilation products for each version of Ghost resource replacement, to solve the age-old BUG.
I uploaded the project to GitHub: github.com/soulteary/y… , so that you can make further customization, and if necessary, can keep up with the official updates of several versions.
Let’s talk about the details of the scheme.
Custom Build images generate “patches”
Official editor patch file, I uploaded to GitHub, can be self – help. Dockerfile: Dockerfile: Dockerfile: Dockerfile
FROM node:12-alpine
LABEL maintainer="[email protected]"
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
ENV LC_ALL=en_US.UTF-8
RUN echo ' ' > /etc/apk/repositories && \
echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/main" >> /etc/apk/repositories && \
echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/community" >> /etc/apk/repositories && \
echo "Asia/Shanghai" > /etc/timezone
RUN apk update && apk add git && \
yarn global add knex-migrator grunt-cli ember-cli bower
COPY patches/mobiledoc-kit/event-manager.js /patches/mobiledoc-kit/event-manager.js
RUN git clone https://github.com/TryGhost/mobiledoc-kit.git /mobiledoc-kit && \
cd /mobiledoc-kit && \
git checkout 3b0f375d32f7183a4eee9cce5373ebabeb249165 && \
cp /patches/mobiledoc-kit/event-manager.js /mobiledoc-kit/src/js/editor/event-manager.js && \
yarn && \
cp -r /mobiledoc-kit/dist /patches/mobiledoc-kit/dist && \
rm -rf /mobiledoc-kit
RUN git clone --recurse-submodules https://github.com/TryGhost/Ghost.git /Ghost && \
cd/Ghost && git checkout 3.3.0 && yarn setup RUN rm -rf /Ghost/core/client/node_modules/\@tryghost/mobiledoc-kit/dist && \ cp -r /patches/mobiledoc-kit/dist /Ghost/core/client/node_modules/\@tryghost/mobiledoc-kit/ WORKDIR /Ghost RUN grunt prod EXPOSE 2368 CMD ["npm"."start"]
Copy the code
Execute docker build-t soulteary/ Ghost :3.3.0, if it is a local build, make a cup of tea and take a rest, about 10 minutes or so the image will be ready. Of course, you can also execute Docker Pull Soulteary/Ghost :3.3.0 to get the built image directly.
Next, create a docker-comemage.assets.yml to extract static resources from the build image.
version: '3'Services: build-ghost-Assets: Image: Soulteary/Ghost :3.3.0 Container_name: ghost- Assets volumes: - ./patches/ghost-assets/loop.js:/Ghost/index.jsCopy the code
Since the mirror of the copied resource must survive the copy, and Ghost startup must configure the database, otherwise an error exit, so here to create an HTTP Server to solve the problem.
const http = require("http");
const server = http.createServer(function(req, res) {
res.writeHead(200);
res.end("Hold on for sync assets");
});
server.listen(2368);
Copy the code
Save the following command as sync-assets.sh, and after execution, the Ghost editor static resource patch for version 3.3.0 will appear in the project directory.
#! /usr/bin/env bash
docker-compose -f docker-compose.assets.yml down && docker-compose -f docker-compose.assets.yml up -d
rm -rf docker-assets && mkdir -p docker-assets
docker cp ghost-assets:/Ghost/core/built ./docker-assets/built
docker cp ghost-assets:/Ghost/core/server/web/admin/views ./docker-assets/admin-views
docker-compose -f docker-compose.assets.yml down
Copy the code
Verify the scheme effect
To verify the patch effect, you can start a set of Ghost locally by creating a docker-comemess.db. yml to start the local database.
version: '2'Services: db: image: mysql:5.7 container_name: ghost-db networks: -traefik restart: always environment: MYSQL_ROOT_PASSWORD: ghost volumes: - ./localdb:/var/lib/mysql networks: traefik: external:true
Copy the code
Wait for ready for Connections to appear in the log. Indicates the database is ready:
Ghost - db | 2020-01-18 T17:24:04. 154079 z 0 [Note] Event Scheduler: The Loaded 0 events ghost - db | 2020-01-18 T17:24:04. 154348 z 0 [Note] mysqld: readyfor connections.
ghost-db | Version: '5.7.28' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
Copy the code
Next create docker-comemage.yml and type the following:
version: "3.6"Services: www-ghost-local: image: Ghost :3.3.0 Expose: -2368 Environment: URL: https://soulteary.io database__client: mysql database__connection__host: ghost-db database__connection__user: root database__connection__password: ghost database__connection__database: ghost NODE_ENV: production volumes: -. / docker - assets/built: / var/lib/ghost/versions / 3.3.0 / core/built: ro - ./docker-assets/admin-views:/var/lib/ghost/current/core/server/web/admin/views:ro - ./config.production.json:/var/lib/ghost/config.production.json:ro - . / content/adapters: / var/lib/ghost/versions / 3.3.0 / content/adapters - . / content/apps: / var/lib/ghost/versions / 3.3.0 / content/apps - . / content/images: / var/lib/ghost/versions / 3.3.0 / content/images - / content/logs: / var/lib/ghost/content/logs - . / content/Settings: / var/lib/ghost/versions / 3.3.0 / content/Settings extra_hosts: -"Soulteary. IO: 127.0.0.1."
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.port=2368"
- "traefik.frontend.rule=Host:soulteary.io"
- "traefik.frontend.entryPoints=https,http"
networks:
traefik:
external: true
Copy the code
Docker-compose up: docker-compose up:
www-ghost-local_1 | [2020-01-18 17:25:10] INFO Ghost is running inproduction... www-ghost-local_1 | [2020-01-18 17:25:10] INFO Your site is now available on https://soulteary.io/ www-ghost-local_1 | 17:25:10 [2020-01-18] the INFO Ctrl + C to shut down the WWW - ghost - local_1 | 17:25:10 [2020-01-18] the INFO ghost boot 9.472 sCopy the code
Visit http://soulteary.io/ghost for project initialization, set up after the administrator account, can conveniently create an article for testing.
The last
Being open source is not easy, but if the goal is more than just marketing PR and driving some traffic. If you want to benefit more people and make the community ecology better, you should be open and inclusive, and modestly accept criticisms and suggestions from the community. Let’s not mention that everyone has written your code for you, just click the Merge button.
–EOF
I now have a small toss group, which gathered some like to toss small partners.
In the case of no advertisement, we will talk about software, HomeLab and some programming problems together, and also share some technical salon information in the group from time to time.
Like to toss small partners welcome to scan code to add friends. (Please specify source and purpose, otherwise it will not be approved)
All this stuff about getting into groups