API:Holidays viewer

Overview
This tutorial covers how to create a demo app that fetches holidays and observances for a given date from Wikipedia, with an option to log in to add new holidays.

Download the code from GitHub Browse the app on Toolforge

The tools and technologies used to create the demo app are:


 * Python 3 and Flask, a Python framework.
 * JQuery and Bootstrap.
 * 1>Special:MyLanguage/API:Main page|MediaWiki Action API modules: ,  and .

Step 1: Set up Python and Flask development environment
Python comes pre-installed on most Linux distributions. For other operating systems, see the [https://wiki.python.org/moin/BeginnersGuide/Download</> Python beginner's guide] for installation instructions.

Install Flask by running <tvar|1> </>. If you don't have pip, get it from [<tvar|url>https://pip.pypa.io/en/stable/installing/</> the official Pip website].

Step 2: Create a simple Flask application
In your home directory, create a folder named <tvar|1> </> which will contain all the app's files. Inside the folder, create a file named <tvar|1> </> and place the following code in it:

Run the app using the command <tvar|1> </> and open <tvar|2> </> on your browser. You should see "<tvar|1>Holidays and observances</>" displayed.

Step 3: Create the base layout
The app will have four pages: the homepage, a search page, a login page and an add page. Each page will have some common elements, so we need to create a base layout file called <tvar|1> </> to contain these elements.

Note that we are using <tvar|1>Bootstrap</> classes to apply a specific CSS style to an element, [<tvar|url>https://materializecss.com/icons.html</> Materialize icons] for the add, search and arrow-back icons, and <tvar|2>Jinja</> to extend the base layout to other pages and to pass variables from Python to HTML.

Other pages will extend <tvar|1> </> using the code below:

Step 4: List holidays
The root url of the app will trigger the <tvar|1> </> function, which lists holidays for a certain date.

In the function and throughout the app, <tvar|1> </> refers to the date of the holidays to be listed, <tvar|2> </> refers to the title of the page, and <tvar|3> </> refers to the html which contains the holidays to be listed. We'll also be using the <tvar|1> </> function which renders a specific html file from the templates directory. Other arguments added to the function are variables which are being passed to the html file.

In <tvar|1> </>, update  with the code below:

Get today's date
If no date is specified, we'll list holidays for today's date. To use Python's <tvar|1>datetime</> module to get today's date, import the module with <tvar|2> </> then create the following function:

Call the function in <tvar|1> </>:

Get the holidays to be listed
Once we have the date, we get the holidays for that date. Wikipedia has a page for each date and the holidays are under a section titled "<tvar|1>Holidays and observances</>". To get the holidays, we need to get it's section number and the content in that section number.

Create a function to get the section number using <tvar|1></>:

Create a function called <tvar|1> </> to get the holidays in that section using <tvar|2></> as well, then call the functions in <tvar|3> </>:

Update holiday links
The HTML of the holidays returned contains 1>Special:MyLanguage/Help:Links#Internal links internal links</>|internal links that point to those holidays, e.g "<tvar|2> </>". We need to prepend "<tvar|1> </>" to these links using jQuery in order to make them external links in our app, and make them open in a new tab. To do that, add the following code to <tvar|1> </>:

Then add jQuery to <tvar|1> </> using:

Step 5: Search for holidays of other dates
To get holidays of other dates, create a search route to display a form that collects the month and day to search for:

Once the search form has been submitted, update <tvar|1> </> to be the date that has been entered. To do that, add the following code to <tvar|1> </>:

Step 6: Add a holiday
The page to which we'll be adding a new holiday is protected from edits by anonymous users, so we need to log in using 1>Special:MyLanguage/API:Login#clientlogin</>|API:Login#clientlogin first.

To add a holiday, send a request to <tvar|1></> with the date and description of the holiday. The edit adds new holidays to this page on Test Wikipedia: <tvar|1>Sandbox/Holidays_and_observances</>. This is to prevent adding test holidays to English Wikipedia.

After the holiday is added, redirect to the homepage where the holidays added will also be shown, and formatted in bold to differentiate them from the real holidays. To fetch the test holidays alongside the real holidays, update <tvar|1> </>:

Step 7: Styling the app
To add more style to our app, create a stylesheet named <tvar|1> </> and link to it from <tvar|2> </> by adding <tvar|3> </>.

Application layout
At this point, the structure of your app should be:

$HOME/holidays-viewer ├── templates/ │  └── add.html └── index.html └── layout.html └── login.html └── search.html ├── static/ │  └── style.css └── update-links.js ├── app.py

With <tvar|1> </> and <tvar|2> </> being:



Next steps

 * Contribute a demo app that you have developed using the MediaWiki API to this [<tvar|url>https://github.com/wikimedia/MediaWiki-Action-API-Code-Samples</> code samples repository].