So we start another
mini project in the journey of self-learning to code so that we can build essential software and also learn our own thinking patterns and practice our ability to organize ourselves. logical arrangement.
Regarding the delay in posting new articles for a long time when the Sub-Series has not ended, I am really sorry if you are the one who is following my series of articles at this Viblo blog network. The reason is because I want to spend time finishing this
mini project first and define a few limitations in terms of code implementation before sharing in the articles here.
The story is that if you have accompanied the self-study journey starting from the first Web Programming Self-Taught Series, this is already the third
mini project ; And I’m sure we are all familiar with using Google Search and Translate to find answers to related problems when reading reference code examples.
Therefore, from this Sub-Series onwards, I will not post detailed code in each article, but instead, the entire completed
source code will be attached in the opening article of each
mini project . After that, the articles will aim to share the overall design perspective and some notable actions or patterns in the process of writing implementation code. That way you’ll be able to easily skim and refer to the points you might find necessary to take notes and not have to spend time Google Searching and adapting your own code architecture.
And here’s a link to a personal blog at GitHub written in Elm, a simple SPA single page application that uses GitHub Pages as a
back-end that handles pure query requests.
- GitHub Page: https://thinhtranhnvn.github.io/
- Source code: Simplicity SPA Elm
Our build target is a single page SPA application and so obviously the main operating logic of the website will be included in the
For example, when a user chooses to open any link in a web page, this code needs to temporarily block the default behavior of the web browser to prevent reloading of the entire web page. Immediately after that, the SPA needs to perform a path analysis of the new link that the user has just selected to make a navigation decision to display the appropriate single page layout. If it is a request to view an article, the SPA will need to identify the data locator elements of that article in the library hosted on GitHub, including:
topic-id– what topic is the post on?
Seriesin the above thread?
post-slug– the description of
Post‘s identifier name in the directory of the above
And that’s how I created a simple database for my personal blog at GitHub. The directory tree diagram below is the structure of the
/data directory containing the data of the blog that I am using with the content of the articles saved in
markdown code in
.txt files, and the
metadata data is stored in the code. put in
├── origin [topic]
│ ├── overview.txt
│ ├── series-list.json
│ ├── hrdaya-sutra [series]
│ | ├── post-list.json
│ | ├── 00-the-first-preface.txt
│ | ├── 01-the-second-preface.txt
│ | ├── ...
│ | └── 12-no-five-skandhas-no-object-until-we-come-to-no-realm.txt
│ └── yoga-sutra [series]
│ ├── post-list.json
│ └── ...
├── linux [topic]
│ ├── overview.txt
│ ├── series-list.json
│ ├── gnome [series]
│ | ├── post-list.json
│ | └── ...
│ └── libreoffice [series]
│ ├── post-list.json
│ └── ...
Thus, the type of link that can be used for the navigation logic of the SPA will have the simplest form:
https://username.github.io/ topic-id / series-id / post-slug
And so, after extracting the above article data file locator elements, the SPA will be able to send a request to GitHub to query the original
raw file content with a link of the following form:
https://raw.githubusercontent.com/username/username.github.io/main/data/ topic-id / series-id / post-slug.txt
Here, when the user chooses to stop at the
Topic overview menu page, the SPA will display the content of an
overview.txt article of that
Topic and so the layout will be the same as the article page. If the user chooses to stop at a single page overview of a
Series , the SPA will display a slightly different layout with the main body replaced by a heading link block that includes a list of links pointing to the post within that
source code is located in the
/src directory on the same first level as the
/data directory and starts with the
src/App.elm file. When we run the
elm make src/App.elm compilation command, we will get a
/index.html file located outside the
/src directory and will be immediately recognized by
GitHub Page to display when the user opens the link to it. blog home page for the first time.
In addition, this file is also duplicated right in the same directory as the
/404.html file and so when the user opens a shared link somewhere and points to any article page,
GitHub Page will return a fallback file containing code with the same operating logic.
When the user opens the above shared link from some source, the browser will receive the
/404.html file instead of the
/index.html file, and now we still have the same processing logic code with the original file. to analyze the current path and send data queries to adjust the interface accordingly. In the event that the right data is found to display, the content will obviously not be a single page layout with an error message, but will still be a single page containing the content.
I started coding naturally from the stage of creating the
/mockup directory to compose static
HTML single pages that simulate the design before starting to code the logic. Here, we have the following components: the main navigation bar
Navigator , the side navigation bar
Overview , the display of the
Reader article content,
Indexer heading link block. All are grouped into a folder
/mockup/Element , actually people often use the word
Component , but probably not too important.
These components are then used for single page layouts: the
HomePage.html home page, the
TopicPage.html topic dashboard,
SeriesPage.html series dashboard, and the
PostPage.html article page. All of these are grouped into a folder
/mockup/Layout . Because only
SeriesPage.html layout is different from the rest in the main content display, I only composed two files in that folder.
In this paragraph, there is a little note that I use a small implicit
conventionthat is the homepage is considered the overview page of a default
So when it comes to the stage of writing and deploying logic code, I have figured out that I need an overview
module for the entire
SPA , which is
module App .
App will then use the components provided by the
module Element :
At this point, this is where I wonder the most to choose the packaging design level and share in the article here. Specifically, the most expected design is that the
Element are designed to be independent of the
context of the design and can be used for other websites if desired.
To implement the design at this level, the code requirement is that each
Element will be an isolated program and need to define its own internal data type, not knowing the elements related to navigation logic. application. Then the code used outside of any
project , for example, we have
module App here will have to
import the data type that that
Element uses internally. Then, when querying the data of a
Post , it will have to convert the
Post record into the type of data record that the other
Element requires to work.
However, I chose to stop at the level of
module design incompletely packed with
Element that understand the application’s global navigation logic, and even auto-generate requests to
GitHub Page for queries. data required for display. Thus,
module App is only responsible for adjusting the overall layout of the single page to be displayed based on the routing elements and does not need to deal with the detailed operation logic of the
The reason for this choice is because this architecture is simpler to deploy if there is no need to reuse
Element for other
project . In addition, from the perspective of anyone else who is new to coding and
Elm , it will be easy to follow the logic of the code’s operation through the articles that I share here. If you still haven’t finished coding any
mini project with
Elm and are very confident in your ability, you can refactor and
source code that you have posted according to the above architecture. It is definitely a very serious practice and the results will certainly be well worth it.
By the way, the half-baked architecture that I use is somewhat not optimal in terms of performance because the
module Element themselves send query requests for data to display, not using shared data. So there will be cases when a user requests to view a single page where the
metadata.json files are queried multiple times from different
With a brief overview of this
mini project , I hope that you will be able to test the
Declarative + Elm learning process with a set of
source code that you personally feel satisfied with. And at the present time, after using
Elm to build a simple blog, I have added data to make the decision that there will not be an
project elm-fullstack .
Elm is great, very simple to approach when you have a basic
Imperative thinking is not too heavy. However, I feel it is necessary to have another Sub-Series dedicated to the serious
Functional Programming story with the
Haskell language. This will be a sure intention after we have prioritized handling the previously located Sub-Series
Object-Oriented + Java .