CINXE.COM

API:Holidays viewer - MediaWiki

<!DOCTYPE html> <html class="client-nojs vector-feature-language-in-header-disabled vector-feature-language-in-main-page-header-disabled vector-feature-sticky-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-feature-night-mode-disabled skin-theme-clientpref-day vector-toc-available" lang="en" dir="ltr"> <head> <meta charset="UTF-8"> <title>API:Holidays viewer - MediaWiki</title> <script>(function(){var className="client-js vector-feature-language-in-header-disabled vector-feature-language-in-main-page-header-disabled vector-feature-sticky-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-feature-night-mode-disabled skin-theme-clientpref-day vector-toc-available";var cookie=document.cookie.match(/(?:^|; )mediawikiwikimwclientpreferences=([^;]+)/);if(cookie){cookie[1].split('%2C').forEach(function(pref){className=className.replace(new RegExp('(^| )'+pref.replace(/-clientpref-\w+$|[^\w-]+/g,'')+'-clientpref-\\w+( |$)'),'$1'+pref+'$2');});}document.documentElement.className=className;}());RLCONF={"wgBreakFrames":false,"wgSeparatorTransformTable":["",""],"wgDigitTransformTable":["",""], "wgDefaultDateFormat":"dmy","wgMonthNames":["","January","February","March","April","May","June","July","August","September","October","November","December"],"wgRequestId":"2120d88d-5582-4fb3-ba7f-f856ff6ee138","wgCanonicalNamespace":"API","wgCanonicalSpecialPageName":false,"wgNamespaceNumber":104,"wgPageName":"API:Holidays_viewer","wgTitle":"Holidays viewer","wgCurRevisionId":6749968,"wgRevisionId":6749968,"wgArticleId":969509,"wgIsArticle":true,"wgIsRedirect":false,"wgAction":"view","wgUserName":null,"wgUserGroups":["*"],"wgCategories":["MediaWiki action API"],"wgPageViewLanguage":"en","wgPageContentLanguage":"en","wgPageContentModel":"wikitext","wgRelevantPageName":"API:Holidays_viewer","wgRelevantArticleId":969509,"wgIsProbablyEditable":false,"wgRelevantPageIsProbablyEditable":false,"wgRestrictionEdit":["autoconfirmed"],"wgRestrictionMove":["autoconfirmed"],"wgNoticeProject":"mediawiki","wgCiteReferencePreviewsActive":true,"wgMediaViewerOnClick":true,"wgMediaViewerEnabledByDefault" :true,"wgVisualEditor":{"pageLanguageCode":"en","pageLanguageDir":"ltr","pageVariantFallbacks":"en"},"wgMFDisplayWikibaseDescriptions":{"search":true,"watchlist":true,"tagline":false,"nearby":true},"wgWMESchemaEditAttemptStepOversample":false,"wgWMEPageLength":30000,"wgTranslatePageTranslation":"source","wgCentralAuthMobileDomain":false,"wgEditSubmitButtonLabelPublish":true,"wgULSPosition":"personal","wgULSisCompactLinksEnabled":true,"wgVector2022LanguageInHeader":false,"wgULSisLanguageSelectorEmpty":false,"wgCheckUserClientHintsHeadersJsApi":["brands","architecture","bitness","fullVersionList","mobile","model","platform","platformVersion"]};RLSTATE={"ext.globalCssJs.user.styles":"ready","site.styles":"ready","user.styles":"ready","ext.globalCssJs.user":"ready","user":"ready","user.options":"loading","ext.translate.tag.languages":"ready","ext.pygments":"ready","skins.vector.search.codex.styles":"ready","skins.vector.styles":"ready","skins.vector.icons":"ready", "jquery.makeCollapsible.styles":"ready","mediawiki.ui.button":"ready","ext.translate.edit.documentation.styles":"ready","ext.translate":"ready","ext.wikimediamessages.styles":"ready","ext.visualEditor.desktopArticleTarget.noscript":"ready","ext.uls.pt":"ready","wikibase.client.init":"ready","ext.wikimediaBadges":"ready"};RLPAGEMODULES=["ext.pygments.view","mediawiki.page.media","site","mediawiki.page.ready","jquery.makeCollapsible","mediawiki.toc","skins.vector.js","ext.centralNotice.geoIP","ext.centralNotice.startUp","ext.translate.pagetranslation.uls","ext.urlShortener.toolbar","ext.centralauth.centralautologin","mmv.bootstrap","ext.visualEditor.desktopArticleTarget.init","ext.visualEditor.targetLoader","ext.echo.centralauth","ext.eventLogging","ext.wikimediaEvents","ext.navigationTiming","ext.uls.compactlinks","ext.uls.interface","ext.checkUser.clientHints"];</script> <script>(RLQ=window.RLQ||[]).push(function(){mw.loader.impl(function(){return["user.options@12s5i",function($,jQuery,require,module){mw.user.tokens.set({"patrolToken":"+\\","watchToken":"+\\","csrfToken":"+\\"}); }];});});</script> <link rel="stylesheet" href="/w/load.php?lang=en&amp;modules=ext.pygments%2Ctranslate%2CwikimediaBadges%7Cext.translate.edit.documentation.styles%7Cext.translate.tag.languages%7Cext.uls.pt%7Cext.visualEditor.desktopArticleTarget.noscript%7Cext.wikimediamessages.styles%7Cjquery.makeCollapsible.styles%7Cmediawiki.ui.button%7Cskins.vector.icons%2Cstyles%7Cskins.vector.search.codex.styles%7Cwikibase.client.init&amp;only=styles&amp;skin=vector-2022"> <script async="" src="/w/load.php?lang=en&amp;modules=startup&amp;only=scripts&amp;raw=1&amp;skin=vector-2022"></script> <meta name="ResourceLoaderDynamicStyles" content=""> <link rel="stylesheet" href="/w/load.php?lang=en&amp;modules=site.styles&amp;only=styles&amp;skin=vector-2022"> <meta name="generator" content="MediaWiki 1.44.0-wmf.5"> <meta name="referrer" content="origin"> <meta name="referrer" content="origin-when-cross-origin"> <meta name="robots" content="max-image-preview:standard"> <meta name="format-detection" content="telephone=no"> <meta name="viewport" content="width=1120"> <meta property="og:site_name" content="MediaWiki"> <meta property="og:title" content="API:Holidays viewer - MediaWiki"> <meta property="og:type" content="website"> <link rel="preconnect" href="//upload.wikimedia.org"> <link rel="alternate" media="only screen and (max-width: 640px)" href="//m.mediawiki.org/wiki/API:Holidays_viewer"> <link rel="apple-touch-icon" href="/static/apple-touch/mediawiki.png"> <link rel="icon" href="/static/favicon/mediawiki.ico"> <link rel="search" type="application/opensearchdescription+xml" href="/w/rest.php/v1/search" title="MediaWiki (en)"> <link rel="EditURI" type="application/rsd+xml" href="//www.mediawiki.org/w/api.php?action=rsd"> <link rel="canonical" href="https://www.mediawiki.org/wiki/API:Holidays_viewer"> <link rel="license" href="https://creativecommons.org/licenses/by-sa/4.0/"> <link rel="alternate" type="application/atom+xml" title="MediaWiki Atom feed" href="/w/index.php?title=Special:RecentChanges&amp;feed=atom"> <link rel="dns-prefetch" href="//meta.wikimedia.org" /> <link rel="dns-prefetch" href="//login.wikimedia.org"> </head> <body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-104 ns-subject page-API_Holidays_viewer rootpage-API_Holidays_viewer skin-vector-2022 action-view"><a class="mw-jump-link" href="#bodyContent">Jump to content</a> <div class="vector-header-container"> <header class="vector-header mw-header"> <div class="vector-header-start"> <nav class="vector-main-menu-landmark" aria-label="Site"> <div id="vector-main-menu-dropdown" class="vector-dropdown vector-main-menu-dropdown vector-button-flush-left vector-button-flush-right" > <input type="checkbox" id="vector-main-menu-dropdown-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-main-menu-dropdown" class="vector-dropdown-checkbox " aria-label="Main menu" > <label id="vector-main-menu-dropdown-label" for="vector-main-menu-dropdown-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--icon-only " aria-hidden="true" ><span class="vector-icon mw-ui-icon-menu mw-ui-icon-wikimedia-menu"></span> <span class="vector-dropdown-label-text">Main menu</span> </label> <div class="vector-dropdown-content"> <div id="vector-main-menu-unpinned-container" class="vector-unpinned-container"> <div id="vector-main-menu" class="vector-main-menu vector-pinnable-element"> <div class="vector-pinnable-header vector-main-menu-pinnable-header vector-pinnable-header-unpinned" data-feature-name="main-menu-pinned" data-pinnable-element-id="vector-main-menu" data-pinned-container-id="vector-main-menu-pinned-container" data-unpinned-container-id="vector-main-menu-unpinned-container" > <div class="vector-pinnable-header-label">Main menu</div> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-pin-button" data-event-name="pinnable-header.vector-main-menu.pin">move to sidebar</button> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button" data-event-name="pinnable-header.vector-main-menu.unpin">hide</button> </div> <div id="p-navigation" class="vector-menu mw-portlet mw-portlet-navigation" > <div class="vector-menu-heading"> Navigation </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="n-mainpage-description" class="mw-list-item"><a href="/wiki/MediaWiki" title="Visit the main page [z]" accesskey="z"><span>Main page</span></a></li><li id="n-mw-download" class="mw-list-item"><a href="/wiki/Download"><span>Get MediaWiki</span></a></li><li id="n-mw-extensions" class="mw-list-item"><a href="/wiki/Special:MyLanguage/Category:Extensions"><span>Get extensions</span></a></li><li id="n-blog-text" class="mw-list-item"><a href="https://techblog.wikimedia.org/"><span>Tech blog</span></a></li><li id="n-mw-contribute" class="mw-list-item"><a href="/wiki/Special:MyLanguage/How_to_contribute"><span>Contribute</span></a></li> </ul> </div> </div> <div id="p-support" class="vector-menu mw-portlet mw-portlet-support" > <div class="vector-menu-heading"> Support </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="n-help" class="mw-list-item"><a href="/wiki/Special:MyLanguage/Help:Contents" title="The place to find out"><span>User help</span></a></li><li id="n-mw-faq" class="mw-list-item"><a href="/wiki/Special:MyLanguage/Manual:FAQ"><span>FAQ</span></a></li><li id="n-mw-manual" class="mw-list-item"><a href="/wiki/Special:MyLanguage/Manual:Contents"><span>Technical manual</span></a></li><li id="n-mw-supportdesk" class="mw-list-item"><a href="/wiki/Project:Support_desk"><span>Support desk</span></a></li><li id="n-mw-communication" class="mw-list-item"><a href="/wiki/Special:MyLanguage/Communication"><span>Communication</span></a></li> </ul> </div> </div> <div id="p-development" class="vector-menu mw-portlet mw-portlet-development" > <div class="vector-menu-heading"> Development </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="n-mw-developerportal" class="mw-list-item"><a href="https://developer.wikimedia.org/"><span>Developer portal</span></a></li><li id="n-svn-statistics" class="mw-list-item"><a href="/wiki/Development_statistics"><span>Code statistics</span></a></li> </ul> </div> </div> <div id="p-mediawiki.org" class="vector-menu mw-portlet mw-portlet-mediawiki_org" > <div class="vector-menu-heading"> mediawiki.org </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="n-portal" class="mw-list-item"><a href="/wiki/Project:Help" title="About the project, what you can do, where to find things"><span>Community portal</span></a></li><li id="n-recentchanges" class="mw-list-item"><a href="/wiki/Special:RecentChanges" title="A list of recent changes in the wiki [r]" accesskey="r"><span>Recent changes</span></a></li><li id="n-mw-translate" class="mw-list-item"><a href="/wiki/Special:LanguageStats"><span>Translate content</span></a></li><li id="n-randompage" class="mw-list-item"><a href="/wiki/Special:Random" title="Load a random page [x]" accesskey="x"><span>Random page</span></a></li><li id="n-mw-discussion" class="mw-list-item"><a href="/wiki/Project:Village_Pump"><span>Village pump</span></a></li><li id="n-Sandboxlink-portlet-label" class="mw-list-item"><a href="/wiki/Project:Sandbox"><span>Sandbox</span></a></li> </ul> </div> </div> <div id="p-lang" class="vector-menu mw-portlet mw-portlet-lang" > <div class="vector-menu-heading"> In other languages </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> </ul> <div class="after-portlet after-portlet-lang"><span class="wb-langlinks-add wb-langlinks-link"><a href="https://www.wikidata.org/wiki/Special:NewItem?site=mediawikiwiki&amp;page=API%3AHolidays+viewer" title="Add interlanguage links" class="wbc-editpage">Add links</a></span></div> </div> </div> </div> </div> </div> </div> </nav> <a href="/wiki/MediaWiki" class="mw-logo"> <img class="mw-logo-icon" src="/static/images/icons/mediawikiwiki.svg" alt="" aria-hidden="true" height="50" width="50"> <span class="mw-logo-container skin-invert"> <img class="mw-logo-wordmark" alt="MediaWiki" src="/static/images/mobile/copyright/mediawikiwiki-wordmark.svg" style="width: 7.5em; height: 1.125em;"> </span> </a> </div> <div class="vector-header-end"> <div id="p-search" role="search" class="vector-search-box-vue vector-search-box-collapses vector-search-box-show-thumbnail vector-search-box-auto-expand-width vector-search-box"> <a href="/wiki/Special:Search" class="cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--icon-only search-toggle" title="Search MediaWiki [f]" accesskey="f"><span class="vector-icon mw-ui-icon-search mw-ui-icon-wikimedia-search"></span> <span>Search</span> </a> <div class="vector-typeahead-search-container"> <div class="cdx-typeahead-search cdx-typeahead-search--show-thumbnail cdx-typeahead-search--auto-expand-width"> <form action="/w/index.php" id="searchform" class="cdx-search-input cdx-search-input--has-end-button"> <div id="simpleSearch" class="cdx-search-input__input-wrapper" data-search-loc="header-moved"> <div class="cdx-text-input cdx-text-input--has-start-icon"> <input class="cdx-text-input__input" type="search" name="search" placeholder="Search MediaWiki" aria-label="Search MediaWiki" autocapitalize="sentences" title="Search MediaWiki [f]" accesskey="f" id="searchInput" > <span class="cdx-text-input__icon cdx-text-input__start-icon"></span> </div> <input type="hidden" name="title" value="Special:Search"> </div> <button class="cdx-button cdx-search-input__end-button">Search</button> </form> </div> </div> </div> <nav class="vector-user-links vector-user-links-wide" aria-label="Personal tools"> <div class="vector-user-links-main"> <div id="p-vector-user-menu-preferences" class="vector-menu mw-portlet" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="ca-uls" class="mw-list-item active user-links-collapsible-item"><a data-mw="interface" href="#" class="uls-trigger cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet"><span class="vector-icon mw-ui-icon-wikimedia-language mw-ui-icon-wikimedia-wikimedia-language"></span> <span>English</span></a> </li> </ul> </div> </div> <div id="p-vector-user-menu-userpage" class="vector-menu mw-portlet emptyPortlet" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> </ul> </div> </div> <nav class="vector-appearance-landmark" aria-label="Appearance"> <div id="vector-appearance-dropdown" class="vector-dropdown " title="Change the appearance of the page&#039;s font size, width, and color" > <input type="checkbox" id="vector-appearance-dropdown-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-appearance-dropdown" class="vector-dropdown-checkbox " aria-label="Appearance" > <label id="vector-appearance-dropdown-label" for="vector-appearance-dropdown-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--icon-only " aria-hidden="true" ><span class="vector-icon mw-ui-icon-appearance mw-ui-icon-wikimedia-appearance"></span> <span class="vector-dropdown-label-text">Appearance</span> </label> <div class="vector-dropdown-content"> <div id="vector-appearance-unpinned-container" class="vector-unpinned-container"> </div> </div> </div> </nav> <div id="p-vector-user-menu-notifications" class="vector-menu mw-portlet emptyPortlet" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> </ul> </div> </div> <div id="p-vector-user-menu-overflow" class="vector-menu mw-portlet" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="pt-sitesupport-2" class="user-links-collapsible-item mw-list-item user-links-collapsible-item"><a data-mw="interface" href="https://donate.wikimedia.org/?wmf_source=donate&amp;wmf_medium=sidebar&amp;wmf_campaign=www.mediawiki.org&amp;uselang=en" class=""><span>Donate</span></a> </li> <li id="pt-createaccount-2" class="user-links-collapsible-item mw-list-item user-links-collapsible-item"><a data-mw="interface" href="/w/index.php?title=Special:CreateAccount&amp;returnto=API%3AHolidays+viewer" title="You are encouraged to create an account and log in; however, it is not mandatory" class=""><span>Create account</span></a> </li> <li id="pt-login-2" class="user-links-collapsible-item mw-list-item user-links-collapsible-item"><a data-mw="interface" href="/w/index.php?title=Special:UserLogin&amp;returnto=API%3AHolidays+viewer" title="You are encouraged to log in; however, it is not mandatory [o]" accesskey="o" class=""><span>Log in</span></a> </li> </ul> </div> </div> </div> <div id="vector-user-links-dropdown" class="vector-dropdown vector-user-menu vector-button-flush-right vector-user-menu-logged-out" title="More options" > <input type="checkbox" id="vector-user-links-dropdown-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-user-links-dropdown" class="vector-dropdown-checkbox " aria-label="Personal tools" > <label id="vector-user-links-dropdown-label" for="vector-user-links-dropdown-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--icon-only " aria-hidden="true" ><span class="vector-icon mw-ui-icon-ellipsis mw-ui-icon-wikimedia-ellipsis"></span> <span class="vector-dropdown-label-text">Personal tools</span> </label> <div class="vector-dropdown-content"> <div id="p-personal" class="vector-menu mw-portlet mw-portlet-personal user-links-collapsible-item" title="User menu" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="pt-sitesupport" class="user-links-collapsible-item mw-list-item"><a href="https://donate.wikimedia.org/?wmf_source=donate&amp;wmf_medium=sidebar&amp;wmf_campaign=www.mediawiki.org&amp;uselang=en"><span>Donate</span></a></li><li id="pt-createaccount" class="user-links-collapsible-item mw-list-item"><a href="/w/index.php?title=Special:CreateAccount&amp;returnto=API%3AHolidays+viewer" title="You are encouraged to create an account and log in; however, it is not mandatory"><span class="vector-icon mw-ui-icon-userAdd mw-ui-icon-wikimedia-userAdd"></span> <span>Create account</span></a></li><li id="pt-login" class="user-links-collapsible-item mw-list-item"><a href="/w/index.php?title=Special:UserLogin&amp;returnto=API%3AHolidays+viewer" title="You are encouraged to log in; however, it is not mandatory [o]" accesskey="o"><span class="vector-icon mw-ui-icon-logIn mw-ui-icon-wikimedia-logIn"></span> <span>Log in</span></a></li> </ul> </div> </div> <div id="p-user-menu-anon-editor" class="vector-menu mw-portlet mw-portlet-user-menu-anon-editor" > <div class="vector-menu-heading"> Pages for logged out editors <a href="/wiki/Help:Introduction" aria-label="Learn more about editing"><span>learn more</span></a> </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="pt-anoncontribs" class="mw-list-item"><a href="/wiki/Special:MyContributions" title="A list of edits made from this IP address [y]" accesskey="y"><span>Contributions</span></a></li><li id="pt-anontalk" class="mw-list-item"><a href="/wiki/Special:MyTalk" title="Discussion about edits from this IP address [n]" accesskey="n"><span>Talk</span></a></li> </ul> </div> </div> </div> </div> </nav> </div> </header> </div> <div class="mw-page-container"> <div class="mw-page-container-inner"> <div class="vector-sitenotice-container"> <div id="siteNotice"><!-- CentralNotice --></div> </div> <div class="vector-column-start"> <div class="vector-main-menu-container"> <div id="mw-navigation"> <nav id="mw-panel" class="vector-main-menu-landmark" aria-label="Site"> <div id="vector-main-menu-pinned-container" class="vector-pinned-container"> </div> </nav> </div> </div> <div class="vector-sticky-pinned-container"> <nav id="mw-panel-toc" aria-label="Contents" data-event-name="ui.sidebar-toc" class="mw-table-of-contents-container vector-toc-landmark"> <div id="vector-toc-pinned-container" class="vector-pinned-container"> <div id="vector-toc" class="vector-toc vector-pinnable-element"> <div class="vector-pinnable-header vector-toc-pinnable-header vector-pinnable-header-pinned" data-feature-name="toc-pinned" data-pinnable-element-id="vector-toc" > <h2 class="vector-pinnable-header-label">Contents</h2> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-pin-button" data-event-name="pinnable-header.vector-toc.pin">move to sidebar</button> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button" data-event-name="pinnable-header.vector-toc.unpin">hide</button> </div> <ul class="vector-toc-contents" id="mw-panel-toc-list"> <li id="toc-mw-content-text" class="vector-toc-list-item vector-toc-level-1"> <a href="#" class="vector-toc-link"> <div class="vector-toc-text">Beginning</div> </a> </li> <li id="toc-Overview" class="vector-toc-list-item vector-toc-level-1 vector-toc-list-item-expanded"> <a class="vector-toc-link" href="#Overview"> <div class="vector-toc-text"> <span class="vector-toc-numb">1</span> <span>Overview</span> </div> </a> <ul id="toc-Overview-sublist" class="vector-toc-list"> </ul> </li> <li id="toc-A_step-by-step_process_for_building_this_application" class="vector-toc-list-item vector-toc-level-1 vector-toc-list-item-expanded"> <a class="vector-toc-link" href="#A_step-by-step_process_for_building_this_application"> <div class="vector-toc-text"> <span class="vector-toc-numb">2</span> <span>A step-by-step process for building this application</span> </div> </a> <button aria-controls="toc-A_step-by-step_process_for_building_this_application-sublist" class="cdx-button cdx-button--weight-quiet cdx-button--icon-only vector-toc-toggle"> <span class="vector-icon mw-ui-icon-wikimedia-expand"></span> <span>Toggle A step-by-step process for building this application subsection</span> </button> <ul id="toc-A_step-by-step_process_for_building_this_application-sublist" class="vector-toc-list"> <li id="toc-Step_1:_Set_up_Python_and_Flask_development_environment" class="vector-toc-list-item vector-toc-level-2"> <a class="vector-toc-link" href="#Step_1:_Set_up_Python_and_Flask_development_environment"> <div class="vector-toc-text"> <span class="vector-toc-numb">2.1</span> <span>Step 1: Set up Python and Flask development environment</span> </div> </a> <ul id="toc-Step_1:_Set_up_Python_and_Flask_development_environment-sublist" class="vector-toc-list"> </ul> </li> <li id="toc-Step_2:_Create_a_simple_Flask_application" class="vector-toc-list-item vector-toc-level-2"> <a class="vector-toc-link" href="#Step_2:_Create_a_simple_Flask_application"> <div class="vector-toc-text"> <span class="vector-toc-numb">2.2</span> <span>Step 2: Create a simple Flask application</span> </div> </a> <ul id="toc-Step_2:_Create_a_simple_Flask_application-sublist" class="vector-toc-list"> </ul> </li> <li id="toc-Step_3:_Create_the_base_layout" class="vector-toc-list-item vector-toc-level-2"> <a class="vector-toc-link" href="#Step_3:_Create_the_base_layout"> <div class="vector-toc-text"> <span class="vector-toc-numb">2.3</span> <span>Step 3: Create the base layout</span> </div> </a> <ul id="toc-Step_3:_Create_the_base_layout-sublist" class="vector-toc-list"> </ul> </li> <li id="toc-Step_4:_List_holidays" class="vector-toc-list-item vector-toc-level-2"> <a class="vector-toc-link" href="#Step_4:_List_holidays"> <div class="vector-toc-text"> <span class="vector-toc-numb">2.4</span> <span>Step 4: List holidays</span> </div> </a> <ul id="toc-Step_4:_List_holidays-sublist" class="vector-toc-list"> <li id="toc-Get_today&#039;s_date" class="vector-toc-list-item vector-toc-level-3"> <a class="vector-toc-link" href="#Get_today&#039;s_date"> <div class="vector-toc-text"> <span class="vector-toc-numb">2.4.1</span> <span>Get today's date</span> </div> </a> <ul id="toc-Get_today&#039;s_date-sublist" class="vector-toc-list"> </ul> </li> <li id="toc-Get_the_holidays_to_be_listed" class="vector-toc-list-item vector-toc-level-3"> <a class="vector-toc-link" href="#Get_the_holidays_to_be_listed"> <div class="vector-toc-text"> <span class="vector-toc-numb">2.4.2</span> <span>Get the holidays to be listed</span> </div> </a> <ul id="toc-Get_the_holidays_to_be_listed-sublist" class="vector-toc-list"> </ul> </li> <li id="toc-Update_holiday_links" class="vector-toc-list-item vector-toc-level-3"> <a class="vector-toc-link" href="#Update_holiday_links"> <div class="vector-toc-text"> <span class="vector-toc-numb">2.4.3</span> <span>Update holiday links</span> </div> </a> <ul id="toc-Update_holiday_links-sublist" class="vector-toc-list"> </ul> </li> </ul> </li> <li id="toc-Step_5:_Search_for_holidays_of_other_dates" class="vector-toc-list-item vector-toc-level-2"> <a class="vector-toc-link" href="#Step_5:_Search_for_holidays_of_other_dates"> <div class="vector-toc-text"> <span class="vector-toc-numb">2.5</span> <span>Step 5: Search for holidays of other dates</span> </div> </a> <ul id="toc-Step_5:_Search_for_holidays_of_other_dates-sublist" class="vector-toc-list"> </ul> </li> <li id="toc-Step_6:_Add_a_holiday" class="vector-toc-list-item vector-toc-level-2"> <a class="vector-toc-link" href="#Step_6:_Add_a_holiday"> <div class="vector-toc-text"> <span class="vector-toc-numb">2.6</span> <span>Step 6: Add a holiday</span> </div> </a> <ul id="toc-Step_6:_Add_a_holiday-sublist" class="vector-toc-list"> </ul> </li> <li id="toc-Step_7:_Styling_the_app" class="vector-toc-list-item vector-toc-level-2"> <a class="vector-toc-link" href="#Step_7:_Styling_the_app"> <div class="vector-toc-text"> <span class="vector-toc-numb">2.7</span> <span>Step 7: Styling the app</span> </div> </a> <ul id="toc-Step_7:_Styling_the_app-sublist" class="vector-toc-list"> </ul> </li> </ul> </li> <li id="toc-Application_layout" class="vector-toc-list-item vector-toc-level-1 vector-toc-list-item-expanded"> <a class="vector-toc-link" href="#Application_layout"> <div class="vector-toc-text"> <span class="vector-toc-numb">3</span> <span>Application layout</span> </div> </a> <ul id="toc-Application_layout-sublist" class="vector-toc-list"> </ul> </li> <li id="toc-Next_steps" class="vector-toc-list-item vector-toc-level-1 vector-toc-list-item-expanded"> <a class="vector-toc-link" href="#Next_steps"> <div class="vector-toc-text"> <span class="vector-toc-numb">4</span> <span>Next steps</span> </div> </a> <ul id="toc-Next_steps-sublist" class="vector-toc-list"> </ul> </li> <li id="toc-See_also" class="vector-toc-list-item vector-toc-level-1 vector-toc-list-item-expanded"> <a class="vector-toc-link" href="#See_also"> <div class="vector-toc-text"> <span class="vector-toc-numb">5</span> <span>See also</span> </div> </a> <ul id="toc-See_also-sublist" class="vector-toc-list"> </ul> </li> </ul> </div> </div> </nav> </div> </div> <div class="mw-content-container"> <main id="content" class="mw-body"> <header class="mw-body-header vector-page-titlebar"> <nav aria-label="Contents" class="vector-toc-landmark"> <div id="vector-page-titlebar-toc" class="vector-dropdown vector-page-titlebar-toc vector-button-flush-left" > <input type="checkbox" id="vector-page-titlebar-toc-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-page-titlebar-toc" class="vector-dropdown-checkbox " aria-label="Toggle the table of contents" > <label id="vector-page-titlebar-toc-label" for="vector-page-titlebar-toc-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--icon-only " aria-hidden="true" ><span class="vector-icon mw-ui-icon-listBullet mw-ui-icon-wikimedia-listBullet"></span> <span class="vector-dropdown-label-text">Toggle the table of contents</span> </label> <div class="vector-dropdown-content"> <div id="vector-page-titlebar-toc-unpinned-container" class="vector-unpinned-container"> </div> </div> </div> </nav> <h1 id="firstHeading" class="firstHeading mw-first-heading"><span class="mw-page-title-namespace">API</span><span class="mw-page-title-separator">:</span><span class="mw-page-title-main">Holidays viewer</span></h1> <div class="mw-indicators"> </div> </header> <div class="vector-page-toolbar"> <div class="vector-page-toolbar-container"> <div id="left-navigation"> <nav aria-label="Namespaces"> <div id="p-associated-pages" class="vector-menu vector-menu-tabs mw-portlet mw-portlet-associated-pages" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="ca-nstab-api" class="selected vector-tab-noicon mw-list-item"><a href="/wiki/API:Holidays_viewer" title="View the subject page [c]" accesskey="c"><span>API</span></a></li><li id="ca-talk" class="new vector-tab-noicon mw-list-item"><a href="/w/index.php?title=API_talk:Holidays_viewer&amp;action=edit&amp;redlink=1" rel="discussion" class="new" title="Discussion about the content page (page does not exist) [t]" accesskey="t"><span>Discussion</span></a></li> </ul> </div> </div> <div id="vector-variants-dropdown" class="vector-dropdown emptyPortlet" > <input type="checkbox" id="vector-variants-dropdown-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-variants-dropdown" class="vector-dropdown-checkbox " aria-label="Change language variant" > <label id="vector-variants-dropdown-label" for="vector-variants-dropdown-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet" aria-hidden="true" ><span class="vector-dropdown-label-text">English</span> </label> <div class="vector-dropdown-content"> <div id="p-variants" class="vector-menu mw-portlet mw-portlet-variants emptyPortlet" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> </ul> </div> </div> </div> </div> </nav> </div> <div id="right-navigation" class="vector-collapsible"> <nav aria-label="Views"> <div id="p-views" class="vector-menu vector-menu-tabs mw-portlet mw-portlet-views" > <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="ca-view" class="selected vector-tab-noicon mw-list-item"><a href="/wiki/API:Holidays_viewer"><span>Read</span></a></li><li id="ca-viewsource" class="vector-tab-noicon mw-list-item"><a href="/w/index.php?title=API:Holidays_viewer&amp;action=edit" title="This page is protected.&#10;You can view its source [e]" accesskey="e"><span>View source</span></a></li><li id="ca-history" class="vector-tab-noicon mw-list-item"><a href="/w/index.php?title=API:Holidays_viewer&amp;action=history" title="Past revisions of this page [h]" accesskey="h"><span>View history</span></a></li> </ul> </div> </div> </nav> <nav class="vector-page-tools-landmark" aria-label="Page tools"> <div id="vector-page-tools-dropdown" class="vector-dropdown vector-page-tools-dropdown" > <input type="checkbox" id="vector-page-tools-dropdown-checkbox" role="button" aria-haspopup="true" data-event-name="ui.dropdown-vector-page-tools-dropdown" class="vector-dropdown-checkbox " aria-label="Tools" > <label id="vector-page-tools-dropdown-label" for="vector-page-tools-dropdown-checkbox" class="vector-dropdown-label cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet" aria-hidden="true" ><span class="vector-dropdown-label-text">Tools</span> </label> <div class="vector-dropdown-content"> <div id="vector-page-tools-unpinned-container" class="vector-unpinned-container"> <div id="vector-page-tools" class="vector-page-tools vector-pinnable-element"> <div class="vector-pinnable-header vector-page-tools-pinnable-header vector-pinnable-header-unpinned" data-feature-name="page-tools-pinned" data-pinnable-element-id="vector-page-tools" data-pinned-container-id="vector-page-tools-pinned-container" data-unpinned-container-id="vector-page-tools-unpinned-container" > <div class="vector-pinnable-header-label">Tools</div> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-pin-button" data-event-name="pinnable-header.vector-page-tools.pin">move to sidebar</button> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button" data-event-name="pinnable-header.vector-page-tools.unpin">hide</button> </div> <div id="p-cactions" class="vector-menu mw-portlet mw-portlet-cactions emptyPortlet vector-has-collapsible-items" title="More options" > <div class="vector-menu-heading"> Actions </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="ca-more-view" class="selected vector-more-collapsible-item mw-list-item"><a href="/wiki/API:Holidays_viewer"><span>Read</span></a></li><li id="ca-more-viewsource" class="vector-more-collapsible-item mw-list-item"><a href="/w/index.php?title=API:Holidays_viewer&amp;action=edit"><span>View source</span></a></li><li id="ca-more-history" class="vector-more-collapsible-item mw-list-item"><a href="/w/index.php?title=API:Holidays_viewer&amp;action=history"><span>View history</span></a></li> </ul> </div> </div> <div id="p-tb" class="vector-menu mw-portlet mw-portlet-tb" > <div class="vector-menu-heading"> General </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="t-whatlinkshere" class="mw-list-item"><a href="/wiki/Special:WhatLinksHere/API:Holidays_viewer" title="A list of all wiki pages that link here [j]" accesskey="j"><span>What links here</span></a></li><li id="t-recentchangeslinked" class="mw-list-item"><a href="/wiki/Special:RecentChangesLinked/API:Holidays_viewer" rel="nofollow" title="Recent changes in pages linked from this page [k]" accesskey="k"><span>Related changes</span></a></li><li id="t-upload" class="mw-list-item"><a href="//commons.wikimedia.org/wiki/Special:UploadWizard" title="Upload files [u]" accesskey="u"><span>Upload file</span></a></li><li id="t-specialpages" class="mw-list-item"><a href="/wiki/Special:SpecialPages" title="A list of all special pages [q]" accesskey="q"><span>Special pages</span></a></li><li id="t-permalink" class="mw-list-item"><a href="/w/index.php?title=API:Holidays_viewer&amp;oldid=6749968" title="Permanent link to this revision of this page"><span>Permanent link</span></a></li><li id="t-info" class="mw-list-item"><a href="/w/index.php?title=API:Holidays_viewer&amp;action=info" title="More information about this page"><span>Page information</span></a></li><li id="t-cite" class="mw-list-item"><a href="/w/index.php?title=Special:CiteThisPage&amp;page=API%3AHolidays_viewer&amp;id=6749968&amp;wpFormIdentifier=titleform" title="Information on how to cite this page"><span>Cite this page</span></a></li><li id="t-urlshortener" class="mw-list-item"><a href="/w/index.php?title=Special:UrlShortener&amp;url=https%3A%2F%2Fwww.mediawiki.org%2Fwiki%2FAPI%3AHolidays_viewer"><span>Get shortened URL</span></a></li><li id="t-urlshortener-qrcode" class="mw-list-item"><a href="/w/index.php?title=Special:QrCode&amp;url=https%3A%2F%2Fwww.mediawiki.org%2Fwiki%2FAPI%3AHolidays_viewer"><span>Download QR code</span></a></li> </ul> </div> </div> <div id="p-coll-print_export" class="vector-menu mw-portlet mw-portlet-coll-print_export" > <div class="vector-menu-heading"> Print/export </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> <li id="coll-create_a_book" class="mw-list-item"><a href="/w/index.php?title=Special:Book&amp;bookcmd=book_creator&amp;referer=API%3AHolidays+viewer"><span>Create a book</span></a></li><li id="coll-download-as-rl" class="mw-list-item"><a href="/w/index.php?title=Special:DownloadAsPdf&amp;page=API%3AHolidays_viewer&amp;action=show-download-screen"><span>Download as PDF</span></a></li><li id="t-print" class="mw-list-item"><a href="/w/index.php?title=API:Holidays_viewer&amp;printable=yes" title="Printable version of this page [p]" accesskey="p"><span>Printable version</span></a></li> </ul> </div> </div> <div id="p-wikibase-otherprojects" class="vector-menu mw-portlet mw-portlet-wikibase-otherprojects emptyPortlet" > <div class="vector-menu-heading"> In other projects </div> <div class="vector-menu-content"> <ul class="vector-menu-content-list"> </ul> </div> </div> </div> </div> </div> </div> </nav> </div> </div> </div> <div class="vector-column-end"> <div class="vector-sticky-pinned-container"> <nav class="vector-page-tools-landmark" aria-label="Page tools"> <div id="vector-page-tools-pinned-container" class="vector-pinned-container"> </div> </nav> <nav class="vector-appearance-landmark" aria-label="Appearance"> <div id="vector-appearance-pinned-container" class="vector-pinned-container"> <div id="vector-appearance" class="vector-appearance vector-pinnable-element"> <div class="vector-pinnable-header vector-appearance-pinnable-header vector-pinnable-header-pinned" data-feature-name="appearance-pinned" data-pinnable-element-id="vector-appearance" data-pinned-container-id="vector-appearance-pinned-container" data-unpinned-container-id="vector-appearance-unpinned-container" > <div class="vector-pinnable-header-label">Appearance</div> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-pin-button" data-event-name="pinnable-header.vector-appearance.pin">move to sidebar</button> <button class="vector-pinnable-header-toggle-button vector-pinnable-header-unpin-button" data-event-name="pinnable-header.vector-appearance.unpin">hide</button> </div> </div> </div> </nav> </div> </div> <div id="bodyContent" class="vector-body" aria-labelledby="firstHeading" data-mw-ve-target-container> <div class="vector-body-before-content"> <div id="siteSub" class="noprint">From mediawiki.org</div> </div> <div id="contentSub"><div id="mw-content-subtitle"></div></div> <div id="mw-content-text" class="mw-body-content"><div class="mw-pt-translate-header noprint nomobile" dir="ltr" lang="en"><a href="/w/index.php?title=Special:Translate&amp;group=page-API%3AHolidays+viewer&amp;action=page&amp;filter=&amp;action_source=translate_page" title="Special:Translate">Translate this page</a></div><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr"><div class="mw-pt-languages noprint navigation-not-searchable" lang="en" dir="ltr"><div class="mw-pt-languages-label">Languages:</div><ul class="mw-pt-languages-list"><li><a href="/wiki/API:Holidays_viewer/de" class="mw-pt-progress mw-pt-progress--complete" title="API:Feiertags-Betrachter (100% translated)" lang="de" dir="ltr">Deutsch</a></li> <li><span class="mw-pt-languages-ui mw-pt-languages-selected mw-pt-progress mw-pt-progress--complete" lang="en" dir="ltr">English</span></li> <li><a href="/wiki/API:Holidays_viewer/ha" class="mw-pt-progress mw-pt-progress--high" title="API: Mai duba hutu (96% translated)" lang="ha" dir="ltr">Hausa</a></li> <li><a href="/wiki/API:Holidays_viewer/mrh" class="mw-pt-progress mw-pt-progress--low" title="API:Chhitinohzy mona (7% translated)" lang="mrh" dir="ltr">Mara</a></li> <li><a href="/wiki/API:Holidays_viewer/tr" class="mw-pt-progress mw-pt-progress--high" title="API:Tatil görüntüleyicisi (99% translated)" lang="tr" dir="ltr">Türkçe</a></li> <li><a href="/wiki/API:Holidays_viewer/es" class="mw-pt-progress mw-pt-progress--low" title="API:Visor de vacaciones (4% translated)" lang="es" dir="ltr">español</a></li> <li><a href="/wiki/API:Holidays_viewer/fr" class="mw-pt-progress mw-pt-progress--complete" title="Afficheur de jour férié (100% translated)" lang="fr" dir="ltr">français</a></li> <li><a href="/wiki/API:Holidays_viewer/pl" class="mw-pt-progress mw-pt-progress--low" title="API:Holidays viewer/pl (3% translated)" lang="pl" dir="ltr">polski</a></li> <li><a href="/wiki/API:Holidays_viewer/pt" class="mw-pt-progress mw-pt-progress--low" title="API:Holidays viewer/pt (0% translated)" lang="pt" dir="ltr">português</a></li> <li><a href="/wiki/API:Holidays_viewer/cs" class="mw-pt-progress mw-pt-progress--complete" title="API:Prohlížeč svátků (100% translated)" lang="cs" dir="ltr">čeština</a></li> <li><a href="/wiki/API:Holidays_viewer/ru" class="mw-pt-progress mw-pt-progress--low" title="API:Просмотр праздников (3% translated)" lang="ru" dir="ltr">русский</a></li> <li><a href="/wiki/API:Holidays_viewer/th" class="mw-pt-progress mw-pt-progress--low" title="API:Holidays viewer (9% translated)" lang="th" dir="ltr">ไทย</a></li> <li><a href="/wiki/API:Holidays_viewer/ja" class="mw-pt-progress mw-pt-progress--low" title="API:休日ビューア (12% translated)" lang="ja" dir="ltr">日本語</a></li></ul></div> <style data-mw-deduplicate="TemplateStyles:r6651108">.mw-parser-output table.ombox{margin:4px 10%;border-collapse:collapse;border:1px solid #a2a9b1;background-color:#f8f9fa;color:#333;box-sizing:border-box}.mw-parser-output .ombox td.mbox-empty-cell{border:none;padding:0;width:1px}.mw-parser-output .ombox th.mbox-text,.mw-parser-output .ombox td.mbox-text{border:none;padding:0.25em 0.9em;width:100%}.mw-parser-output .ombox td.mbox-image{border:none;text-align:center;padding:2px 0 2px 0.9em}.mw-parser-output .ombox td.mbox-imageright{border:none;text-align:center;padding:2px 0.9em 2px 0}.mw-parser-output table.ombox-notice{border-color:#a2a9b1}.mw-parser-output table.ombox-speedy{background-color:#fee7e6;color:#333}.mw-parser-output table.ombox-speedy,.mw-parser-output table.ombox-delete{border-color:#b32424;border-width:2px}.mw-parser-output table.ombox-content{border-color:#f28500}.mw-parser-output table.ombox-style{border-color:#fc3}.mw-parser-output table.ombox-move{border-color:#9932cc}.mw-parser-output table.ombox-protection{border-color:#a2a9b1;border-width:2px}html body.mediawiki .mw-parser-output .ombox.mbox-small{clear:right;float:right;margin:4px 0 4px 1em;box-sizing:border-box;width:238px;font-size:88%;line-height:1.25em}@media screen{html.skin-theme-clientpref-night .mw-parser-output table.ombox{background-color:transparent;color:inherit}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output table.ombox{background-color:transparent;color:inherit}}</style><table class="skin-nightmode-reset-color ombox ombox-content plainlinks" role="presentation" style="display: block; color:#222; border:solid 1px #A8A8A8; padding: .5em 1em; margin:0.5em 0em;"><tbody><tr><td class="mbox-image"><span class="skin-invert-image" typeof="mw:File"><span><img alt="" src="//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/API_-_The_Noun_Project.svg/30px-API_-_The_Noun_Project.svg.png" decoding="async" width="30" height="30" class="mw-file-element" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/API_-_The_Noun_Project.svg/45px-API_-_The_Noun_Project.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/f/f6/API_-_The_Noun_Project.svg/60px-API_-_The_Noun_Project.svg.png 2x" data-file-width="512" data-file-height="512" /></span></span></td><td class="mbox-text">This page is part of the <a href="/wiki/Special:MyLanguage/API:Main_page" title="Special:MyLanguage/API:Main page">MediaWiki Action API</a> documentation.</td></tr></tbody></table> <style data-mw-deduplicate="TemplateStyles:r6605224">.mw-parser-output .tpl-sidebar{background-color:var(--background-color-interactive-subtle,#f8f9fa);border:1px solid var(--border-color-divider,#a2a9b1);color:var(--color-base,#202122);width:22em;padding:.2em;text-align:center;line-height:1.4em;font-size:88%}.mw-parser-output .tpl-sidebar-pagedir-ltr,.mw-parser-output .tpl-sidebar.tpl-sidebar-floatright{float:right;clear:right;margin:.5em 0 1em 1em}.mw-parser-output .tpl-sidebar-pagedir-rtl,.mw-parser-output .tpl-sidebar.tpl-sidebar-floatleft{float:left;clear:left;margin:.5em 1em 1em 0}.mw-parser-output .tpl-sidebar.tpl-sidebar-floatnone{float:none;clear:both;margin:.5em 0 1em 1em}.mw-parser-output .tpl-sidebar>caption{padding-bottom:.2em;font-size:125%;line-height:1.2em;font-weight:bold}.mw-parser-output .tpl-sidebar>tbody>tr>th,.mw-parser-output .tpl-sidebar>tbody>tr>td{padding:0}.mw-parser-output .tpl-sidebar .tpl-sidebar-topimage>td{padding:.4em 0}.mw-parser-output .tpl-sidebar-imagecaption{padding-top:.2em;line-height:1.2em}.mw-parser-output .tpl-sidebar .tpl-sidebar-pretitle>td{padding-top:.4em;line-height:1.2em}.mw-parser-output .tpl-sidebar .tpl-sidebar-topimage+.tpl-sidebar-pretitle>td{padding-top:.2em}.mw-parser-output .tpl-sidebar .tpl-sidebar-title>th{padding:.2em .4em .2em;font-size:145%;line-height:1.2em}.mw-parser-output .tpl-sidebar .tpl-sidebar-pretitle+.tpl-sidebar-title>th{padding-top:0}.mw-parser-output .tpl-sidebar .tpl-sidebar-image>td{padding:.2em 0 .4em}.mw-parser-output .tpl-sidebar .tpl-sidebar-abovebelow>td{padding:.3em .4em;font-weight:bold}.mw-parser-output .tpl-sidebar .tpl-sidebar-heading>th{padding-top:.2em}.mw-parser-output .tpl-sidebar .tpl-sidebar-image~.tpl-sidebar-heading-first>th{padding-top:.4em}.mw-parser-output .tpl-sidebar .tpl-sidebar-content>td{padding-bottom:.2em}.mw-parser-output .tpl-sidebar :not(.tpl-sidebar-heading)+.tpl-sidebar-content-first>td{padding-top:.2em}.mw-parser-output .tpl-sidebar-navbar>td{font-size:115%}.mw-parser-output .tpl-sidebar-pagedir-ltr .tpl-sidebar-navbar>td{text-align:right}.mw-parser-output .tpl-sidebar-pagedir-rtl .tpl-sidebar-navbar>td{text-align:left}</style><table class="vertical-navbox tpl-sidebar tpl-sidebar-pagedir-ltr nowraplinks noprint" role="navigation" style="width:22em; border-spacing: 0.4em 0; text-align: left; padding: 1.5em; padding: min(1.5em, 2%); margin: 0 0 2em 2em; width: 320px; max-width: 40%;"><tbody><tr class="tpl-sidebar-title"> <th class="" style="font-size: 19px; font-weight: 700; padding: 0;"><a href="/wiki/Special:MyLanguage/API:Main_page" title="Special:MyLanguage/API:Main page">MediaWiki Action API</a><span style="display:none"><a href="/wiki/API:Main_page" title="API:Main page"> </a></span></th> </tr><tr class="tpl-sidebar-heading tpl-sidebar-heading-first"> <th class="" style="font-size: 16px; font-weight: 700; padding-top: 1em;;">Basics</th> </tr><tr class="tpl-sidebar-content tpl-sidebar-content-first"> <td class="" style=";"> <ul><li><a href="/wiki/Special:MyLanguage/API:Etiquette" title="Special:MyLanguage/API:Etiquette">Etiquette and usage guidelines</a><span style="display:none"><a href="/wiki/API:Etiquette" title="API:Etiquette"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Query" title="Special:MyLanguage/API:Query">All query modules</a><span style="display:none"><a href="/wiki/API:Query" title="API:Query"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Properties" title="Special:MyLanguage/API:Properties">All page properties</a><span style="display:none"><a href="/wiki/API:Properties" title="API:Properties"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Lists" title="Special:MyLanguage/API:Lists">All list modules</a><span style="display:none"><a href="/wiki/API:Lists" title="API:Lists"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Meta" title="Special:MyLanguage/API:Meta">All meta modules</a><span style="display:none"><a href="/wiki/API:Meta" title="API:Meta"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Data_formats" title="Special:MyLanguage/API:Data formats">Output formats</a><span style="display:none"><a href="/wiki/API:Data_formats" title="API:Data formats"> </a></span></li></ul></td> </tr><tr class="tpl-sidebar-heading"> <th class="" style="font-size: 16px; font-weight: 700; padding-top: 1em;;">Authentication</th> </tr><tr class="tpl-sidebar-content"> <td class="" style=";"> <ul><li><a href="/wiki/Special:MyLanguage/API:Tokens" title="Special:MyLanguage/API:Tokens">Get tokens for data modifying operations</a><span style="display:none"><a href="/wiki/API:Tokens" title="API:Tokens"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Login" title="Special:MyLanguage/API:Login">Login</a><span style="display:none"><a href="/wiki/API:Login" title="API:Login"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Logout" title="Special:MyLanguage/API:Logout">Logout</a><span style="display:none"><a href="/wiki/API:Logout" title="API:Logout"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Assert" title="Special:MyLanguage/API:Assert">Verifying authentication (assertions)</a><span style="display:none"><a href="/wiki/API:Assert" title="API:Assert"> </a></span></li></ul></td> </tr><tr class="tpl-sidebar-heading"> <th class="" style="font-size: 16px; font-weight: 700; padding-top: 1em;;">Accounts and Users</th> </tr><tr class="tpl-sidebar-content"> <td class="" style=";"> <ul><li><a href="/wiki/Special:MyLanguage/API:Account_creation" title="Special:MyLanguage/API:Account creation">Create an account</a><span style="display:none"><a href="/wiki/API:Account_creation" title="API:Account creation"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Block" title="Special:MyLanguage/API:Block">Block or unblock a user</a><span style="display:none"><a href="/wiki/API:Block" title="API:Block"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Userinfo" title="Special:MyLanguage/API:Userinfo">Get info about the current user</a><span style="display:none"><a href="/wiki/API:Userinfo" title="API:Userinfo"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Watchlist_feed" title="Special:MyLanguage/API:Watchlist feed">Get the current user's watchlist as a feed</a><span style="display:none"><a href="/wiki/API:Watchlist_feed" title="API:Watchlist feed"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Options" title="Special:MyLanguage/API:Options">Change user options</a><span style="display:none"><a href="/wiki/API:Options" title="API:Options"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:User_group_membership" title="Special:MyLanguage/API:User group membership">Change user group membership</a><span style="display:none"><a href="/wiki/API:User_group_membership" title="API:User group membership"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Emailuser" title="Special:MyLanguage/API:Emailuser">Send an email</a><span style="display:none"><a href="/wiki/API:Emailuser" title="API:Emailuser"> </a></span></li></ul></td> </tr><tr class="tpl-sidebar-heading"> <th class="" style="font-size: 16px; font-weight: 700; padding-top: 1em;;">Page Operations</th> </tr><tr class="tpl-sidebar-content"> <td class="" style=";"> <ul><li><a href="/wiki/Special:MyLanguage/API:Edit" title="Special:MyLanguage/API:Edit">Create and edit a page</a><span style="display:none"><a href="/wiki/API:Edit" title="API:Edit"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Get_the_contents_of_a_page" title="Special:MyLanguage/API:Get the contents of a page">Get the contents of a page</a><span style="display:none"><a href="/wiki/API:Get_the_contents_of_a_page" title="API:Get the contents of a page"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Upload" title="Special:MyLanguage/API:Upload">Upload a file</a><span style="display:none"><a href="/wiki/API:Upload" title="API:Upload"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Import" title="Special:MyLanguage/API:Import">Import a page</a><span style="display:none"><a href="/wiki/API:Import" title="API:Import"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Delete" title="Special:MyLanguage/API:Delete">Delete a page</a><span style="display:none"><a href="/wiki/API:Delete" title="API:Delete"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Parsing_wikitext" title="Special:MyLanguage/API:Parsing wikitext">Parse content of a page</a><span style="display:none"><a href="/wiki/API:Parsing_wikitext" title="API:Parsing wikitext"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Watch" title="Special:MyLanguage/API:Watch">Watch or unwatch a page</a><span style="display:none"><a href="/wiki/API:Watch" title="API:Watch"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Purge" title="Special:MyLanguage/API:Purge">Purge cache for page(s)</a><span style="display:none"><a href="/wiki/API:Purge" title="API:Purge"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Rollback" title="Special:MyLanguage/API:Rollback">Rollback a page</a><span style="display:none"><a href="/wiki/API:Rollback" title="API:Rollback"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Move" title="Special:MyLanguage/API:Move">Move a page</a><span style="display:none"><a href="/wiki/API:Move" title="API:Move"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Patrol" title="Special:MyLanguage/API:Patrol">Patrol a page or revision</a><span style="display:none"><a href="/wiki/API:Patrol" title="API:Patrol"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Undelete" title="Special:MyLanguage/API:Undelete">Restore revisions of a deleted page</a><span style="display:none"><a href="/wiki/API:Undelete" title="API:Undelete"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Protect" title="Special:MyLanguage/API:Protect">Change a page's protection level</a><span style="display:none"><a href="/wiki/API:Protect" title="API:Protect"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:SetPageLanguage" title="Special:MyLanguage/API:SetPageLanguage">Change a page's language</a><span style="display:none"><a href="/wiki/API:SetPageLanguage" title="API:SetPageLanguage"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Changing_wiki_content" title="Special:MyLanguage/API:Changing wiki content">More...</a><span style="display:none"><a href="/wiki/API:Changing_wiki_content" title="API:Changing wiki content"> </a></span></li></ul></td> </tr><tr class="tpl-sidebar-heading"> <th class="" style="font-size: 16px; font-weight: 700; padding-top: 1em;;">Search</th> </tr><tr class="tpl-sidebar-content"> <td class="" style=";"> <ul><li><a href="/wiki/Special:MyLanguage/API:Opensearch" title="Special:MyLanguage/API:Opensearch">Search wiki pages by title (OpenSearch)</a><span style="display:none"><a href="/wiki/API:Opensearch" title="API:Opensearch"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Search" title="Special:MyLanguage/API:Search">Advanced search for wiki pages by title or text</a><span style="display:none"><a href="/wiki/API:Search" title="API:Search"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Geosearch" title="Special:MyLanguage/API:Geosearch">Search wiki pages near a location</a><span style="display:none"><a href="/wiki/API:Geosearch" title="API:Geosearch"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Languagesearch" title="Special:MyLanguage/API:Languagesearch">Search for a language name</a><span style="display:none"><a href="/wiki/API:Languagesearch" title="API:Languagesearch"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Prefixsearch" title="Special:MyLanguage/API:Prefixsearch">Perform a prefix search for page titles</a><span style="display:none"><a href="/wiki/API:Prefixsearch" title="API:Prefixsearch"> </a></span></li></ul></td> </tr><tr class="tpl-sidebar-heading"> <th class="" style="font-size: 16px; font-weight: 700; padding-top: 1em;;">Developer Utilities</th> </tr><tr class="tpl-sidebar-content"> <td class="" style=";"> <ul><li><a href="/wiki/Special:MyLanguage/API:Client_code" title="Special:MyLanguage/API:Client code">Access libraries</a><span style="display:none"><a href="/wiki/API:Client_code" title="API:Client code"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Cross-site_requests" title="Special:MyLanguage/API:Cross-site requests">Cross-site requests</a><span style="display:none"><a href="/wiki/API:Cross-site_requests" title="API:Cross-site requests"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Extensions" title="Special:MyLanguage/API:Extensions">Creating an API module in an extension</a><span style="display:none"><a href="/wiki/API:Extensions" title="API:Extensions"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Calling_internally" title="Special:MyLanguage/API:Calling internally">Using the API in MediaWiki and extensions</a><span style="display:none"><a href="/wiki/API:Calling_internally" title="API:Calling internally"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Restricting_API_usage" title="Special:MyLanguage/API:Restricting API usage">Restricting API usage</a><span style="display:none"><a href="/wiki/API:Restricting_API_usage" title="API:Restricting API usage"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Localisation" title="Special:MyLanguage/API:Localisation">Localisation</a><span style="display:none"><a href="/wiki/API:Localisation" title="API:Localisation"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Implementation_Strategy" title="Special:MyLanguage/API:Implementation Strategy">Implementation Strategy</a><span style="display:none"><a href="/wiki/API:Implementation_Strategy" title="API:Implementation Strategy"> </a></span></li></ul></td> </tr><tr class="tpl-sidebar-heading"> <th class="" style="font-size: 16px; font-weight: 700; padding-top: 1em;;">Tutorials</th> </tr><tr class="tpl-sidebar-content"> <td class="" style=";"> <ul><li><a href="/wiki/Special:MyLanguage/API:Tutorial" title="Special:MyLanguage/API:Tutorial">Action API Tutorial</a><span style="display:none"><a href="/wiki/API:Tutorial" title="API:Tutorial"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Article_ideas_generator" title="Special:MyLanguage/API:Article ideas generator">Article ideas generator</a><span style="display:none"><a href="/wiki/API:Article_ideas_generator" title="API:Article ideas generator"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Nearby_places_viewer" title="Special:MyLanguage/API:Nearby places viewer">Nearby places viewer</a><span style="display:none"><a href="/wiki/API:Nearby_places_viewer" title="API:Nearby places viewer"> </a></span></li> <li><a href="/wiki/Special:MyLanguage/API:Picture_of_the_day_viewer" title="Special:MyLanguage/API:Picture of the day viewer">Picture of the day viewer</a><span style="display:none"><a href="/wiki/API:Picture_of_the_day_viewer" title="API:Picture of the day viewer"> </a></span></li> <li><b><a href="/wiki/Special:MyLanguage/API:Holidays_viewer" title="Special:MyLanguage/API:Holidays viewer">Holidays viewer</a></b><span style="display:none"><a class="mw-selflink selflink"> </a></span></li></ul></td> </tr><tr class="tpl-sidebar-navbar"> <td style=""><style data-mw-deduplicate="TemplateStyles:r4692751">.mw-parser-output .navbar{display:inline;font-size:88%;font-weight:normal}.mw-parser-output .navbar ul{display:inline;white-space:nowrap}.mw-parser-output .navbar li{word-spacing:-0.125em}.mw-parser-output .navbox .navbar{display:block;font-size:100%}.mw-parser-output .navbox-title .navbar{float:left;text-align:left;margin-right:0.5em;width:6em}</style><span class="noprint plainlinks navbar" style=""><small><span style="white-space:nowrap;word-spacing:-.12em;"><a href="/wiki/Template:API" title="Template:API"><span style="" title="View this template">v</span></a><span style="">&#32;<b>&#183;</b>&#32;</span><a class="external text" href="https://www.mediawiki.org/wiki/Template_talk:API"><span style="" title="Discuss this template">d</span></a><span style="">&#32;<b>&#183;</b>&#32;</span><a class="external text" href="https://www.mediawiki.org/w/index.php?title=Template:API&amp;action=edit"><span style="" title="Edit this template">e</span></a></span></small></span></td> </tr> </tbody></table> <div style="overflow:auto"> <style data-mw-deduplicate="TemplateStyles:r4577480">.mw-parser-output .toclimit-2 .toclevel-1 ul,.mw-parser-output .toclimit-3 .toclevel-2 ul,.mw-parser-output .toclimit-4 .toclevel-3 ul,.mw-parser-output .toclimit-5 .toclevel-4 ul,.mw-parser-output .toclimit-6 .toclevel-5 ul,.mw-parser-output .toclimit-7 .toclevel-6 ul{display:none}</style><div style="margin-bottom: .5em; float: none; width: auto;" class="toclimit-4"><meta property="mw:PageProp/toc" /></div> </div> <div class="mw-heading mw-heading2"><h2 id="Overview">Overview</h2></div> <p>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. </p> <div style="text-align: center"> <p><a rel="nofollow" class="external text" href="https://github.com/wikimedia/mediawiki-api-demos/tree/master/apps/holidays-viewer"><span class="mw-ui-button mw-ui-progressive mw-ui-small" style="font-size: 1.2em">Download the code from GitHub</span></a> <a href="https://iw.toolforge.org/holidays-viewer/" class="extiw" title="toolforge:holidays-viewer/"><span class="mw-ui-button mw-ui-progressive mw-ui-small" style="font-size: 1.2em">Browse the app on Toolforge</span></a> </p> </div> <p>The tools and technologies used to create the demo app are: </p> <ul><li><a rel="nofollow" class="external text" href="https://www.python.org/">Python 3</a> and <a rel="nofollow" class="external text" href="https://flask.palletsprojects.com/en/1.1.x/">Flask</a>, a Python framework.</li> <li><a rel="nofollow" class="external text" href="https://jquery.com/">jQuery</a> and <a rel="nofollow" class="external text" href="https://getbootstrap.com/">Bootstrap</a>. They are <a class="external text" href="https://phabricator.wikimedia.org/phame/post/view/65/toolforge_provides_proxied_mirrors_of_cdnjs_and_now_fontcdn_for_your_usage_and_user-privacy/">loaded from Wikimedia Toolforge for privacy reasons</a>.</li> <li><a href="/wiki/Special:MyLanguage/API:Main_page" title="Special:MyLanguage/API:Main page">MediaWiki Action API</a> modules: <a href="/wiki/Special:MyLanguage/API:Parse" title="Special:MyLanguage/API:Parse">API:Parse</a><span style="display:none"><a href="/wiki/API:Parse" class="mw-redirect" title="API:Parse"> </a></span>, <a href="/wiki/Special:MyLanguage/API:Login" title="Special:MyLanguage/API:Login">API:Login</a><span style="display:none"><a href="/wiki/API:Login" title="API:Login"> </a></span> and <a href="/wiki/Special:MyLanguage/API:Edit" title="Special:MyLanguage/API:Edit">API:Edit</a><span style="display:none"><a href="/wiki/API:Edit" title="API:Edit"> </a></span>.</li></ul> <div class="mw-heading mw-heading2"><h2 id="A_step-by-step_process_for_building_this_application">A step-by-step process for building this application</h2></div> <div class="mw-heading mw-heading3"><h3 id="Step_1:_Set_up_Python_and_Flask_development_environment">Step 1: Set up Python and Flask development environment</h3></div> <p>Python comes pre-installed on most Linux distributions. For other operating systems, see the <a rel="nofollow" class="external text" href="https://wiki.python.org/moin/BeginnersGuide/Download">Python beginner's guide</a> for installation instructions. </p><p>Install Flask by running <code>pip install flask</code>. If you don't have Pip, get it from <a rel="nofollow" class="external text" href="https://pip.pypa.io/en/stable/installation/">the official Pip website</a> </p><p><br /> </p> <div class="mw-heading mw-heading3"><h3 id="Step_2:_Create_a_simple_Flask_application">Step 2: Create a simple Flask application</h3></div> <p>In your home directory, create a folder named <code>holidays-viewer</code> which will contain all the app's files. Inside the folder, create a file named <code>app.py</code> and place the following code in it: </p> <div style="width: 60%"> <div class="mw-highlight mw-highlight-lang-python3 mw-content-ltr" dir="ltr"><pre><span></span><span class="ch">#!/usr/bin/python3</span> <span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span> <span class="n">APP</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span> <span class="nd">@APP</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span> <span class="k">def</span> <span class="nf">list_holidays</span><span class="p">():</span> <span class="k">return</span> <span class="s2">&quot;Holidays and observances&quot;</span> <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span> <span class="n">APP</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> </pre></div> </div> <p>Run the app using the command <code>python app.py</code> and open <code><a rel="nofollow" class="external free" href="http://127.0.0.1:5000/">http://127.0.0.1:5000/</a></code> on your browser. You should see "Holidays and observances" displayed. </p> <div class="mw-heading mw-heading3"><h3 id="Step_3:_Create_the_base_layout">Step 3: Create the base layout</h3></div> <p>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 <code>layout.html</code> to contain these elements. </p><p>Note that we are using <a rel="nofollow" class="external text" href="https://getbootstrap.com/">Bootstrap</a> classes to apply a specific CSS style to an element, <a rel="nofollow" class="external text" href="https://materializecss.com/icons.html">Materialize icons</a> for the add, search and arrow-back icons, and <a rel="nofollow" class="external text" href="https://palletsprojects.com/p/jinja/">Jinja</a> to extend the base layout to other pages and to pass variables from Python to HTML. </p> <div style="display:block;margin-left:0;"><table class="mw-collapsible mw-collapsed" style="margin-top:.2em; border:1px solid silver;text-align:left; width: 100%;"><tbody><tr><th style="font-size:112%;background:#F8FCFF;color:black;text-align:center">$HOME/holidays-viewer/templates/layout.html</th></tr><tr><td style="font-size:112%;background:white;border:solid 1px silver;padding:8px"> <div class="mw-highlight mw-highlight-lang-html mw-content-ltr" dir="ltr"><pre><span></span><span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>Holidays<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;//tools-static.wmflabs.org/fontcdn/css?family=Material+Icons&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;content bg-secondary rounded m-auto&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;title-bar bg-primary-dark text-white pl-2&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">small</span><span class="p">&gt;</span>Holidays and observances<span class="p">&lt;/</span><span class="nt">small</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;header-bar bg-primary text-white shadow p-2&quot;</span><span class="p">&gt;</span> {% if request.path&#160;!= url_for(&#39;list_holidays&#39;)&#160;%} <span class="p">&lt;</span><span class="nt">a</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot; btn text-white&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;{{ url_for(&#39;list_holidays&#39;) }}&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">i</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;material-icons&quot;</span><span class="p">&gt;</span>arrow_back<span class="p">&lt;/</span><span class="nt">i</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> {% endif&#160;%} <span class="p">&lt;</span><span class="nt">h5</span><span class="p">&gt;</span>{{header}}<span class="p">&lt;/</span><span class="nt">h5</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;filler&quot;</span><span class="p">&gt;&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">a</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;btn text-white&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;{{ url_for(&#39;add&#39;) }}&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">i</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;material-icons&quot;</span><span class="p">&gt;</span>add<span class="p">&lt;/</span><span class="nt">i</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">a</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;btn text-white&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;{{ url_for(&#39;search&#39;) }}&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">i</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;material-icons&quot;</span><span class="p">&gt;</span>search<span class="p">&lt;/</span><span class="nt">i</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> {% with messages = get_flashed_messages()&#160;%} {% if messages&#160;%} <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;alert alert-primary mb-0&quot;</span> <span class="na">role</span><span class="o">=</span><span class="s">&quot;alert&quot;</span><span class="p">&gt;</span> {% for message in messages&#160;%} {{ message }} {% endfor&#160;%} <span class="p">&lt;</span><span class="nt">button</span> <span class="na">type</span><span class="o">=</span><span class="s">&quot;button&quot;</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;close&quot;</span> <span class="na">data-dismiss</span><span class="o">=</span><span class="s">&quot;alert&quot;</span> <span class="na">aria-label</span><span class="o">=</span><span class="s">&quot;Close&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">span</span> <span class="na">aria-hidden</span><span class="o">=</span><span class="s">&quot;true&quot;</span><span class="p">&gt;</span>×<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> {% endif&#160;%} {% endwith&#160;%} {% block content&#160;%}{% endblock&#160;%} <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&quot;//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js&quot;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </pre></div> </td></tr></tbody></table></div> <p>Other pages will extend <code>layout.html</code> using the code below: </p> <div class="mw-highlight mw-highlight-lang-html mw-content-ltr" dir="ltr"><pre><span></span>{% extends &quot;layout.html&quot;&#160;%} {% block content&#160;%} <span class="cm">&lt;!--content for other pages--&gt;</span> {% endblock&#160;%} </pre></div> <div class="mw-heading mw-heading3"><h3 id="Step_4:_List_holidays">Step 4: List holidays</h3></div> <p>The root url of the app will trigger the <code>list_holidays(...)</code> function, which lists holidays for a certain date. </p><p>In the function and throughout the app, <code>holidays_date</code> refers to the date of the holidays to be listed, <code>header</code> refers to the title of the page, and <code>holidays_html</code> refers to the html which contains the holidays to be listed. We'll also be using the <code>render_template(...)</code> 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. </p><p>In <code>app.py</code>, update <code>list_holidays()</code> with the code below: </p> <div class="mw-highlight mw-highlight-lang-python3 mw-content-ltr" dir="ltr"><pre><span></span><span class="nd">@APP</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="s1">&#39;POST&#39;</span><span class="p">])</span> <span class="nd">@APP</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s1">&#39;/&lt;holidays_date&gt;&#39;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="s1">&#39;POST&#39;</span><span class="p">])</span> <span class="k">def</span> <span class="nf">list_holidays</span><span class="p">(</span><span class="n">holidays_date</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> <span class="n">holidays_html</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span> <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">&quot;index.html&quot;</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="n">holidays_date</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;_&#39;</span><span class="p">,</span> <span class="s1">&#39; &#39;</span><span class="p">),</span> <span class="n">holidays_html</span><span class="o">=</span><span class="n">holidays_html</span><span class="p">)</span> </pre></div> <div style="display:block;margin-left:0;"><table class="mw-collapsible mw-collapsed" style="margin-top:.2em; border:1px solid silver;text-align:left; width: 100%;"><tbody><tr><th style="font-size:112%;background:#F8FCFF;color:black;text-align:center">$HOME/holidays-viewer/templates/index.html</th></tr><tr><td style="font-size:112%;background:white;border:solid 1px silver;padding:8px"> <div class="mw-highlight mw-highlight-lang-html mw-content-ltr" dir="ltr"><pre><span></span>{% extends &quot;layout.html&quot;&#160;%} {% block content&#160;%} <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;holidays-html&quot;</span><span class="p">&gt;</span> {{holidays_html|safe}} <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> {% endblock&#160;%} </pre></div> </td></tr></tbody></table></div> <div class="mw-heading mw-heading4"><h4 id="Get_today's_date"><span id="Get_today.27s_date"></span>Get today's date</h4></div> <p>If no date is specified, we'll list holidays for today's date. To use Python's <a rel="nofollow" class="external text" href="https://docs.python.org/3/library/datetime.html">datetime</a> module to get today's date, import the module with <code>from datetime import datetime</code> then create the following function: </p> <div class="mw-highlight mw-highlight-lang-python3 mw-content-ltr" dir="ltr"><pre><span></span><span class="k">def</span> <span class="nf">get_todays_date</span><span class="p">():</span> <span class="n">current_month</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">&#39;%B&#39;</span><span class="p">)</span> <span class="n">current_day</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">&#39;</span><span class="si">%d</span><span class="s1">&#39;</span><span class="p">)</span> <span class="k">if</span> <span class="n">current_day</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;0&#39;</span><span class="p">):</span> <span class="n">current_day</span> <span class="o">=</span> <span class="n">current_day</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;0&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="k">return</span> <span class="n">current_month</span> <span class="o">+</span> <span class="s2">&quot;_&quot;</span> <span class="o">+</span> <span class="n">current_day</span> </pre></div> <p>Call the function in <code>list_holidays(...)</code>: </p> <div class="mw-highlight mw-highlight-lang-python3 mw-content-ltr" dir="ltr"><pre><span></span><span class="k">if</span> <span class="n">holidays_date</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">holidays_date</span> <span class="o">=</span> <span class="n">get_todays_date</span><span class="p">()</span> </pre></div> <div class="mw-heading mw-heading4"><h4 id="Get_the_holidays_to_be_listed">Get the holidays to be listed</h4></div> <p>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 "Holidays and observances". To get the holidays, we need to get its section number and the content in that section number. </p><p>Create a function to get the section number using <a href="/wiki/Special:MyLanguage/API:Parse" title="Special:MyLanguage/API:Parse">API:Parse</a><span style="display:none"><a href="/wiki/API:Parse" class="mw-redirect" title="API:Parse"> </a></span>: </p> <div class="mw-highlight mw-highlight-lang-python3 mw-content-ltr" dir="ltr"><pre><span></span><span class="k">def</span> <span class="nf">get_holidays_section</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">page</span><span class="p">,</span> <span class="n">date_to_get</span><span class="p">):</span> <span class="n">params</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;format&quot;</span><span class="p">:</span><span class="s2">&quot;json&quot;</span><span class="p">,</span> <span class="s2">&quot;action&quot;</span><span class="p">:</span><span class="s2">&quot;parse&quot;</span><span class="p">,</span> <span class="s2">&quot;prop&quot;</span><span class="p">:</span><span class="s2">&quot;sections&quot;</span><span class="p">,</span> <span class="s2">&quot;page&quot;</span><span class="p">:</span><span class="n">page</span> <span class="p">}</span> <span class="n">response</span> <span class="o">=</span> <span class="n">S</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="n">url</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">)</span> <span class="n">data</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span> <span class="n">sections</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s1">&#39;parse&#39;</span><span class="p">][</span><span class="s1">&#39;sections&#39;</span><span class="p">]</span> <span class="n">section_number</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">sections</span><span class="p">):</span> <span class="k">if</span> <span class="n">value</span><span class="p">[</span><span class="s1">&#39;anchor&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;Holidays_and_observances&quot;</span><span class="p">:</span> <span class="n">section_number</span> <span class="o">=</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">url</span> <span class="o">==</span> <span class="n">TEST_URL</span><span class="p">:</span> <span class="k">if</span> <span class="n">value</span><span class="p">[</span><span class="s1">&#39;anchor&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="n">date_to_get</span><span class="p">:</span> <span class="n">section_number</span> <span class="o">=</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">return</span> <span class="n">section_number</span> </pre></div> <p>Create a function called <code>get_holidays(...)</code> to get the holidays in that section using <a href="/wiki/Special:MyLanguage/API:Parse" title="Special:MyLanguage/API:Parse">API:Parse</a><span style="display:none"><a href="/wiki/API:Parse" class="mw-redirect" title="API:Parse"> </a></span> as well, then call the functions in <code>list_holidays(...)</code>: </p> <div class="mw-highlight mw-highlight-lang-python3 mw-content-ltr" dir="ltr"><pre><span></span><span class="n">section_number</span> <span class="o">=</span> <span class="n">get_holidays_section</span><span class="p">(</span><span class="n">URL</span><span class="p">,</span> <span class="n">holidays_date</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="n">holidays</span> <span class="o">=</span> <span class="n">get_holidays</span><span class="p">(</span><span class="n">URL</span><span class="p">,</span> <span class="n">holidays_date</span><span class="p">,</span> <span class="n">section_number</span><span class="p">)</span> <span class="n">holidays_html</span> <span class="o">=</span> <span class="n">holidays</span> </pre></div> <div class="mw-heading mw-heading4"><h4 id="Update_holiday_links">Update holiday links</h4></div> <p>The HTML of the holidays returned contains <a href="/wiki/Special:MyLanguage/Help:Links#Internal_links" title="Special:MyLanguage/Help:Links">internal links</a> that point to those holidays, e.g "<code>/wiki/New_Years_Day</code>". We need to prepend "<code>//en.wikipedia.org</code>" to these links using jQuery to make them external links in our app, and make them open in a new tab. To do that, add the following code to <code>$HOME/holidays-viewer/static/update-links.js</code>: </p> <div class="mw-highlight mw-highlight-lang-javascript mw-content-ltr" dir="ltr"><pre><span></span><span class="nx">$</span><span class="p">(</span><span class="w"> </span><span class="nb">document</span><span class="w"> </span><span class="p">).</span><span class="nx">ready</span><span class="p">(</span><span class="w"> </span><span class="kd">function</span><span class="p">()</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="nx">$</span><span class="p">(</span><span class="w"> </span><span class="s2">&quot;.holidays-html a&quot;</span><span class="w"> </span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="w"> </span><span class="s2">&quot;target&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;_blank&quot;</span><span class="w"> </span><span class="p">);</span> <span class="w"> </span><span class="nx">$</span><span class="p">(</span><span class="w"> </span><span class="s2">&quot;.holidays-html a&quot;</span><span class="w"> </span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="w"> </span><span class="s2">&quot;href&quot;</span><span class="p">,</span><span class="w"> </span><span class="kd">function</span><span class="p">(</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">href</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="s2">&quot;//en.wikipedia.org&quot;</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">href</span><span class="p">;</span> <span class="w"> </span><span class="p">});</span> <span class="p">});</span> </pre></div> <p>Then add jQuery to <code>layout.html</code> using: </p> <div class="mw-highlight mw-highlight-lang-javascript mw-content-ltr" dir="ltr"><pre><span></span><span class="o">&lt;</span><span class="nx">script</span><span class="w"> </span><span class="nx">src</span><span class="o">=</span><span class="s2">&quot;//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.4.1/jquery.min.js&quot;</span><span class="o">&gt;&lt;</span><span class="err">/script&gt;</span> <span class="o">&lt;</span><span class="nx">script</span><span class="w"> </span><span class="nx">src</span><span class="o">=</span><span class="s2">&quot;static/update-links.js&quot;</span><span class="o">&gt;&lt;</span><span class="err">/script&gt;</span> </pre></div> <p><br /> </p> <div class="mw-heading mw-heading3"><h3 id="Step_5:_Search_for_holidays_of_other_dates">Step 5: Search for holidays of other dates</h3></div> <p>To get holidays for other dates, create a search route to display a form that collects the month and day to search for: </p> <div class="mw-highlight mw-highlight-lang-python3 mw-content-ltr" dir="ltr"><pre><span></span><span class="nd">@APP</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/search&quot;</span><span class="p">)</span> <span class="k">def</span> <span class="nf">search</span><span class="p">():</span> <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">&quot;search.html&quot;</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="s2">&quot;Search date&quot;</span><span class="p">)</span> </pre></div> <div style="display:block;margin-left:0;"><table class="mw-collapsible mw-collapsed" style="margin-top:.2em; border:1px solid silver;text-align:left; width: 100%;"><tbody><tr><th style="font-size:112%;background:#F8FCFF;color:black;text-align:center">$HOME/holidays-viewer/templates/search.html</th></tr><tr><td style="font-size:112%;background:white;border:solid 1px silver;padding:8px"> <div class="mw-highlight mw-highlight-lang-html mw-content-ltr" dir="ltr"><pre><span></span>{% extends &quot;layout.html&quot;&#160;%} {% block content&#160;%} <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;instructions m-3&quot;</span><span class="p">&gt;</span> Search for holidays by date <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;base rounded shadow bg-white m-3&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">form</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;m-auto&quot;</span> <span class="na">action</span><span class="o">=</span><span class="s">&quot;/&quot;</span> <span class="na">method</span><span class="o">=</span><span class="s">&quot;POST&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">fieldset</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;label-field&quot;</span><span class="p">&gt;</span>Select Month<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">select</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;bg-secondary mb-5 border-0&quot;</span> <span class="na">name</span><span class="o">=</span><span class="s">&quot;monthList&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;January&quot;</span><span class="p">&gt;</span>January <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;February&quot;</span><span class="p">&gt;</span>February <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;March&quot;</span><span class="p">&gt;</span>March <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;April&quot;</span><span class="p">&gt;</span>April <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;May&quot;</span><span class="p">&gt;</span>May <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;June&quot;</span><span class="p">&gt;</span>June <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;July&quot;</span><span class="p">&gt;</span>July <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;August&quot;</span><span class="p">&gt;</span>August <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;September&quot;</span><span class="p">&gt;</span>September <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;October&quot;</span><span class="p">&gt;</span>October <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;November&quot;</span><span class="p">&gt;</span>November <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;December&quot;</span><span class="p">&gt;</span>December <span class="p">&lt;/</span><span class="nt">select</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">fieldset</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">fieldset</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;label-field&quot;</span><span class="p">&gt;</span>Select Day<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">select</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;bg-secondary mb-5 border-0&quot;</span> <span class="na">name</span><span class="o">=</span><span class="s">&quot;dayList&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;1&quot;</span><span class="p">&gt;</span>1 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;2&quot;</span><span class="p">&gt;</span>2 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;3&quot;</span><span class="p">&gt;</span>3 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;4&quot;</span><span class="p">&gt;</span>4 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;5&quot;</span><span class="p">&gt;</span>5 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;6&quot;</span><span class="p">&gt;</span>6 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;7&quot;</span><span class="p">&gt;</span>7 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;8&quot;</span><span class="p">&gt;</span>8 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;9&quot;</span><span class="p">&gt;</span>9 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;10&quot;</span><span class="p">&gt;</span>10 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;11&quot;</span><span class="p">&gt;</span>11 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;12&quot;</span><span class="p">&gt;</span>12 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;13&quot;</span><span class="p">&gt;</span>13 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;14&quot;</span><span class="p">&gt;</span>14 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;15&quot;</span><span class="p">&gt;</span>15 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;16&quot;</span><span class="p">&gt;</span>16 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;17&quot;</span><span class="p">&gt;</span>17 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;18&quot;</span><span class="p">&gt;</span>18 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;19&quot;</span><span class="p">&gt;</span>19 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;20&quot;</span><span class="p">&gt;</span>20 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;21&quot;</span><span class="p">&gt;</span>21 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;22&quot;</span><span class="p">&gt;</span>22 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;23&quot;</span><span class="p">&gt;</span>23 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;24&quot;</span><span class="p">&gt;</span>24 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;25&quot;</span><span class="p">&gt;</span>25 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;26&quot;</span><span class="p">&gt;</span>26 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;27&quot;</span><span class="p">&gt;</span>27 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;28&quot;</span><span class="p">&gt;</span>28 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;29&quot;</span><span class="p">&gt;</span>29 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;30&quot;</span><span class="p">&gt;</span>30 <span class="p">&lt;</span><span class="nt">option</span> <span class="na">value</span><span class="o">=</span><span class="s">&quot;31&quot;</span><span class="p">&gt;</span>31 <span class="p">&lt;/</span><span class="nt">select</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">fieldset</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">button</span> <span class="na">type</span><span class="o">=</span><span class="s">&quot;submit&quot;</span> <span class="na">name</span><span class="o">=</span><span class="s">&quot;search&quot;</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;bg-primary btn btn-submit text-white&quot;</span><span class="p">&gt;</span>Submit<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">form</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> {% endblock&#160;%} </pre></div> </td></tr></tbody></table></div> <p>Once the search form has been submitted, update <code>holidays_date</code> to be the date that has been entered. To do that, add the following code to <code>list_holidays(...)</code>: </p> <div class="mw-highlight mw-highlight-lang-python3 mw-content-ltr" dir="ltr"><pre><span></span><span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s1">&#39;POST&#39;</span> <span class="ow">and</span> <span class="s1">&#39;search&#39;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">:</span> <span class="n">search_month</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;monthList&#39;</span><span class="p">))</span> <span class="n">search_day</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;dayList&#39;</span><span class="p">))</span> <span class="n">holidays_date</span> <span class="o">=</span> <span class="n">search_month</span> <span class="o">+</span><span class="s2">&quot;_&quot;</span><span class="o">+</span><span class="n">search_day</span> </pre></div> <div class="mw-heading mw-heading3"><h3 id="Step_6:_Add_a_holiday">Step 6: Add a holiday</h3></div> <p>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 <a href="/wiki/Special:MyLanguage/API:Login#clientlogin" title="Special:MyLanguage/API:Login">API:Login#clientlogin</a> first. </p><p>To add a holiday, send a request to <a href="/wiki/Special:MyLanguage/API:Edit" title="Special:MyLanguage/API:Edit">API:Edit</a><span style="display:none"><a href="/wiki/API:Edit" title="API:Edit"> </a></span> with the date and description of the holiday. The edit adds new holidays to this page on Test Wikipedia: <a class="external text" href="https://test.wikipedia.org/wiki/Sandbox/Holidays_and_observances">Sandbox/Holidays_and_observances</a>. This is to prevent adding test holidays to English Wikipedia. </p><p>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 <code>list_holidays(...)</code>: </p> <div class="mw-highlight mw-highlight-lang-javascript mw-content-ltr" dir="ltr"><pre><span></span><span class="nx">test_section_number</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">get_holidays_section</span><span class="p">(</span><span class="nx">TEST_URL</span><span class="p">,</span><span class="w"> </span><span class="nx">TEST_PAGE</span><span class="p">,</span><span class="w"> </span><span class="nx">holidays_date</span><span class="p">)</span> <span class="nx">test_holidays</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">get_holidays</span><span class="p">(</span><span class="nx">TEST_URL</span><span class="p">,</span><span class="w"> </span><span class="nx">TEST_PAGE</span><span class="p">,</span><span class="w"> </span><span class="nx">test_section_number</span><span class="p">)</span> <span class="nx">holidays_html</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">test_holidays</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">holidays</span> <span class="nx">flash</span><span class="p">(</span><span class="s2">&quot;Holidays added through this app are in bold&quot;</span><span class="p">)</span> </pre></div> <div style="display:block;margin-left:0;"><table class="mw-collapsible mw-collapsed" style="margin-top:.2em; border:1px solid silver;text-align:left; width: 100%;"><tbody><tr><th style="font-size:112%;background:#F8FCFF;color:black;text-align:center">$HOME/holidays-viewer/templates/login.html</th></tr><tr><td style="font-size:112%;background:white;border:solid 1px silver;padding:8px"> <div class="mw-highlight mw-highlight-lang-html mw-content-ltr" dir="ltr"><pre><span></span>{% extends &quot;layout.html&quot;&#160;%} {% block content&#160;%} <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;instructions m-3&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>You need to login to Wikipedia in order to add a new holiday <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;base rounded shadow bg-white m-3&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">form</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;m-auto&quot;</span> <span class="na">action</span><span class="o">=</span><span class="s">&quot;/login&quot;</span> <span class="na">method</span><span class="o">=</span><span class="s">&quot;POST&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;form-group&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;form-field&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;label-field&quot;</span><span class="p">&gt;</span>Username<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">input</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;bg-secondary mb-5 border-0&quot;</span> <span class="na">name</span><span class="o">=</span><span class="s">&quot;username&quot;</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;form-field&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;label-field&quot;</span><span class="p">&gt;</span>Password<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">input</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;bg-secondary mb-5 border-0&quot;</span> <span class="na">type</span><span class="o">=</span><span class="s">&quot;password&quot;</span> <span class="na">name</span><span class="o">=</span><span class="s">&quot;password&quot;</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">button</span> <span class="na">type</span><span class="o">=</span><span class="s">&quot;submit&quot;</span> <span class="na">name</span><span class="o">=</span><span class="s">&quot;login&quot;</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;bg-primary btn btn-submit text-white&quot;</span><span class="p">&gt;</span>Login<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">form</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> {% endblock&#160;%} </pre></div> </td></tr></tbody></table></div> <div style="display:block;margin-left:0;"><table class="mw-collapsible mw-collapsed" style="margin-top:.2em; border:1px solid silver;text-align:left; width: 100%;"><tbody><tr><th style="font-size:112%;background:#F8FCFF;color:black;text-align:center">$HOME/holidays-viewer/templates/add.html</th></tr><tr><td style="font-size:112%;background:white;border:solid 1px silver;padding:8px"> <div class="mw-highlight mw-highlight-lang-html mw-content-ltr" dir="ltr"><pre><span></span>{% extends &quot;layout.html&quot;&#160;%} {% block content&#160;%} <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;instructions m-3&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Add a new test holiday <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;base rounded shadow bg-white m-3&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">form</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;m-auto&quot;</span> <span class="na">action</span><span class="o">=</span><span class="s">&quot;&quot;</span> <span class="na">method</span><span class="o">=</span><span class="s">&quot;POST&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;form-group&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;form-field&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;label-field&quot;</span><span class="p">&gt;</span>Date [MMMM dd]<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">input</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;bg-secondary border-0 mb-5&quot;</span> <span class="na">name</span><span class="o">=</span><span class="s">&quot;date&quot;</span> <span class="na">placeholder</span><span class="o">=</span><span class="s">&quot;e.g April 1&quot;</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;form-field&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;label-field&quot;</span><span class="p">&gt;</span>Description<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">input</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;bg-secondary border-0 mb-5&quot;</span> <span class="na">name</span><span class="o">=</span><span class="s">&quot;description&quot;</span> <span class="na">placeholder</span><span class="o">=</span><span class="s">&quot;e.g April fools&#39; day&quot;</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">button</span> <span class="na">type</span><span class="o">=</span><span class="s">&quot;submit&quot;</span> <span class="na">name</span><span class="o">=</span><span class="s">&quot;add&quot;</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;bg-primary btn btn-submit text-white&quot;</span><span class="p">&gt;</span>Add<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">form</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> {% endblock&#160;%} </pre></div> </td></tr></tbody></table></div> <div class="mw-heading mw-heading3"><h3 id="Step_7:_Styling_the_app">Step 7: Styling the app</h3></div> <p>To add more style to our app, create a stylesheet named <code>style.css</code> and link to it from <code>layout.html</code> by adding <code class="mw-highlight mw-highlight-lang-html mw-content-ltr" dir="ltr"><span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;static/style.css&quot;</span><span class="p">&gt;</span></code>. </p> <div style="display:block;margin-left:0;"><table class="mw-collapsible mw-collapsed" style="margin-top:.2em; border:1px solid silver;text-align:left; width: 100%;"><tbody><tr><th style="font-size:112%;background:#F8FCFF;color:black;text-align:center">$HOME/holidays-viewer/static/style.css</th></tr><tr><td style="font-size:112%;background:white;border:solid 1px silver;padding:8px"> <div class="mw-highlight mw-highlight-lang-css mw-content-ltr" dir="ltr"><pre><span></span><span class="p">.</span><span class="nc">content</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">width</span><span class="p">:</span><span class="w"> </span><span class="mi">420</span><span class="kt">px</span><span class="p">;</span> <span class="w"> </span><span class="k">min-height</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="kt">vh</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">holidays-html</span><span class="p">{</span> <span class="w"> </span><span class="k">overflow-y</span><span class="p">:</span><span class="w"> </span><span class="kc">auto</span><span class="p">;</span> <span class="w"> </span><span class="k">overflow-x</span><span class="p">:</span><span class="w"> </span><span class="kc">hidden</span><span class="p">;</span> <span class="w"> </span><span class="k">max-height</span><span class="p">:</span><span class="w"> </span><span class="mi">88</span><span class="kt">vh</span><span class="p">;</span> <span class="w"> </span><span class="k">scrollbar-width</span><span class="p">:</span><span class="w"> </span><span class="kc">thin</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">base</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">height</span><span class="p">:</span><span class="w"> </span><span class="mi">400</span><span class="kt">px</span><span class="p">;</span> <span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">flex</span><span class="p">;</span> <span class="p">}</span> <span class="nt">input</span><span class="o">,</span><span class="w"> </span><span class="nt">select</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">width</span><span class="p">:</span><span class="w"> </span><span class="mi">300</span><span class="kt">px</span><span class="p">;</span> <span class="w"> </span><span class="k">height</span><span class="p">:</span><span class="w"> </span><span class="mi">40</span><span class="kt">px</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">btn-submit</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">width</span><span class="p">:</span><span class="w"> </span><span class="mi">300</span><span class="kt">px</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">btn</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">cursor</span><span class="p">:</span><span class="w"> </span><span class="kc">pointer</span><span class="p">;</span> <span class="w"> </span><span class="k">align-content</span><span class="p">:</span><span class="w"> </span><span class="kc">center</span><span class="p">;</span> <span class="w"> </span><span class="k">background-color</span><span class="p">:</span><span class="w"> </span><span class="kc">transparent</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">bg-primary</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">background-color</span><span class="p">:</span><span class="w"> </span><span class="mh">#36c</span><span class="w"> </span><span class="cp">!important</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">bg-primary-dark</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">background-color</span><span class="p">:</span><span class="w"> </span><span class="mh">#2a4b8d</span><span class="w"> </span><span class="cp">!important</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">bg-secondary</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">background-color</span><span class="p">:</span><span class="w"> </span><span class="mh">#eaecf0</span><span class="w"> </span><span class="cp">!important</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">header-bar</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">height</span><span class="p">:</span><span class="w"> </span><span class="mi">48</span><span class="kt">px</span><span class="p">;</span> <span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">flex</span><span class="p">;</span> <span class="w"> </span><span class="k">flex</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span> <span class="w"> </span><span class="k">align-items</span><span class="p">:</span><span class="w"> </span><span class="kc">center</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">filler</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">flex-grow</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span> <span class="w"> </span><span class="k">text-align</span><span class="p">:</span><span class="w"> </span><span class="kc">center</span> <span class="p">}</span> <span class="nt">h2</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">none</span><span class="p">;</span> <span class="p">}</span> <span class="nt">ul</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">margin</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="kt">px</span><span class="p">;</span> <span class="w"> </span><span class="k">padding</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="nt">li</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">list-style-type</span><span class="p">:</span><span class="w"> </span><span class="kc">none</span><span class="p">;</span> <span class="w"> </span><span class="k">margin-bottom</span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="kt">px</span><span class="p">;</span> <span class="w"> </span><span class="k">background-color</span><span class="p">:</span><span class="w"> </span><span class="kc">white</span><span class="p">;</span> <span class="w"> </span><span class="k">padding</span><span class="p">:</span><span class="w"> </span><span class="mi">8</span><span class="kt">px</span><span class="p">;</span> <span class="w"> </span><span class="k">border-radius</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="kt">px</span><span class="p">;</span> <span class="p">}</span> <span class="nt">ul</span><span class="w"> </span><span class="nt">li</span><span class="w"> </span><span class="nt">li</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="k">box-shadow</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="mf">.5</span><span class="kt">rem</span><span class="w"> </span><span class="mi">1</span><span class="kt">rem</span><span class="w"> </span><span class="nb">rgba</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mf">.15</span><span class="p">);</span> <span class="p">}</span> </pre></div> </td></tr></tbody></table></div> <div class="mw-heading mw-heading2"><h2 id="Application_layout">Application layout</h2></div> <p>At this point, the structure of your app should be: </p> <pre>$HOME/holidays-viewer ├── templates/ │ └── add.html └── index.html └── layout.html └── login.html └── search.html ├── static/ │ └── style.css └── update-links.js ├── app.py </pre> <p>With <code>app.py</code> and <code>layout.html</code> being: </p> <div style="display:block;margin-left:0;"><table class="mw-collapsible mw-collapsed" style="margin-top:.2em; border:1px solid silver;text-align:left; width: 100%;"><tbody><tr><th style="font-size:112%;background:#F8FCFF;color:black;text-align:center">$HOME/holidays-viewer/app.py</th></tr><tr><td style="font-size:112%;background:white;border:solid 1px silver;padding:8px"> <div class="mw-highlight mw-highlight-lang-python3 mw-content-ltr" dir="ltr"><pre><span></span><span class="ch">#!/usr/bin/python3</span> <span class="sd">&quot;&quot;&quot;</span> <span class="sd"> app.py</span> <span class="sd"> MediaWiki API Demos</span> <span class="sd"> Holidays viewer: A demo app that fetches the day&#39;s holidays from Wikipedia with options to search for holidays of other dates, and login to add new holidays.</span> <span class="sd"> MIT license</span> <span class="sd">&quot;&quot;&quot;</span> <span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span> <span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">render_template</span><span class="p">,</span> <span class="n">flash</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">url_for</span><span class="p">,</span> <span class="n">redirect</span> <span class="kn">import</span> <span class="nn">requests</span> <span class="n">APP</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span> <span class="n">APP</span><span class="o">.</span><span class="n">secret_key</span> <span class="o">=</span> <span class="s1">&#39;your_secret_key&#39;</span> <span class="n">URL</span> <span class="o">=</span> <span class="s2">&quot;https://en.wikipedia.org/w/api.php&quot;</span> <span class="n">TEST_URL</span> <span class="o">=</span> <span class="s2">&quot;https://test.wikipedia.org/w/api.php&quot;</span> <span class="n">TEST_PAGE</span> <span class="o">=</span> <span class="s2">&quot;Sandbox/Holidays_and_observances&quot;</span> <span class="n">S</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">Session</span><span class="p">()</span> <span class="n">IS_LOGGED_IN</span> <span class="o">=</span> <span class="kc">False</span> <span class="nd">@APP</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="s1">&#39;POST&#39;</span><span class="p">])</span> <span class="nd">@APP</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s1">&#39;/&lt;holidays_date&gt;&#39;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="s1">&#39;POST&#39;</span><span class="p">])</span> <span class="k">def</span> <span class="nf">list_holidays</span><span class="p">(</span><span class="n">holidays_date</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot; Lists holidays for the current date or a custom date</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">if</span> <span class="n">holidays_date</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">holidays_date</span> <span class="o">=</span> <span class="n">get_todays_date</span><span class="p">()</span> <span class="c1"># Update date to a custom date</span> <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s1">&#39;POST&#39;</span> <span class="ow">and</span> <span class="s1">&#39;search&#39;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">:</span> <span class="n">search_month</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;monthList&#39;</span><span class="p">))</span> <span class="n">search_day</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;dayList&#39;</span><span class="p">))</span> <span class="n">holidays_date</span> <span class="o">=</span> <span class="n">search_month</span> <span class="o">+</span><span class="s2">&quot;_&quot;</span><span class="o">+</span><span class="n">search_day</span> <span class="c1"># Get the section numbers for the holidays on Wikipedia and for those on the test page</span> <span class="n">section_number</span> <span class="o">=</span> <span class="n">get_holidays_section</span><span class="p">(</span><span class="n">URL</span><span class="p">,</span> <span class="n">holidays_date</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="n">test_section_number</span> <span class="o">=</span> <span class="n">get_holidays_section</span><span class="p">(</span><span class="n">TEST_URL</span><span class="p">,</span> <span class="n">TEST_PAGE</span><span class="p">,</span> <span class="n">holidays_date</span><span class="p">)</span> <span class="n">holidays</span> <span class="o">=</span> <span class="n">get_holidays</span><span class="p">(</span><span class="n">URL</span><span class="p">,</span> <span class="n">holidays_date</span><span class="p">,</span> <span class="n">section_number</span><span class="p">)</span> <span class="n">test_holidays</span> <span class="o">=</span> <span class="n">get_holidays</span><span class="p">(</span><span class="n">TEST_URL</span><span class="p">,</span> <span class="n">TEST_PAGE</span><span class="p">,</span> <span class="n">test_section_number</span><span class="p">)</span> <span class="n">holidays_html</span> <span class="o">=</span> <span class="n">test_holidays</span> <span class="o">+</span> <span class="n">holidays</span> <span class="n">flash</span><span class="p">(</span><span class="s1">&#39;Holidays added through this app are in bold&#39;</span><span class="p">)</span> <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">&quot;index.html&quot;</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="n">holidays_date</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;_&#39;</span><span class="p">,</span> <span class="s1">&#39; &#39;</span><span class="p">),</span> <span class="n">holidays_html</span><span class="o">=</span><span class="n">holidays_html</span><span class="p">)</span> <span class="k">def</span> <span class="nf">get_todays_date</span><span class="p">():</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot; Get the current month as text and the current day as a number</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="n">current_month</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">&#39;%B&#39;</span><span class="p">)</span> <span class="n">current_day</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s1">&#39;</span><span class="si">%d</span><span class="s1">&#39;</span><span class="p">)</span> <span class="k">if</span> <span class="n">current_day</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">&#39;0&#39;</span><span class="p">):</span> <span class="n">current_day</span> <span class="o">=</span> <span class="n">current_day</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;0&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="k">return</span> <span class="n">current_month</span> <span class="o">+</span> <span class="s2">&quot;_&quot;</span> <span class="o">+</span> <span class="n">current_day</span> <span class="k">def</span> <span class="nf">get_holidays_section</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">page</span><span class="p">,</span> <span class="n">date_to_get</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot; Get the section number for holidays on Wikipedia and holidays on the test page</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="n">params</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;format&quot;</span><span class="p">:</span><span class="s2">&quot;json&quot;</span><span class="p">,</span> <span class="s2">&quot;action&quot;</span><span class="p">:</span><span class="s2">&quot;parse&quot;</span><span class="p">,</span> <span class="s2">&quot;prop&quot;</span><span class="p">:</span><span class="s2">&quot;sections&quot;</span><span class="p">,</span> <span class="s2">&quot;page&quot;</span><span class="p">:</span><span class="n">page</span> <span class="p">}</span> <span class="n">response</span> <span class="o">=</span> <span class="n">S</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="n">url</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">)</span> <span class="n">data</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span> <span class="n">sections</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s1">&#39;parse&#39;</span><span class="p">][</span><span class="s1">&#39;sections&#39;</span><span class="p">]</span> <span class="n">section_number</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">sections</span><span class="p">):</span> <span class="k">if</span> <span class="n">value</span><span class="p">[</span><span class="s1">&#39;anchor&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;Holidays_and_observances&quot;</span><span class="p">:</span> <span class="n">section_number</span> <span class="o">=</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">url</span> <span class="o">==</span> <span class="n">TEST_URL</span><span class="p">:</span> <span class="k">if</span> <span class="n">value</span><span class="p">[</span><span class="s1">&#39;anchor&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="n">date_to_get</span><span class="p">:</span> <span class="n">section_number</span> <span class="o">=</span> <span class="n">index</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">return</span> <span class="n">section_number</span> <span class="k">def</span> <span class="nf">get_holidays</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">page</span><span class="p">,</span> <span class="n">section_number</span><span class="p">):</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot; Get the html which contains holidays</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="n">params</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;format&quot;</span><span class="p">:</span><span class="s2">&quot;json&quot;</span><span class="p">,</span> <span class="s2">&quot;action&quot;</span><span class="p">:</span><span class="s2">&quot;parse&quot;</span><span class="p">,</span> <span class="s2">&quot;prop&quot;</span><span class="p">:</span><span class="s2">&quot;text&quot;</span><span class="p">,</span> <span class="s2">&quot;page&quot;</span><span class="p">:</span> <span class="n">page</span><span class="p">,</span> <span class="s2">&quot;section&quot;</span><span class="p">:</span> <span class="n">section_number</span><span class="p">,</span> <span class="s2">&quot;disableeditsection&quot;</span><span class="p">:</span><span class="mi">1</span> <span class="p">}</span> <span class="n">response</span> <span class="o">=</span> <span class="n">S</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="n">url</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">)</span> <span class="n">data</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span> <span class="n">text</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s1">&#39;parse&#39;</span><span class="p">][</span><span class="s1">&#39;text&#39;</span><span class="p">][</span><span class="s1">&#39;*&#39;</span><span class="p">]</span> <span class="k">return</span> <span class="n">text</span> <span class="nd">@APP</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/search&quot;</span><span class="p">)</span> <span class="k">def</span> <span class="nf">search</span><span class="p">():</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot; Search for holidays of custom dates</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">&quot;search.html&quot;</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="s2">&quot;Search date&quot;</span><span class="p">)</span> <span class="nd">@APP</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/login&quot;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="s1">&#39;POST&#39;</span><span class="p">])</span> <span class="k">def</span> <span class="nf">login</span><span class="p">():</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot; Login to Wikipedia</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s1">&#39;POST&#39;</span> <span class="ow">and</span> <span class="s1">&#39;login&#39;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">:</span> <span class="n">params_0</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;action&quot;</span><span class="p">:</span> <span class="s2">&quot;query&quot;</span><span class="p">,</span> <span class="s2">&quot;meta&quot;</span><span class="p">:</span> <span class="s2">&quot;tokens&quot;</span><span class="p">,</span> <span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;login&quot;</span><span class="p">,</span> <span class="s2">&quot;format&quot;</span><span class="p">:</span> <span class="s2">&quot;json&quot;</span> <span class="p">}</span> <span class="n">response</span> <span class="o">=</span> <span class="n">S</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="n">URL</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params_0</span><span class="p">)</span> <span class="n">data</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span> <span class="n">login_token</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s1">&#39;query&#39;</span><span class="p">][</span><span class="s1">&#39;tokens&#39;</span><span class="p">][</span><span class="s1">&#39;logintoken&#39;</span><span class="p">]</span> <span class="n">params_1</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;action&quot;</span><span class="p">:</span> <span class="s2">&quot;clientlogin&quot;</span><span class="p">,</span> <span class="s2">&quot;username&quot;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;username&#39;</span><span class="p">)),</span> <span class="s2">&quot;password&quot;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;password&#39;</span><span class="p">)),</span> <span class="s2">&quot;loginreturnurl&quot;</span><span class="p">:</span> <span class="s2">&quot;http://127.0.0.1:5000/login&quot;</span><span class="p">,</span> <span class="s2">&quot;logintoken&quot;</span><span class="p">:</span> <span class="n">login_token</span><span class="p">,</span> <span class="s2">&quot;format&quot;</span><span class="p">:</span> <span class="s2">&quot;json&quot;</span> <span class="p">}</span> <span class="n">response</span> <span class="o">=</span> <span class="n">S</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="n">URL</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">params_1</span><span class="p">)</span> <span class="n">data</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span> <span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="s1">&#39;clientlogin&#39;</span><span class="p">][</span><span class="s1">&#39;status&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;PASS&#39;</span><span class="p">:</span> <span class="n">flash</span><span class="p">(</span><span class="s1">&#39;Oops! Something went wrong -- &#39;</span> <span class="o">+</span> <span class="n">data</span><span class="p">[</span><span class="s1">&#39;clientlogin&#39;</span><span class="p">][</span><span class="s1">&#39;messagecode&#39;</span><span class="p">])</span> <span class="k">else</span><span class="p">:</span> <span class="k">global</span> <span class="n">IS_LOGGED_IN</span> <span class="n">IS_LOGGED_IN</span> <span class="o">=</span> <span class="kc">True</span> <span class="n">flash</span><span class="p">(</span><span class="s1">&#39;Login success! Welcome, &#39;</span> <span class="o">+</span> <span class="n">data</span><span class="p">[</span><span class="s1">&#39;clientlogin&#39;</span><span class="p">][</span><span class="s1">&#39;username&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="s1">&#39;!&#39;</span><span class="p">)</span> <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s1">&#39;add&#39;</span><span class="p">))</span> <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">&quot;login.html&quot;</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="s2">&quot;Login&quot;</span><span class="p">)</span> <span class="nd">@APP</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/add&quot;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;GET&#39;</span><span class="p">,</span> <span class="s1">&#39;POST&#39;</span><span class="p">])</span> <span class="k">def</span> <span class="nf">add</span><span class="p">():</span> <span class="w"> </span><span class="sd">&quot;&quot;&quot; Add a new holiday to a test page and redirect to that date&#39;s holidays to show the added holidays</span> <span class="sd"> &quot;&quot;&quot;</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">IS_LOGGED_IN</span><span class="p">:</span> <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s1">&#39;login&#39;</span><span class="p">))</span> <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s1">&#39;POST&#39;</span> <span class="ow">and</span> <span class="s1">&#39;add&#39;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">:</span> <span class="c1"># Wiki markup to format the added holiday&#39;s text as a list item and in bold</span> <span class="n">holiday_text</span> <span class="o">=</span> <span class="s2">&quot;* &#39;&#39;&#39;&quot;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;description&#39;</span><span class="p">))</span> <span class="o">+</span> <span class="s2">&quot;&#39;&#39;&#39;&quot;</span> <span class="n">date</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;date&#39;</span><span class="p">))</span> <span class="n">params_2</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;action&quot;</span><span class="p">:</span> <span class="s2">&quot;query&quot;</span><span class="p">,</span> <span class="s2">&quot;meta&quot;</span><span class="p">:</span> <span class="s2">&quot;tokens&quot;</span><span class="p">,</span> <span class="s2">&quot;format&quot;</span><span class="p">:</span> <span class="s2">&quot;json&quot;</span> <span class="p">}</span> <span class="n">response</span> <span class="o">=</span> <span class="n">S</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="n">TEST_URL</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params_2</span><span class="p">)</span> <span class="n">data</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span> <span class="n">csrf_token</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s1">&#39;query&#39;</span><span class="p">][</span><span class="s1">&#39;tokens&#39;</span><span class="p">][</span><span class="s1">&#39;csrftoken&#39;</span><span class="p">]</span> <span class="n">params_4</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;action&quot;</span><span class="p">:</span> <span class="s2">&quot;edit&quot;</span><span class="p">,</span> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="n">TEST_PAGE</span><span class="p">,</span> <span class="s2">&quot;token&quot;</span><span class="p">:</span> <span class="n">csrf_token</span><span class="p">,</span> <span class="s2">&quot;format&quot;</span><span class="p">:</span> <span class="s2">&quot;json&quot;</span><span class="p">,</span> <span class="s2">&quot;section&quot;</span><span class="p">:</span> <span class="s2">&quot;new&quot;</span><span class="p">,</span> <span class="s2">&quot;sectiontitle&quot;</span><span class="p">:</span> <span class="n">date</span><span class="p">,</span> <span class="s2">&quot;text&quot;</span><span class="p">:</span> <span class="n">holiday_text</span><span class="p">,</span> <span class="p">}</span> <span class="n">response</span> <span class="o">=</span> <span class="n">S</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="n">TEST_URL</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">params_4</span><span class="p">)</span> <span class="n">data</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span> <span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="s1">&#39;edit&#39;</span><span class="p">][</span><span class="s1">&#39;result&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;Success&#39;</span><span class="p">:</span> <span class="n">flash</span><span class="p">(</span><span class="s1">&#39;Oops! Something went wrong -- &#39;</span> <span class="o">+</span> <span class="n">data</span><span class="p">[</span><span class="s1">&#39;clientlogin&#39;</span><span class="p">][</span><span class="s1">&#39;messagecode&#39;</span><span class="p">])</span> <span class="k">else</span><span class="p">:</span> <span class="n">flash</span><span class="p">(</span><span class="s1">&#39;New holiday added successfully!&#39;</span><span class="p">)</span> <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s1">&#39;list_holidays&#39;</span><span class="p">,</span> <span class="n">holidays_date</span><span class="o">=</span><span class="n">date</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;_&#39;</span><span class="p">)))</span> <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">&quot;add.html&quot;</span><span class="p">,</span> <span class="n">header</span><span class="o">=</span><span class="s2">&quot;Add holiday&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span> <span class="n">APP</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> </pre></div> </td></tr></tbody></table></div> <div style="display:block;margin-left:0;"><table class="mw-collapsible mw-collapsed" style="margin-top:.2em; border:1px solid silver;text-align:left; width: 100%;"><tbody><tr><th style="font-size:112%;background:#F8FCFF;color:black;text-align:center">$HOME/holidays-viewer/templates/layout.html</th></tr><tr><td style="font-size:112%;background:white;border:solid 1px silver;padding:8px"> <div class="mw-highlight mw-highlight-lang-html mw-content-ltr" dir="ltr"><pre><span></span><span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>Holidays<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;//tools-static.wmflabs.org/fontcdn/css?family=Material+Icons&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">link</span> <span class="na">rel</span><span class="o">=</span><span class="s">&quot;stylesheet&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;static/style.css&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&quot;//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.4.1/jquery.min.js&quot;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&quot;static/update-links.js&quot;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;content bg-secondary rounded m-auto&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;title-bar bg-primary-dark text-white pl-2&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">small</span><span class="p">&gt;</span>Holidays and observances<span class="p">&lt;/</span><span class="nt">small</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;header-bar bg-primary text-white shadow p-2&quot;</span><span class="p">&gt;</span> {% if request.path&#160;!= url_for(&#39;list_holidays&#39;)&#160;%} <span class="p">&lt;</span><span class="nt">a</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot; btn text-white&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;{{ url_for(&#39;list_holidays&#39;) }}&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">i</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;material-icons&quot;</span><span class="p">&gt;</span>arrow_back<span class="p">&lt;/</span><span class="nt">i</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> {% endif&#160;%} <span class="p">&lt;</span><span class="nt">h5</span><span class="p">&gt;</span>{{header}}<span class="p">&lt;/</span><span class="nt">h5</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;filler&quot;</span><span class="p">&gt;&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">a</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;btn text-white&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;{{ url_for(&#39;add&#39;) }}&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">i</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;material-icons&quot;</span><span class="p">&gt;</span>add<span class="p">&lt;/</span><span class="nt">i</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">a</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;btn text-white&quot;</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;{{ url_for(&#39;search&#39;) }}&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">i</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;material-icons&quot;</span><span class="p">&gt;</span>search<span class="p">&lt;/</span><span class="nt">i</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> {% with messages = get_flashed_messages()&#160;%} {% if messages&#160;%} <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;alert alert-primary mb-0&quot;</span> <span class="na">role</span><span class="o">=</span><span class="s">&quot;alert&quot;</span><span class="p">&gt;</span> {% for message in messages&#160;%} {{ message }} {% endfor&#160;%} <span class="p">&lt;</span><span class="nt">button</span> <span class="na">type</span><span class="o">=</span><span class="s">&quot;button&quot;</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;close&quot;</span> <span class="na">data-dismiss</span><span class="o">=</span><span class="s">&quot;alert&quot;</span> <span class="na">aria-label</span><span class="o">=</span><span class="s">&quot;Close&quot;</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">span</span> <span class="na">aria-hidden</span><span class="o">=</span><span class="s">&quot;true&quot;</span><span class="p">&gt;</span>×<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> {% endif&#160;%} {% endwith&#160;%} {% block content&#160;%}{% endblock&#160;%} <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&quot;//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js&quot;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span> </pre></div> </td></tr></tbody></table></div> <figure class="mw-default-size" typeof="mw:File/Thumb"><a href="/wiki/File:List-holidays.png" class="mw-file-description"><img src="//upload.wikimedia.org/wikipedia/commons/thumb/9/96/List-holidays.png/220px-List-holidays.png" decoding="async" width="220" height="323" class="mw-file-element" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/9/96/List-holidays.png/330px-List-holidays.png 1.5x, //upload.wikimedia.org/wikipedia/commons/9/96/List-holidays.png 2x" data-file-width="420" data-file-height="616" /></a><figcaption>Holidays viewer homepage screenshot</figcaption></figure> <div class="mw-heading mw-heading2"><h2 id="Next_steps">Next steps</h2></div> <ul><li>Contribute a demo app that you have developed using the MediaWiki API to this <a rel="nofollow" class="external text" href="https://github.com/wikimedia/MediaWiki-Action-API-Code-Samples">code samples repository</a>.</li></ul> <div class="mw-heading mw-heading2"><h2 id="See_also">See also</h2></div> <ul><li><a href="/wiki/Special:MyLanguage/API:Main_page" title="Special:MyLanguage/API:Main page">API:Main page</a><span style="display:none"><a href="/wiki/API:Main_page" title="API:Main page"> </a></span> — The quick start guide for the MediaWiki Action API.</li> <li><a href="/wiki/Special:MyLanguage/API:Parsing_wikitext" title="Special:MyLanguage/API:Parsing wikitext">API:Parsing wikitext</a><span style="display:none"><a href="/wiki/API:Parsing_wikitext" title="API:Parsing wikitext"> </a></span> — Parses the content of a page and obtain the output.</li> <li><a href="/wiki/Special:MyLanguage/API:Edit" title="Special:MyLanguage/API:Edit">API:Edit</a><span style="display:none"><a href="/wiki/API:Edit" title="API:Edit"> </a></span> — Edits a page.</li> <li><a href="/wiki/Special:MyLanguage/API:Login" title="Special:MyLanguage/API:Login">API:Login</a><span style="display:none"><a href="/wiki/API:Login" title="API:Login"> </a></span> — Allows logging in to a wiki.</li></ul> <!-- NewPP limit report Parsed by mw‐web.eqiad.main‐59856bd7d8‐tnlrh Cached time: 20241119180755 Cache expiry: 2592000 Reduced expiry: false Complications: [show‐toc] CPU time usage: 0.591 seconds Real time usage: 1.913 seconds Preprocessor visited node count: 4791/1000000 Post‐expand include size: 52138/2097152 bytes Template argument size: 23052/2097152 bytes Highest expansion depth: 15/100 Expensive parser function count: 44/500 Unstrip recursion depth: 0/20 Unstrip post‐expand size: 93693/5000000 bytes Lua time usage: 0.119/10.000 seconds Lua memory usage: 1400885/52428800 bytes Number of Wikibase entities loaded: 0/400 --> <!-- Transclusion expansion time report (%,ms,calls,template) 100.00% 1608.693 1 -total 15.28% 245.757 1 Template:API 12.51% 201.219 60 Template:Ll 11.95% 192.161 1 Template:Sidebar 7.40% 119.109 77 Template:Pagelang 7.29% 117.249 120 Template:Translatable 2.87% 46.093 1 Template:Mbox 2.61% 42.058 8 Template:Collapse_top 1.53% 24.593 19 Template:Dir 1.09% 17.549 7 Template:TNTN --> <!-- Saved in parser cache with key mediawikiwiki:pcache:969509:|#|:idhash:canonical and timestamp 20241119180755 and revision id 6749968. Rendering was triggered because: page-view --> </div><!--esi <esi:include src="/esitest-fa8a495983347898/content" /> --><noscript><img src="https://login.wikimedia.org/wiki/Special:CentralAutoLogin/start?type=1x1" alt="" width="1" height="1" style="border: none; position: absolute;"></noscript> <div class="printfooter" data-nosnippet="">Retrieved from "<a dir="ltr" href="https://www.mediawiki.org/w/index.php?title=API:Holidays_viewer&amp;oldid=6749968">https://www.mediawiki.org/w/index.php?title=API:Holidays_viewer&amp;oldid=6749968</a>"</div></div> <div id="catlinks" class="catlinks" data-mw="interface"><div id="mw-normal-catlinks" class="mw-normal-catlinks"><a href="/wiki/Special:Categories" title="Special:Categories">Category</a>: <ul><li><a href="/wiki/Category:MediaWiki_action_API" title="Category:MediaWiki action API">MediaWiki action API</a></li></ul></div></div> </div> </main> </div> <div class="mw-footer-container"> <footer id="footer" class="mw-footer" > <ul id="footer-info"> <li id="footer-info-lastmod"> This page was last edited on 11 September 2024, at 21:35.</li> <li id="footer-info-copyright">Text is available under the <a rel="nofollow" class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-ShareAlike License</a>; additional terms may apply. Text in <a class="external text" href="https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents">the Help: namespace</a> is available under the <a rel="nofollow" class="external text" href="https://creativecommons.org/publicdomain/zero/1.0/">Creative Commons CC0 License</a>. By using this site, you agree to the <a class="external text" href="https://foundation.wikimedia.org/wiki/Special:MyLanguage/Policy:Terms_of_Use">Terms of Use</a> and <a class="external text" href="https://foundation.wikimedia.org/wiki/Special:MyLanguage/Policy:Privacy_policy">Privacy Policy</a>.</li> </ul> <ul id="footer-places"> <li id="footer-places-privacy"><a href="https://foundation.wikimedia.org/wiki/Special:MyLanguage/Policy:Privacy_policy">Privacy policy</a></li> <li id="footer-places-about"><a href="/wiki/Project:About">About mediawiki.org</a></li> <li id="footer-places-disclaimers"><a href="/wiki/Project:General_disclaimer">Disclaimers</a></li> <li id="footer-places-wm-codeofconduct"><a href="https://www.mediawiki.org/wiki/Special:MyLanguage/Code_of_Conduct">Code of Conduct</a></li> <li id="footer-places-developers"><a href="https://developer.wikimedia.org">Developers</a></li> <li id="footer-places-statslink"><a href="https://stats.wikimedia.org/#/www.mediawiki.org">Statistics</a></li> <li id="footer-places-cookiestatement"><a href="https://foundation.wikimedia.org/wiki/Special:MyLanguage/Policy:Cookie_statement">Cookie statement</a></li> <li id="footer-places-mobileview"><a href="//m.mediawiki.org/w/index.php?title=API:Holidays_viewer&amp;mobileaction=toggle_view_mobile" class="noprint stopMobileRedirectToggle">Mobile view</a></li> </ul> <ul id="footer-icons" class="noprint"> <li id="footer-copyrightico"><a href="https://wikimediafoundation.org/" class="cdx-button cdx-button--fake-button cdx-button--size-large cdx-button--fake-button--enabled"><img src="/static/images/footer/wikimedia-button.svg" width="84" height="29" alt="Wikimedia Foundation" loading="lazy"></a></li> <li id="footer-poweredbyico"><a href="https://www.mediawiki.org/" class="cdx-button cdx-button--fake-button cdx-button--size-large cdx-button--fake-button--enabled"><img src="/w/resources/assets/poweredby_mediawiki.svg" alt="Powered by MediaWiki" width="88" height="31" loading="lazy"></a></li> </ul> </footer> </div> </div> </div> <div class="vector-settings" id="p-dock-bottom"> <ul></ul> </div><script>(RLQ=window.RLQ||[]).push(function(){mw.log.warn("This page is using the deprecated ResourceLoader module \"mediawiki.ui.button\".\n[1.41] Please use Codex. See migration guidelines: https://www.mediawiki.org/wiki/Codex/Migrating_from_MediaWiki_UI");mw.config.set({"wgHostname":"mw-web.codfw.main-6df7948d6c-ncj9r","wgBackendResponseTime":120,"wgPageParseReport":{"limitreport":{"cputime":"0.591","walltime":"1.913","ppvisitednodes":{"value":4791,"limit":1000000},"postexpandincludesize":{"value":52138,"limit":2097152},"templateargumentsize":{"value":23052,"limit":2097152},"expansiondepth":{"value":15,"limit":100},"expensivefunctioncount":{"value":44,"limit":500},"unstrip-depth":{"value":0,"limit":20},"unstrip-size":{"value":93693,"limit":5000000},"entityaccesscount":{"value":0,"limit":400},"timingprofile":["100.00% 1608.693 1 -total"," 15.28% 245.757 1 Template:API"," 12.51% 201.219 60 Template:Ll"," 11.95% 192.161 1 Template:Sidebar"," 7.40% 119.109 77 Template:Pagelang"," 7.29% 117.249 120 Template:Translatable"," 2.87% 46.093 1 Template:Mbox"," 2.61% 42.058 8 Template:Collapse_top"," 1.53% 24.593 19 Template:Dir"," 1.09% 17.549 7 Template:TNTN"]},"scribunto":{"limitreport-timeusage":{"value":"0.119","limit":"10.000"},"limitreport-memusage":{"value":1400885,"limit":52428800}},"cachereport":{"origin":"mw-web.eqiad.main-59856bd7d8-tnlrh","timestamp":"20241119180755","ttl":2592000,"transientcontent":false}}});});</script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10