Simplicity SPA Elm

Tram Ho

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.

Data Service

Our build target is a single page SPA application and so obviously the main operating logic of the website will be included in the JavaScript code on the front end of the website. This code will be operated by the web browser on the user’s computer to control the entire navigation logic handled after each user interaction event operation.

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?
  • series-id – Which Series in the above thread?
  • post-slug – the description of Post ‘s identifier name in the directory of the above Series ?

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 .json files.

Thus, the type of link that can be used for the navigation logic of the SPA will have the simplest form:

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:

For example:

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 Topic .

Launch files

The entire 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.

For example:

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.

Code architecture

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 convention that is the homepage is considered the overview page of a default Topic named Origin .

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 : Element.Navigator , Element.Overview , Element.Reader , Element.Indexer .

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 Element .

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 refactor 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 Element .

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 .

Yes, Elm is great, very simple to approach when you have a basic JavaScript background and 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 .

Share the news now

Source : Viblo