Overview

     The Joshua Project API is a REST based API for retrieving data from the Joshua Project Initiative . If you are not familiar with the term REST, you can read more at Wikipedia . All requests for data from the API must contain a valid API Key, and must pass the data with the GET HTTP request method.

API Keys

     An API Key is a unique 12 character string that identifies your application as the source of every request. Here is a sample of an API key: 233f76f4c84e. API keys are free and you are allowed to have multiple API keys. The only requirement is that you verify your email before you get access to your key. Before starting this tutorial, you will need to retrieve an API key . Here are the steps for retrieving the API Key:

  • Fill out and submit the form on this page (You must fill in all required fields)
  • Visit the email you provided. You should receive an email from the Joshua Project Intiative. (You may need to check your Spam folder)
  • Click the link in the email to retrieve your API Key

GET HTTP Request Method

     Each time you click on a link in your browser, you are sending a GET HTTP request method. There are several HTTP Request methods including POST, PUT, and DELETE, but GET is one of the most common HTTP request methods. GET HTTP requests pass the parameters through the URL string. You may be familiar with URLs like:

http://mysite.com/store_center.html?page=store&task=purchase

     Let us break this URL down. In this URL, you are requesting the http://mysite.com/ domain name, and you want to see the store_center.html file on that web server. We are also passing 2 parameters that follow the ?. The question mark tells the server that we want to send some parameters. Each parameter has a key and a value. Here are the parameters we are sending:

Parameters
Key Value
page store
task purchase

The & is required to seperate each parameter. That is pretty much all you will need to do to make a GET request. We will look at this in more depth below.

     For more information on the REST Architecture and the GET HTTP request method, check out this tutorial at NetTuts.

URL Structure

     Below is a typical request for data from the Joshua Project API. In this example, we will request the Joshua Project's unreached people group of the day for January 11th.

http://api.joshuaproject.net/v1/people_groups/daily_unreached.json?api_key=233f76f4c84e&month=01&day=11

     Here is a breakdown of the URL structure:

http://api.joshuaproject.net/[api_version_number]/[resource_path].[format]?api_key=[your_api_key]&[other_parameters]
URL Definitions
api_version_number The letter "v" followed by an integer indicating the version of the API you want to use. (Current version = v1)
resource_path The path to the data you want to retreived. You can see available resource paths in the documentation.
format The format of the server's response. (json or xml)
your_api_key The API Key your retrieved for your application.
other_parameters A series of parameters (key=value) used to filter your request. Each parameter needs to be seperated by an &.

Response

     Once you make a request, the server will send back a response in either JSON or XML based on the format you specified. Here is the JSON response for the request above:

[
    {
        "ROG3": "LA",
        "PeopleID3": "14966",
        "ROP3": "109364",
        "PeopNameInCountry": "So",
        "ROG2": "ASI",
        "Continent": "Asia",
        "RegionName": "Southeast Asia",
        "ISO3": "LAO",
        "LocationInCountry": "They live on both sides of the Laos-Thailand border, especially in
        northern Savannakhet Province and southern Khammouan Province in Laos. An additional group
        of So people inhabit 53 villages in north-east Thailand.",
        "PeopleID1": "20",
        "ROP1": "A011",
        "AffinityBloc": "Southeast Asian Peoples",
        "PeopleID2": "239",
        "ROP2": "C0147",
        "PeopleCluster": "Mon-Khmer",
        "PeopNameAcrossCountries": "So",
        "Population": "138000",
        "PopulationPercentUN": "2.15989",
        "Category": "2",
        "ROL3": "sss",
        "PrimaryLanguageName": "So",
        "ROL4": "0",
        "PrimaryLanguageDialect": null,
        "NumberLanguagesSpoken": "1",
        "ROL3OfficialLanguage": "lao",
        "OfficialLang": "Lao",
        "SpeakNationalLang": null,
        "BibleStatus": "2",
        "BibleYear": null,
        "NTYear": null,
        "PortionsYear": "1980-2004",
        "TranslationNeedQuestionable": null,
        "JPScale": "1.2",
        "JPScalePC": "3.1",
        "JPScalePGAC": "1.2",
        "LeastReached": "Y",
        "LeastReachedBasis": "2",
        "LeastReachedPC": null,
        "LeastReachedPGAC": "Y",
        "GSEC": "2",
        "Unengaged": "",
        "JF": "",
        "AudioRecordings": "Y",
        "NTOnline": "",
        "GospelRadio": "",
        "RLG3": "2",
        "RLG3PC": "2",
        "RLG3PGAC": "2",
        "PrimaryReligion": "Buddhism",
        "PrimaryReligionPC": "Buddhism",
        "PrimaryReligionPGAC": "Buddhism",
        "RLG4": null,
        "ReligionSubdivision": null,
        "PCIslam": "0",
        "PCNonReligious": "0",
        "PCUnknown": "0",
        "PCAnglican": "0",
        "PCIndependent": "0",
        "PCProtestant": "70",
        "PCOrthodox": "0",
        "PCOtherChristian": "0",
        "StonyGround": "Y",
        "SecurityLevel": "2",
        "RaceCode": "AUG03z",
        "LRWebProfile": "Y",
        "LRofTheDayMonth": "1",
        "LRofTheDayDay": "11",
        "LRTop100": "",
        "PhotoAddress": "p14966.jpg",
        "PhotoWidth": "200",
        "PhotoHeight": "249",
        "PhotoCredits": "Ray Mason",
        "PhotoCreditURL": null,
        "PhotoCreativeCommons": null,
        "PhotoCopyright": null,
        "PhotoPermission": null,
        "ProfileTextExists": "Y",
        "Top10Ranking": null,
        "RankOverall": "73",
        "RankProgress": "26",
        "RankPopulation": "19",
        "RankLocation": "18",
        "RankMinistryTools": "10",
        "CountOfCountries": "2",
        "CountOfProvinces": "2",
        "EthnolinguisticMap": "http://www.lib.utexas.edu/maps/middle_east_and_asia/indochina_eth_1970.jpg",
        "MapID": "sss-LA",
        "V59Country": null,
        "Longitude": "105.427040000396",
        "Latitude": "17.0162099995918",
        "UNMap": "http://www.un.org/Depts/Cartographic/map/profile/laos.pdf",
        "Ctry": "Laos",
        "IndigenousCode": "Y",
        "PercentAdherents": "0.2",
        "PercentChristianPC": "9.55",
        "PercentChristianPGAC": "0.47",
        "PercentEvangelical": "0.0500834733247757",
        "PercentEvangelicalPC": "2.77",
        "PercentEvangelicalPGAC": "0.2",
        "PCBuddhism": "90",
        "PCDblyProfessing": "0",
        "PCEthnicReligions": "9.8",
        "PCHinduism": "0",
        "PCOtherSmall": "0",
        "PCRomanCatholic": "30",
        "RegionCode": "2",
        "Window1040": "Y",
        "PeopleGroupURL": "http://joshuaproject.net/people_groups/14966/LA",
        "PeopleGroupPhotoURL": "http://www.joshuaproject.net/profiles/photos/p14966.jpg",
        "CountryURL": "http://joshuaproject.net/countries/LA",
        "JPScaleText": "Unreached",
        "JPScaleImageURL": "http://www.joshuaproject.net/images/scale1.jpg",
        "ProfileText": [
            {
                "ProfileID": "2445",
                "ROL3": "eng",
                "Active": "1",
                "Format": "GB",
                "FileName": "t14966_la.txt",
                "IntroductionHistory": "The So live along both banks of the Mekong River
                in Thailand and Laos. This is a rugged mountain region with many dense
                tropical forests. The Lao-Thai name So (\"elder brother\") refers to
                the fact that the So were present in this area long before their
                \"younger brothers,\" the Lao. The So are bilingual, speaking So
                (a Mon-Khmer language) in their homes and Lao in social settings.
                \r\n\r\nIt is said that the Mon Khmer-speaking tribes were the original
                settlers of this region. However, they were pushed out of the best lands
                in the early centuries A.D. by Thai-speaking peoples. About 400 years ago,
                the Thai-speakers forced the So to leave their homes and re-settle on the
                banks of the Mekong River. They gradually adapted to the lifestyles of the
                Thai and the Lao. In recent years, Laos has been the location of numerous
                battles. It has also been the object of political competition among China,
                Russia, and Vietnam. Recurring warfare and forced relocation has disrupted
                the lives of the So.",
                "WhereLocated": null,
                "LivesLike": "The So of Laos are primarily farmers. They cultivate a wide
                variety of crops, such as rice, fruit, and vegetables, for both consumption
                and trade. They are poorer than most of the surrounding ethnic groups and
                are therefore dependent on the Lao for many goods and services. The
                villagers also frequently meet with the Thai to trade meat and vegetables
                for necessary items such as clothing and salt.\r\n\r\nOver the years,
                the So began adopting the practices of the surrounding peoples, especially
                the Thai and Lao. This brought on many significant changes within their
                culture. For example, they no longer use their traditional farming methods
                of burning and clearing plots. Instead, they grow wet-rice on terraced
                plots, which is the agricultural method of the Thai. They also raise their
                cattle and till their fields much like the Lao. The fields are prepared with
                plows drawn by buffalo or oxen. In addition, fishing and hunting have become
                important activities.\r\n\r\nSuch things as traditional dress, language,
                educational methods, housing, and public administration have also changed over the
                years. Only a few distinctive, cultural characteristics have remained, such as
                the silk scarves worn by the So women around a bun of hair at their necks.
                \r\n\r\nAmong the So, the village is considered the most significant political
                unit of society. Each village is led by a headman, and each family is led by
                the father. A young married couple may live with the bride's family until they
                are able to establish their own home. The So typically live in thatch roof bamboo
                houses built on stilts. They are not known to be clean people, but rather dirty and
                disorderly.",
                "Beliefs": "Buddhism was introduced into Thailand in 329 B.C.; and today, most of
                the So profess to be Buddhist. However, most of them have mixed elements of Buddhism
                with their traditional animistic beliefs (belief that non-living objects have spirits).
                They often seek help through supernatural spirits and objects. Ancestor worship
                (praying to deceased ancestors for provision and guidance) is also common.
                The ancestral spirits are thought to cause illnesses if they are not appeased.
                Families usually have small altars near their homes where sacrifices and offerings
                are made to the spirits. The people also believe that each village has a
                \"guardian spirit,\" as well as various spirits that are linked to the elements
                of nature.",
                "Needs": "The area where the So live is often affected by destructive floods.
                Due to the crop losses in 1996, there is a projected food shortage that will
                greatly affect the rural population. Food aid and basic relief items are needed.
                \r\n\r\nMany of the fields in this area are laden with cluster bomblets that were
                dropped by U.S. warplanes during Vietnam War. The villagers need God's protection
                over them as they work daily in the fields. Medical help, especially with prosthesis
                and physical therapy, is needed. Perhaps these needs will provide opportunities for
                Christian medical missionaries to gain access to the So.",
                "Prayer": "* Pray that God will give the missions agencies in Laos fresh strategies
                for reaching the So with the Gospel. \r\n* Ask the Lord to call Christian medical
                teams and humanitarian aid workers to go to Laos and live among the So. \r\n* Pray
                that God will protect the So from the destructive floods in their region. \r\n* Ask
                God to strengthen, encourage, and protect the few known So Christians. \r\n* Pray
                that the So believers will have opportunities to share the Gospel with their own people.
                \r\n* Ask God to call forth prayer teams who will begin breaking up the soil through
                worship and intercession. \r\n* Ask the Lord to raise up strong local churches among the So.",
                "Reference": null,
                "Summary": null,
                "ScriptureFocus": null,
                "Obstacles": null,
                "HowReach": null,
                "PrayForChurch": null,
                "PrayForPG": null,
                "Identity": null,
                "History": null,
                "Customs": null,
                "Religion": null,
                "Christianity": null,
                "Comments": null,
                "Copyright": "Y",
                "Permission": "Y",
                "CreativeCommons": null,
                "Credits": "Bethany World Prayer Center",
                "CreditsURL": null
            },
            {
                "ProfileID": "4453",
                "ROL3": "eng",
                "Active": "1",
                "Format": "M",
                "FileName": null,
                "IntroductionHistory": null,
                "WhereLocated": null,
                "LivesLike": null,
                "Beliefs": null,
                "Needs": null,
                "Prayer": null,
                "Reference": null,
                "Summary": "The So of Laos are primarily farmers. They cultivate a wide variety of
                crops, such as rice, fruit, and vegetables, for both consumption and trade. They
                are poorer than most of the surrounding ethnic groups and are therefore dependent
                on the Lao for many goods and services. Among the So, the village is considered
                the most significant political unit of society. Each village is led by a headman,
                and each family is led by the father. \"Although the So often show an intense
                interest in scripture, they have not yet overcome the spiritual barriers that keep
                them from embracing the King of Kings. Their families and relatives all fear that
                if any one of them abandons worship of the spirits, the entire family will be
                punished.\"",
                "ScriptureFocus": "\"And you shall be my witnesses, both in Jerusalem, and in
                all Judea and Samaria, and even to the remotest part of the earth.\" Acts 1:8",
                "Obstacles": "Fear is one of the obstacles to the Gospel experienced by the So.
                Please pray they will be set free from fear.",
                "HowReach": "Pray for spiritually mature, indigenous workers to take the liberating
                news of Christ to the So tribe. Laos has a number of evangelical churches, and
                people in these churches can take the Gospel to unreached tribes in their own country.",
                "PrayForChurch": "Please pray for the few individuals in the So tribe who identify
                themselves as Christians. They need to be taught how to quickly confess sin, and
                then trust God's Spirit to fill them and give them the fruit of the Spirit: love,
                joy, peace, patience, kindness, goodness, faithfulness, gentleness, self-control.",
                "PrayForPG": "Pray the poor So tribe will be able to improve their standard of
                living, and will care for those unable to care for themselves.",
                "Identity": null,
                "History": null,
                "Customs": null,
                "Religion": null,
                "Christianity": null,
                "Comments": null,
                "Copyright": null,
                "Permission": null,
                "CreativeCommons": null,
                "Credits": "Joshua Project",
                "CreditsURL": null
            }
        ],
        "Resources": [
            {
                "ROL3": "sss",
                "Category": "Audio Recordings",
                "WebText": "Global Recordings",
                "URL": "http://www.globalrecordings.net/langcode/sss"
            }
        ]
    }
]
                    

And here is the XML response:

<?xml version="1.0" encoding="UTF-8"?>
<api>
    <people_groups>
        <people_group>
            <ROG3>LA</ROG3>
            <PeopleID3>14966</PeopleID3>
            <ROP3>109364</ROP3>
            <PeopNameInCountry>So</PeopNameInCountry>
            <ROG2>ASI</ROG2>
            <Continent>Asia</Continent>
            <RegionName>Southeast Asia</RegionName>
            <ISO3>LAO</ISO3>
            <LocationInCountry>
            They live on both sides of the Laos-Thailand border, especially in
            northern Savannakhet Province and southern Khammouan Province in Laos.
            An additional group of So people inhabit 53 villages in north-east Thailand.
            </LocationInCountry>
            <PeopleID1>20</PeopleID1>
            <ROP1>A011</ROP1>
            <AffinityBloc>Southeast Asian Peoples</AffinityBloc>
            <PeopleID2>239</PeopleID2>
            <ROP2>C0147</ROP2>
            <PeopleCluster>Mon-Khmer</PeopleCluster>
            <PeopNameAcrossCountries>So</PeopNameAcrossCountries>
            <Population>138000</Population>
            <PopulationPercentUN>2.15989</PopulationPercentUN>
            <Category>2</Category>
            <ROL3>sss</ROL3>
            <PrimaryLanguageName>So</PrimaryLanguageName>
            <ROL4>0</ROL4>
            <PrimaryLanguageDialect />
            <NumberLanguagesSpoken>1</NumberLanguagesSpoken>
            <ROL3OfficialLanguage>lao</ROL3OfficialLanguage>
            <OfficialLang>Lao</OfficialLang>
            <SpeakNationalLang />
            <BibleStatus>2</BibleStatus>
            <BibleYear />
            <NTYear />
            <PortionsYear>1980-2004</PortionsYear>
            <TranslationNeedQuestionable />
            <JPScale>1.2</JPScale>
            <JPScalePC>3.1</JPScalePC>
            <JPScalePGAC>1.2</JPScalePGAC>
            <LeastReached>Y</LeastReached>
            <LeastReachedBasis>2</LeastReachedBasis>
            <LeastReachedPC />
            <LeastReachedPGAC>Y</LeastReachedPGAC>
            <GSEC>2</GSEC>
            <Unengaged />
            <JF />
            <AudioRecordings>Y</AudioRecordings>
            <NTOnline />
            <GospelRadio />
            <RLG3>2</RLG3>
            <RLG3PC>2</RLG3PC>
            <RLG3PGAC>2</RLG3PGAC>
            <PrimaryReligion>Buddhism</PrimaryReligion>
            <PrimaryReligionPC>Buddhism</PrimaryReligionPC>
            <PrimaryReligionPGAC>Buddhism</PrimaryReligionPGAC>
            <RLG4 />
            <ReligionSubdivision />
            <PCIslam>0</PCIslam>
            <PCNonReligious>0</PCNonReligious>
            <PCUnknown>0</PCUnknown>
            <PCAnglican>0</PCAnglican>
            <PCIndependent>0</PCIndependent>
            <PCProtestant>70</PCProtestant>
            <PCOrthodox>0</PCOrthodox>
            <PCOtherChristian>0</PCOtherChristian>
            <StonyGround>Y</StonyGround>
            <SecurityLevel>2</SecurityLevel>
            <RaceCode>AUG03z</RaceCode>
            <LRWebProfile>Y</LRWebProfile>
            <LRofTheDayMonth>1</LRofTheDayMonth>
            <LRofTheDayDay>11</LRofTheDayDay>
            <LRTop100 />
            <PhotoAddress>p14966.jpg</PhotoAddress>
            <PhotoWidth>200</PhotoWidth>
            <PhotoHeight>249</PhotoHeight>
            <PhotoCredits>Ray Mason</PhotoCredits>
            <PhotoCreditURL />
            <PhotoCreativeCommons />
            <PhotoCopyright />
            <PhotoPermission />
            <ProfileTextExists>Y</ProfileTextExists>
            <Top10Ranking />
            <RankOverall>73</RankOverall>
            <RankProgress>26</RankProgress>
            <RankPopulation>19</RankPopulation>
            <RankLocation>18</RankLocation>
            <RankMinistryTools>10</RankMinistryTools>
            <CountOfCountries>2</CountOfCountries>
            <CountOfProvinces>2</CountOfProvinces>
            <EthnolinguisticMap>
            http://www.lib.utexas.edu/maps/middle_east_and_asia/indochina_eth_1970.jpg
            </EthnolinguisticMap>
            <MapID>sss-LA</MapID>
            <V59Country />
            <Longitude>105.427040000396</Longitude>
            <Latitude>17.0162099995918</Latitude>
            <UNMap>http://www.un.org/Depts/Cartographic/map/profile/laos.pdf</UNMap>
            <Ctry>Laos</Ctry>
            <IndigenousCode>Y</IndigenousCode>
            <PercentAdherents>0.2</PercentAdherents>
            <PercentChristianPC>9.55</PercentChristianPC>
            <PercentChristianPGAC>0.47</PercentChristianPGAC>
            <PercentEvangelical>0.0500834733247757</PercentEvangelical>
            <PercentEvangelicalPC>2.77</PercentEvangelicalPC>
            <PercentEvangelicalPGAC>0.2</PercentEvangelicalPGAC>
            <PCBuddhism>90</PCBuddhism>
            <PCDblyProfessing>0</PCDblyProfessing>
            <PCEthnicReligions>9.8</PCEthnicReligions>
            <PCHinduism>0</PCHinduism>
            <PCOtherSmall>0</PCOtherSmall>
            <PCRomanCatholic>30</PCRomanCatholic>
            <RegionCode>2</RegionCode>
            <Window1040>Y</Window1040>
            <PeopleGroupURL>
            http://joshuaproject.net/people_groups/14966/LA
            </PeopleGroupURL>
            <PeopleGroupPhotoURL>
            http://www.joshuaproject.net/profiles/photos/p14966.jpg
            </PeopleGroupPhotoURL>
            <CountryURL>http://joshuaproject.net/countries/LA</CountryURL>
            <JPScaleText>Unreached</JPScaleText>
            <JPScaleImageURL>http://www.joshuaproject.net/images/scale1.jpg</JPScaleImageURL>
            <ProfileText>
                <ProfileText_0>
                    <ProfileID>2445</ProfileID>
                    <ROL3>eng</ROL3>
                    <Active>1</Active>
                    <Format>GB</Format>
                    <FileName>t14966_la.txt</FileName>
                    <IntroductionHistory>
                    The So live along both banks of the Mekong River in Thailand
                     and Laos. This is a rugged mountain region with many dense
                     tropical forests. The Lao-Thai name So ("elder brother")
                     refers to the fact that the So were present in this area long
                     before their "younger brothers," the Lao. The So are bilingual,
                     speaking So (a Mon-Khmer language) in their homes and Lao in social
                     settings. 

It is said that the Mon Khmer-speaking tribes were
                     the original settlers of this region. However, they were pushed out
                     of the best lands in the early centuries A.D. by Thai-speaking peoples.
                     About 400 years ago, the Thai-speakers forced the So to leave their
                     homes and re-settle on the banks of the Mekong River. They gradually
                     adapted to the lifestyles of the Thai and the Lao. In recent years,
                     Laos has been the location of numerous battles. It has also been the
                     object of political competition among China, Russia, and Vietnam.
                     Recurring warfare and forced relocation has disrupted the lives of
                     the So.
                     </IntroductionHistory>
                    <WhereLocated />
                    <LivesLike>
                    The So of Laos are primarily farmers. They cultivate a wide variety of
                    crops, such as rice, fruit, and vegetables, for both consumption and trade.
                    They are poorer than most of the surrounding ethnic groups and are
                    therefore dependent on the Lao for many goods and services. The villagers
                    also frequently meet with the Thai to trade meat and vegetables for necessary
                    items such as clothing and salt.

Over the years, the So began
                    adopting the practices of the surrounding peoples, especially the Thai and
                    Lao. This brought on many significant changes within their culture. For
                    example, they no longer use their traditional farming methods of burning
                    and clearing plots. Instead, they grow wet-rice on terraced plots, which is the
                    agricultural method of the Thai. They also raise their cattle and till their
                    fields much like the Lao. The fields are prepared with plows drawn by buffalo
                    or oxen. In addition, fishing and hunting have become important activities.
                    

Such things as traditional dress, language, educational methods,
                    housing, and public administration have also changed over the years. Only a
                    few distinctive, cultural characteristics have remained, such as the silk
                    scarves worn by the So women around a bun of hair at their necks.

                    Among the So, the village is considered the most significant political unit
                    of society. Each village is led by a headman, and each family is led by the
                    father. A young married couple may live with the bride's family until they are
                    able to establish their own home. The So typically live in thatch roof bamboo
                    houses built on stilts. They are not known to be clean people, but rather
                    dirty and disorderly.
                    </LivesLike>
                    <Beliefs>
                    Buddhism was introduced into Thailand in 329 B.C.; and today, most of the
                    So profess to be Buddhist. However, most of them have mixed elements of
                    Buddhism with their traditional animistic beliefs (belief that non-living
                    objects have spirits). They often seek help through supernatural spirits
                    and objects. Ancestor worship (praying to deceased ancestors for provision
                    and guidance) is also common. The ancestral spirits are thought to cause
                    illnesses if they are not appeased. Families usually have small altars near
                    their homes where sacrifices and offerings are made to the spirits. The
                    people also believe that each village has a "guardian spirit," as well as
                    various spirits that are linked to the elements of nature.
                    </Beliefs>
                    <Needs>
                    The area where the So live is often affected by destructive floods. Due to the
                    crop losses in 1996, there is a projected food shortage that will greatly
                    affect the rural population. Food aid and basic relief items are needed.
                    

Many of the fields in this area are laden with cluster bomblets
                    that were dropped by U.S. warplanes during Vietnam War. The villagers need
                    God's protection over them as they work daily in the fields. Medical help,
                    especially with prosthesis and physical therapy, is needed. Perhaps these needs
                    will provide opportunities for Christian medical missionaries to gain access
                    to the So.
                    </Needs>
                    <Prayer>
                    * Pray that God will give the missions agencies in Laos fresh strategies for
                    reaching the So with the Gospel. 
* Ask the Lord to call Christian medical
                    teams and humanitarian aid workers to go to Laos and live among the So. 
*
                    Pray that God will protect the So from the destructive floods in their region.
                    
* Ask God to strengthen, encourage, and protect the few known So Christians.
                    
* Pray that the So believers will have opportunities to share the Gospel
                    with their own people. 
* Ask God to call forth prayer teams who will begin
                    breaking up the soil through worship and intercession. 
* Ask the Lord to
                    raise up strong local churches among the So.
                    </Prayer>
                    <Reference />
                    <Summary />
                    <ScriptureFocus />
                    <Obstacles />
                    <HowReach />
                    <PrayForChurch />
                    <PrayForPG />
                    <Identity />
                    <History />
                    <Customs />
                    <Religion />
                    <Christianity />
                    <Comments />
                    <Copyright>Y</Copyright>
                    <Permission>Y</Permission>
                    <CreativeCommons />
                    <Credits>Bethany World Prayer Center</Credits>
                    <CreditsURL />
                </ProfileText_0>
                <ProfileText_1>
                    <ProfileID>4453</ProfileID>
                    <ROL3>eng</ROL3>
                    <Active>1</Active>
                    <Format>M</Format>
                    <FileName />
                    <IntroductionHistory />
                    <WhereLocated />
                    <LivesLike />
                    <Beliefs />
                    <Needs />
                    <Prayer />
                    <Reference />
                    <Summary>
                    The So of Laos are primarily farmers. They cultivate a wide variety of crops,
                    such as rice, fruit, and vegetables, for both consumption and trade. They are
                    poorer than most of the surrounding ethnic groups and are therefore dependent
                    on the Lao for many goods and services. Among the So, the village is
                    considered the most significant political unit of society. Each village is
                    led by a headman, and each family is led by the father. "Although the So often
                    show an intense interest in scripture, they have not yet overcome the spiritual
                    barriers that keep them from embracing the King of Kings. Their families and
                    relatives all fear that if any one of them abandons worship of the spirits,
                    the entire family will be punished."
                    </Summary>
                    <ScriptureFocus>
                    "And you shall be my witnesses, both in Jerusalem, and in all Judea and Samaria,
                    and even to the remotest part of the earth." Acts 1:8
                    </ScriptureFocus>
                    <Obstacles>
                    Fear is one of the obstacles to the Gospel experienced by the So. Please pray
                    they will be set free from fear.
                    </Obstacles>
                    <HowReach>
                    Pray for spiritually mature, indigenous workers to take the liberating news
                    of Christ to the So tribe. Laos has a number of evangelical churches, and
                    people in these churches can take the Gospel to unreached tribes in their
                    own country.
                    </HowReach>
                    <PrayForChurch>
                    Please pray for the few individuals in the So tribe who identify themselves
                    as Christians. They need to be taught how to quickly confess sin, and then
                    trust God's Spirit to fill them and give them the fruit of the Spirit: love,
                    joy, peace, patience, kindness, goodness, faithfulness, gentleness, self-control.
                    </PrayForChurch>
                    <PrayForPG>
                    Pray the poor So tribe will be able to improve their standard of living, and
                    will care for those unable to care for themselves.
                    </PrayForPG>
                    <Identity />
                    <History />
                    <Customs />
                    <Religion />
                    <Christianity />
                    <Comments />
                    <Copyright />
                    <Permission />
                    <CreativeCommons />
                    <Credits>Joshua Project</Credits>
                    <CreditsURL />
                </ProfileText_1>
            </ProfileText>
            <Resources>
                <Resources_0>
                    <ROL3>sss</ROL3>
                    <Category>Audio Recordings</Category>
                    <WebText>Global Recordings</WebText>
                    <URL>http://www.globalrecordings.net/langcode/sss</URL>
                </Resources_0>
            </Resources>
        </people_group>
    </people_groups>
</api>
                    

     Once you have a response, you can use and manipulate the provided data.

Getting Started (All Tutorials)

     In the following tutorials, we will walk through four different approaches for creating the Joshua Project's unreached people group of the day widget using the new API. These tutorials come in a variety of programming languages including Javascript using the JQuery library, PHP, Python and Ruby. Feel free and choose the programming language that you feel more comfortable programming in. Before starting this tutorial, you will need to retrieve an API key.

Starting Code

     We have created zip files containing the starting code for each programming language. You can download these files from the following links:

     After downloading and unzipping the directory, look for the styles.css file. This file offers the basic design for the widget. Here is a look at the code:

.upgotd {
    color: #000000;
    font-family: Arial, Helvetica, Verdana, sans-serif;
}
#jp_widget {
    background-color: #EEE;
    border: #CCCCCC 1px dashed;
    text-align: center;
    width: 215px;
    font-size:12px;
}
#jp_widget a {
    color: #000000 !important;
    text-decoration: none;
}
#jp_widget a:hover {
    color: #0000FF !important;
    text-decoration: none;
}
.upgotd-title, .upgotd-footer {
    padding: 3px;
    background-color: #BBDDFF;
}
.upgotd-title, .upgotd-title a {
    font-weight: bold; font-size:13px !important;
    margin-bottom: 5px;
}
.upgotd-image {
    text-align: center;
}
.upgotd-pray {
    font-style: italic;
    font-weight: normal;
    padding: 3px 0px;
    font-size: 12px;
}
.upgotd-people {
    font-weight: normal;
    font-size:12px !important;
    padding-bottom:4px;
}
.upgotd-people a {
    font-weight: bold;
}
.upgotd-table td {
    font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
    font-size:11px;
    font-weight: normal;
    color: #000;
    line-height: 14px;
    text-align: left;
    border: 0px;
    background-color: #EEE;
    margin: 0px;
    padding: 0px 0px 0px 3px;
}
.upgotd-more, .upgotd-more a {
    font-size: 10px;
}
.upgotd-footer, .upgotd-footer a {
    font-weight: normal ;
    font-size: 11px;
    margin-top: 3px;
}
a#progress-scale-image img {
    border: none;
}
.hidden {
    display: none;
}
                    

     You will also find an index file. (The extension varies based on the programming language) This file offers the basic structure of the final widget. The code looks like this:

<!DOCTYPE html>
<html>
    <head>
        <title>Joshua Project</title>
        <link rel="stylesheet" type="text/css" href="css/styles.css">
    </head>
    <body>
        <div id="jp_widget">
            <div class="upgotd upgotd-title">
                <a href="http://www.joshuaproject.net/upgotdfeed.php" class="upgotd-link">
                Unreached of the Day
                </a>
            </div>
            <div class="upgotd-image">
                <a href="#" class="upgotd-link pg-link" id="people-group-image">
                </a>
            </div>
            <div class="upgotd upgotd-pray">Please pray for the ...</div>
            <div class="upgotd upgotd-people">
                <a href="#" class="upgotd-link pg-link pg-name"></a> of
                <a href="#" class="upgotd-link country-link country-name"></a>
            </div>
            <table align="center" class="upgotd-table" cellpadding="0" cellspacing="0">
                <tbody><tr>
                    <td width="65">Population:</td>
                    <td width="135" class="pg-population"></td>
                </tr>
                <tr>
                    <td>Language:</td>
                    <td class="pg-language"></td>
                </tr>
                <tr>
                    <td>Religion:</td>
                    <td class="pg-religion"></td>
                </tr>
                <tr>
                    <td>Evangelical:</td>
                    <td class="pg-evangelical"></td>
                </tr>
                <tr>
                    <td>Status:</td>
                    <td>
                        <a
                        href="http://www.joshuaproject.net/definitions.php?term=25"
                        class="upgotd-link pg-scale-text">
                        </a> (
                        <a
                        href="http://www.joshuaproject.net/global-progress-scale.php"
                        class="upgotd-link pg-scale">
                        </a> 
                        <a
                        href="http://www.joshuaproject.net/global-progress-scale.php"
                        class="upgotd-link"
                        id="progress-scale-image">
                        </a>
                        )
                    </td>
                </tr>
            </tbody></table>
            <div class="upgotd upgotd-footer">
            Add this daily global vision feature to <br>
            <a href="/upgotdfeed.php" class="upgotd-link">your website</a> or get it
            <a href="http://www.unreachedoftheday.org/unreached-email.php" class="upgotd-link">
            by email
            </a>.</div>
        </div>
    </body>
</html>
                    

     We will use this starting code to launch into developing a widget that pulls in the data from our API. To get started, please choose your preferred programming language to continue this tutorial:

     Before beginning this tutorial, you should have a good understanding of the Javascript programming language, and the JQuery library! You will also need to download the starting code.

The JQuery Library

     JQuery is a Javascript library designed to make scripting in Javascript much more enjoyable and faster. It helps speed up common tasks like traversing the DOM, animating and manipulating DOM elements, and running Ajax calls. In order to use the library, we need to include it in the head tag of our index.html file. So open the index.html file and add the following line between the tags <head></head>:

<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>

     We do not need to download the JQuery library, because we will just use the file on their hosted CDN.

Calling the API

     Before calling the API, we can use a common JQuery method .ready() (Jquery Docs) to check if the DOM has loaded before running our Ajax request. So in the <head></head> tag, after the declaring the JQuery library, we need to add the following code:

<script type="text/javascript">
    jQuery(document).ready(function($) {

    });
</script>
                    

     We should also declare two variables to hold the API's domain name, and your API key. Remember to add your API key!

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {

    });
</script>
                    

     We are now ready to make the API request using JQuery's .ajax() ( Jquery Docs ) method. If you are not familiar with Ajax, it is an acronym for Asynchronous Javascript and XML. Wikipedia states:

With Ajax, web applications can send data to, and retrieve data from, a server asynchronously (in the background) without interfering with the display and behavior of the existing page.

Wikipedia

     Here is the code to run the Ajax request after the DOM has loaded:

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            /* Code in here runs when the request is completed */
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            /* Code in here runs when the request failed */
        });
    });
</script>
                    

     As you can see in the code above, we send the following settings to JQuery's .ajax() ( Jquery Docs ) method:

JQuery Ajax Settings
Setting Description
url http://api.joshuaproject.net/v1/people_groups/daily_unreached.json - The URL of the web page to request. (See the URL Structure section)
dataType json - The type of data returned from the web page
data {api_key: API_KEY} - The additional paramaters to pass the web page.
type GET - The HTTP Request Method

     When this request is completed, it will call the empty function we provided for JQuery's .done() callback ( Jquery Docs ). If the request fails, the empty function provided for the .fail() callback (Jquery Docs) is triggered.

Handling the Error

     Let us start with handling any errors. This will help us debug any problems we may run into later. If the request for the web page is unsuccessful, it will trigger the .fail() callback ( Jquery Docs ). If this happens, we should let the visitor know. We will do this by appending an error message at the top of the page. Here is the updated code:

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            /* Code in here runs when the request is completed */
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            var pTagSettings = {'color': 'red', 'font-weight': 'bold'};
            var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);
            $('body').prepend(pTag);
        });
    });
</script>
                    

     We start by declaring CSS styles (Red & Bold) for the <p></p> tag that will hold the message:

var pTagSettings = {'color': 'red', 'font-weight': 'bold'};

     We then create the <p></p> tag, add the warning message using JQuery's .text() method ( JQuery Docs ), and add the CSS styles using JQuery's .css() method ( JQuery Docs ):

var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);

     We finally prepend the new <p></p> tag to the body of the web page using JQuery's .prepend() method ( JQuery Docs ).

$('body').prepend(pTag);

     That is all we need to do to warn the user when the Ajax fails.

Creating the Widget

     Now that we have handled the errors, let us deal with the response sent back from the API. When the Ajax has successfully received a response from the API, it triggers JQuery's .done() callback ( Jquery Docs ). One of the parameters passed to our empty function is data. This is the API's response. As you remember, we asked the server for JSON. So now we need to handle that JSON response. This code is temporary, but it will help us understand what we are receiving from the API. In the .done() callback ( Jquery Docs ) we will prepend the data to the body of our HTML similar to the .fail() callback ( Jquery Docs ). Here is the code:

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            /* JSON.stringify is only supported in IE 8 > */
            $('body').prepend(JSON.stringify(data));
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            var pTagSettings = {'color': 'red', 'font-weight': 'bold'};
            var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);
            $('body').prepend(pTag);
        });
    });
</script>
                    

     When you save and run this code, you will see something similar to the response code we showed up above. If you do not get a response, then you need to check if you created your URL structure correctly. As you can see in the response, we are receiving a Javascript Array of a single JSON object. So to get the first JSON object, we simply set a variable to the first object of the array (data[0]) like this:

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            var unreached = data[0];
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            var pTagSettings = {'color': 'red', 'font-weight': 'bold'};
            var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);
            $('body').prepend(pTag);
        });
    });
</script>
                    

     Now we can access any of the supplied attributes of that JSON object using it's key. So if we want to get the people group's name, we can access it like this: unreached['PeopNameInCountry']. Now that we can access the data, we just need to start putting the data into the HTML we already provided. If you look at the HTML of the index.html file you have been working on, you will see the following code:

<div id="jp_widget">
    <div class="upgotd upgotd-title">
        <a href="http://www.joshuaproject.net/upgotdfeed.php" class="upgotd-link">Unreached of the Day</a>
    </div>
    <div class="upgotd-image">
        <a href="#" class="upgotd-link pg-link" id="people-group-image">
        </a>
    </div>
    <div class="upgotd upgotd-pray">Please pray for the ...</div>
    <div class="upgotd upgotd-people">
        <a href="#" class="upgotd-link pg-link pg-name"></a>
         of <a href="#" class="upgotd-link country-link country-name"></a>
    </div>
    <table align="center" class="upgotd-table" cellpadding="0" cellspacing="0">
        <tbody><tr>
            <td width="65">Population:</td>
            <td width="135" class="pg-population"></td>
        </tr>
        <tr>
            <td>Language:</td>
            <td class="pg-language"></td>
        </tr>
        <tr>
            <td>Religion:</td>
            <td class="pg-religion"></td>
        </tr>
        <tr>
            <td>Evangelical:</td>
            <td class="pg-evangelical"></td>
        </tr>
        <tr>
            <td>Status:</td>
            <td>
                <a
                href="http://www.joshuaproject.net/definitions.php?term=25"
                class="upgotd-link pg-scale-text">
                </a>
                (<a
                href="http://www.joshuaproject.net/global-progress-scale.php"
                class="upgotd-link pg-scale">
                </a>
                 <a
                href="http://www.joshuaproject.net/global-progress-scale.php"
                class="upgotd-link"
                id="progress-scale-image"></a>)
            </td>
        </tr>
    </tbody></table>
    <div class="upgotd upgotd-footer">Add this daily global vision feature to <br>
    <a href="/upgotdfeed.php" class="upgotd-link">your website</a>
    or get it <a
    href="http://www.unreachedoftheday.org/unreached-email.php"
    class="upgotd-link">by email</a>.</div>
</div>
                    

     As you look through that code, you will see unique classes and ids set to different elements. We will use these classes/ids to let Javascript manipulate it and add the appropriate content from the API. Here is a list of all the classes/ids, and how we will manipulate those elements to show people group data:

Widget Classes
ID/Class Data Accessible With Changes
class country‑link unreached['CountryURL'] We will set the link's href to the Joshua Project's people group's country URL
class country‑name unreached['Ctry'] We will set the text to the people group's country name
id people‑group‑image unreached['PeopleGroupPhotoURL'] We will create an image with a src equal to the location of the people group's image. We will also set it's dimensions to 128 X 160
class pg‑evangelical unreached['PercentEvangelical'] We will set a percentage formatted number totaling the people group's percentage of Evangelicals
class pg‑language unreached['PrimaryLanguageName'] We will set the text to the people group's primary language
class pg‑link unreached['PeopleGroupURL'] We will set the link's href to the Joshua Project's people group's URL
class pg‑name unreached['PeopNameInCountry'] We will set the text to the people group name
class pg‑population unreached['Population'] We will set a comma formatted number totaling the people group's population
class pg‑religion unreached['PrimaryReligion'] We will set the text to the people group's primary religion
class pg‑scale unreached['JPScale'] We will set the text to the people group's progress scale number
id  progress‑scale‑image unreached['JPScaleImageURL'] We will create an image with a src equal to the progress scale image for the people group
class pg‑scale‑text unreached['JPScaleText'] We will set the text to the people group's progress scale text

     So let us begin by completing all the tasks that say "We will set the text to...". This is easy to accomplish by using JQuery's .text() method. (JQuery Docs) Here is the code:

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            var unreached = data[0];
            /* Set the text of each class to the appropriate data */
            $('.country-name').text(unreached['Ctry']);
            $('.pg-language').text(unreached['PrimaryLanguageName']);
            $('.pg-name').text(unreached['PeopNameInCountry']);
            $('.pg-religion').text(unreached['PrimaryReligion']);
            $('.pg-scale').text(unreached['JPScale']);
            $('.pg-scale-text').text(unreached['JPScaleText']);
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            var pTagSettings = {'color': 'red', 'font-weight': 'bold'};
            var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);
            $('body').prepend(pTag);
        });
    });
</script>
                    

     If you refresh the webpage, you should see something like this with different data:

Snapshot Adding text() method

     Mine looks different! If you do not supply a month or day parameter, the API will return today's unreached people group of the day by default. Most likely you are not doing this tutorial the same day as I was. This now leaves us with the following tasks:

Widget Classes
ID/Class Data Accessible With Changes
class country‑link unreached['CountryURL'] We will set the link's href to the Joshua Project's people group's country URL
id people‑group‑image unreached['PeopleGroupPhotoURL'] We will create an image with a src equal to the location of the people group's image. We will also set it's dimensions to 128 X 160
class pg‑evangelical unreached['PercentEvangelical'] We will set a percentage formatted number totaling the people group's percentage of Evangelicals
class pg‑link unreached['PeopleGroupURL'] We will set the link's href to the Joshua Project's people group's URL
class pg‑population unreached['Population'] We will set a comma formatted number totaling the people group's population
id  progress‑scale‑image unreached['JPScaleImageURL'] We will create an image with a src equal to the progress scale image for the people group

     Let us now handle the two links that need URLS (.country-link, and .pg-link). We will use JQuery's .attr() method (JQuery Docs) to handle it. Here is the code:

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            var unreached = data[0];
            /* Set the text of each class to the appropriate data */
            $('.country-name').text(unreached['Ctry']);
            $('.pg-language').text(unreached['PrimaryLanguageName']);
            $('.pg-name').text(unreached['PeopNameInCountry']);
            $('.pg-religion').text(unreached['PrimaryReligion']);
            $('.pg-scale').text(unreached['JPScale']);
            $('.pg-scale-text').text(unreached['JPScaleText']);
            /* Handle the two links that need URL's*/
            $('.country-link').attr('href', unreached['CountryURL']);
            $('.pg-link').attr('href', unreached['PeopleGroupURL']);
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            var pTagSettings = {'color': 'red', 'font-weight': 'bold'};
            var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);
            $('body').prepend(pTag);
        });
    });
</script>
                    

     If you refresh the page, you may not see a difference. Just hover your mouse over either the people group name or country name and verify the URL is set. So here is what is remaining:

Widget Classes
ID/Class Data Accessible With Changes
id people‑group‑image unreached['PeopleGroupPhotoURL'] We will create an image with a src equal to the location of the people group's image. We will also set it's dimensions to 128 X 160
class pg‑evangelical unreached['PercentEvangelical'] We will set a percentage formatted number totaling the people group's percentage of Evangelicals
class pg‑population unreached['Population'] We will set a comma formatted number totaling the people group's population
id  progress‑scale‑image unreached['JPScaleImageURL'] We will create an image with a src equal to the progress scale image for the people group

     OK, we are getting close. Let us now tackle the two images. We will create an <img> tag similar to how we created the <p></p> tag in the .fail() callback ( Jquery Docs). We will use JQuery's .attr() method ( JQuery Docs) to set the src attribute, and JQuery's .css() method ( JQuery Docs) to add width and height. Finally, we will append the image to the element using JQuery's .append() method (JQuery Docs). Here is the code:

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            var unreached = data[0];
            /* Set the text of each class to the appropriate data */
            $('.country-name').text(unreached['Ctry']);
            $('.pg-language').text(unreached['PrimaryLanguageName']);
            $('.pg-name').text(unreached['PeopNameInCountry']);
            $('.pg-religion').text(unreached['PrimaryReligion']);
            $('.pg-scale').text(unreached['JPScale']);
            $('.pg-scale-text').text(unreached['JPScaleText']);
            /* Handle the two links that need URL's*/
            $('.country-link').attr('href', unreached['CountryURL']);
            $('.pg-link').attr('href', unreached['PeopleGroupURL']);
            /* Append the images */
            var pgSettings = {'height': '160px', 'width': '128px'};
            var pgImg = $('<img/>').attr('src', unreached['PeopleGroupPhotoURL']).css(pgSettings);
            $('#people-group-image').append(pgImg);
            var scaleImg = $('<img/>').attr('src', unreached['JPScaleImageURL']);
            $('#progress-scale-image').append(scaleImg);
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            var pTagSettings = {'color': 'red', 'font-weight': 'bold'};
            var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);
            $('body').prepend(pTag);
        });
    });
</script>
                    

     If you refresh the page in your browser, you should see something like this:

Snapshot of the images

     So here is what is remaining:

Widget Classes
ID/Class Data Accessible With Changes
class pg‑evangelical unreached['PercentEvangelical'] We will set a percentage formatted number totaling the people group's percentage of Evangelicals
class pg‑population unreached['Population'] We will set a comma formatted number totaling the people group's population

     So let's tackle the percentage of Evangelicals in the people group. We first need to check if it is set to null, if so then we will display 0.00. If not null, we will use Javascript's parseFloat() method ( Docs) to turn the number to a float. After that we format it to 2 decimals using Javascripts toFixed() method ( Docs). Finally, we will use JQuery's .text() method ( JQuery Docs) to set the text for the element. Here is the code:

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            var unreached = data[0];
            /* Set the text of each class to the appropriate data */
            $('.country-name').text(unreached['Ctry']);
            $('.pg-language').text(unreached['PrimaryLanguageName']);
            $('.pg-name').text(unreached['PeopNameInCountry']);
            $('.pg-religion').text(unreached['PrimaryReligion']);
            $('.pg-scale').text(unreached['JPScale']);
            $('.pg-scale-text').text(unreached['JPScaleText']);
            /* Handle the two links that need URL's*/
            $('.country-link').attr('href', unreached['CountryURL']);
            $('.pg-link').attr('href', unreached['PeopleGroupURL']);
            /* Append the images */
            var pgSettings = {'height': '160px', 'width': '128px'};
            var pgImg = $('<img/>').attr('src', unreached['PeopleGroupPhotoURL']).css(pgSettings);
            $('#people-group-image').append(pgImg);
            var scaleImg = $('<img/>').attr('src', unreached['JPScaleImageURL']);
            $('#progress-scale-image').append(scaleImg);
            /* Set the Percent Evangelical */
            if (unreached['PercentEvangelical'] == null) {
                percent_evangelical = '0.00';
            } else {
                percent_evangelical = parseFloat(unreached['PercentEvangelical']).toFixed(2);
            };
            $('.pg-evangelical').text(percent_evangelical+'%');
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            var pTagSettings = {'color': 'red', 'font-weight': 'bold'};
            var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);
            $('body').prepend(pTag);
        });
    });
</script>
                    

     Once you reload the web page, you should now see the percentage like this:

Percent Evangelical

     So we only have one item remaining:

Widget Classes
ID/Class Data Accessible With Changes
class pg‑population unreached['Population'] We will set a comma formatted number totaling the people group's population

     First, we will need to create a custom function for formatting a comma seperated value. We will use Javascript's toString() method ( Docs) to make sure the value is a string. We then will use Regular Expressions to format it. Here is the code:

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            var unreached = data[0];
            /* Set the text of each class to the appropriate data */
            $('.country-name').text(unreached['Ctry']);
            $('.pg-language').text(unreached['PrimaryLanguageName']);
            $('.pg-name').text(unreached['PeopNameInCountry']);
            $('.pg-religion').text(unreached['PrimaryReligion']);
            $('.pg-scale').text(unreached['JPScale']);
            $('.pg-scale-text').text(unreached['JPScaleText']);
            /* Handle the two links that need URL's*/
            $('.country-link').attr('href', unreached['CountryURL']);
            $('.pg-link').attr('href', unreached['PeopleGroupURL']);
            /* Append the images */
            var pgSettings = {'height': '160px', 'width': '128px'};
            var pgImg = $('<img/>').attr('src', unreached['PeopleGroupPhotoURL']).css(pgSettings);
            $('#people-group-image').append(pgImg);
            var scaleImg = $('<img/>').attr('src', unreached['JPScaleImageURL']);
            $('#progress-scale-image').append(scaleImg);
            /* Set the Percent Evangelical */
            if (unreached['PercentEvangelical'] == null) {
                percent_evangelical = '0.00';
            } else {
                percent_evangelical = parseFloat(unreached['PercentEvangelical']).toFixed(2);
            };
            $('.pg-evangelical').text(percent_evangelical+'%');
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            var pTagSettings = {'color': 'red', 'font-weight': 'bold'};
            var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);
            $('body').prepend(pTag);
        });
    });
    /* Number formating method. */
    function numberWithCommas(x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    };
</script>
                    

     Finally we use JQuery's .text() method. ( JQuery Docs) to set the text of the element.

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            var unreached = data[0];
            /* Set the text of each class to the appropriate data */
            $('.country-name').text(unreached['Ctry']);
            $('.pg-language').text(unreached['PrimaryLanguageName']);
            $('.pg-name').text(unreached['PeopNameInCountry']);
            $('.pg-religion').text(unreached['PrimaryReligion']);
            $('.pg-scale').text(unreached['JPScale']);
            $('.pg-scale-text').text(unreached['JPScaleText']);
            /* Handle the two links that need URL's*/
            $('.country-link').attr('href', unreached['CountryURL']);
            $('.pg-link').attr('href', unreached['PeopleGroupURL']);
            /* Append the images */
            var pgSettings = {'height': '160px', 'width': '128px'};
            var pgImg = $('<img/>').attr('src', unreached['PeopleGroupPhotoURL']).css(pgSettings);
            $('#people-group-image').append(pgImg);
            var scaleImg = $('<img/>').attr('src', unreached['JPScaleImageURL']);
            $('#progress-scale-image').append(scaleImg);
            /* Set the Percent Evangelical */
            if (unreached['PercentEvangelical'] == null) {
                percent_evangelical = '0.00';
            } else {
                percent_evangelical = parseFloat(unreached['PercentEvangelical']).toFixed(2);
            };
            $('.pg-evangelical').text(percent_evangelical+'%');
            /* Set the Population */
            $('.pg-population').text(numberWithCommas(unreached['Population']));
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            var pTagSettings = {'color': 'red', 'font-weight': 'bold'};
            var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);
            $('body').prepend(pTag);
        });
    });
    /* Number formating method. */
    function numberWithCommas(x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    };
</script>
                    

     Here is the final result of our newly created widget:

Snapshot of Final Widget

Finishing Touches

     If you reload the web page, you will notice a delay before all the information is correctly displayed. Visitors may find this unappealing. So we will hide the widget, and display it when it is ready. First we need to add a hidden class to the widget. This class hides the widget from view. Here is the code:

<div id="jp_widget" class="hidden">
    <div class="upgotd upgotd-title">
        <a href="http://www.joshuaproject.net/upgotdfeed.php" class="upgotd-link">Unreached of the Day</a>
    </div>
    <div class="upgotd-image">
        <a href="#" class="upgotd-link pg-link" id="people-group-image">
        </a>
    </div>
    <div class="upgotd upgotd-pray">Please pray for the ...</div>
    <div class="upgotd upgotd-people">
        <a
        href="#"
        class="upgotd-link pg-link pg-name">
        </a> of
        <a
        href="#"
        class="upgotd-link country-link country-name">
        </a>
    </div>
    <table align="center" class="upgotd-table" cellpadding="0" cellspacing="0">
        <tbody><tr>
            <td width="65">Population:</td>
            <td width="135" class="pg-population"></td>
        </tr>
        <tr>
            <td>Language:</td>
            <td class="pg-language"></td>
        </tr>
        <tr>
            <td>Religion:</td>
            <td class="pg-religion"></td>
        </tr>
        <tr>
            <td>Evangelical:</td>
            <td class="pg-evangelical"></td>
        </tr>
        <tr>
            <td>Status:</td>
            <td>
                <a
                href="http://www.joshuaproject.net/definitions.php?term=25"
                class="upgotd-link pg-scale-text">
                </a> (
                <a
                href="http://www.joshuaproject.net/global-progress-scale.php"
                class="upgotd-link pg-scale">
                </a> 
                <a
                href="http://www.joshuaproject.net/global-progress-scale.php"
                class="upgotd-link"
                id="progress-scale-image">
                </a>)
            </td>
        </tr>
    </tbody></table>
    <div class="upgotd upgotd-footer">
    Add this daily global vision feature to <br>
    <a
    href="/upgotdfeed.php"
    class="upgotd-link">
    your website</a> or get it
    <a
    href="http://www.unreachedoftheday.org/unreached-email.php"
    class="upgotd-link">
    by email
    </a>.
    </div>
</div>
                    

     Then we will use JQuery's .fadeIn() method ( JQuery Docs) to fade in the widget when we finished setting it up.

<script type="text/javascript">
    var DOMAIN = 'http://api.joshuaproject.net';
    var API_KEY = "YOUR_API_KEY";
    jQuery(document).ready(function($) {
        $.ajax({
            url: DOMAIN+'/v1/people_groups/daily_unreached.json',
            dataType: 'json',
            data: {api_key: API_KEY},
            type: 'GET'
        })
        .done(function(data) {
            var unreached = data[0];
            /* Set the text of each class to the appropriate data */
            $('.country-name').text(unreached['Ctry']);
            $('.pg-language').text(unreached['PrimaryLanguageName']);
            $('.pg-name').text(unreached['PeopNameInCountry']);
            $('.pg-religion').text(unreached['PrimaryReligion']);
            $('.pg-scale').text(unreached['JPScale']);
            $('.pg-scale-text').text(unreached['JPScaleText']);
            /* Handle the two links that need URL's*/
            $('.country-link').attr('href', unreached['CountryURL']);
            $('.pg-link').attr('href', unreached['PeopleGroupURL']);
            /* Append the images */
            var pgSettings = {'height': '160px', 'width': '128px'};
            var pgImg = $('<img/>').attr('src', unreached['PeopleGroupPhotoURL']).css(pgSettings);
            $('#people-group-image').append(pgImg);
            var scaleImg = $('<img/>').attr('src', unreached['JPScaleImageURL']);
            $('#progress-scale-image').append(scaleImg);
            /* Set the Percent Evangelical */
            if (unreached['PercentEvangelical'] == null) {
                percent_evangelical = '0.00';
            } else {
                percent_evangelical = parseFloat(unreached['PercentEvangelical']).toFixed(2);
            };
            $('.pg-evangelical').text(percent_evangelical+'%');
            /* Set the Population */
            $('.pg-population').text(numberWithCommas(unreached['Population']));
            /* Fade in the widget */
            $('div#jp_widget').fadeIn('slow');
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            var pTagSettings = {'color': 'red', 'font-weight': 'bold'};
            var pTag = $('<p/>').text('There was an error: '+errorThrown).css(pTagSettings);
            $('body').prepend(pTag);
        });
    });
    /* Number formating method. */
    function numberWithCommas(x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    };
</script>
                    

     Congratulations! You have completed the Javascript tutorial. If you would like to download the sample code, you can visit our Github Account .

Setup

     Before you start this tutorial, you will need some understanding of the PHP programming language. You will also need a PHP environment setup on your local machine , or be able to upload your code to a PHP web server. This tutorial does not cover how to accomplish that. Once you have an environment setup, you will need to download the starting code.

Calling the API

     Open the index.php file in your favorite text editor. Let us start by creating 3 variables to hold the API domain, API key, and the URL to get the unreached of the day information. Remember to add your API key! Add the following code to the top of the index.php file:

<?php
$domain = "http://api.joshuaproject.net";
$api_key = "YOUR_API_KEY";
$url = $domain . "/v1/people_groups/daily_unreached.json?api_key=" . $api_key;
?>
                    

     To access an API with PHP, we need to use the cURL Library.

cURL is a computer software project providing a library and command-line tool for transferring data using various protocols.

Wikipedia

     PHP offers methods for making cURL requests in the code. Let us begin by opening a cURL connection using PHP's curl_init() function ( PHP DOCS).

<?php
$domain = "http://api.joshuaproject.net";
$api_key = "YOUR_API_KEY";
$url = $domain . "/v1/people_groups/daily_unreached.json?api_key=" . $api_key;
/**
 * open connection
 *
 * @author Johnathan Pulos
 */
$ch = curl_init();
?>
                    

     Next we need to set some options for the request using PHP's curl_setopt() function ( PHP DOCS).

<?php
$domain = "http://api.joshuaproject.net";
$api_key = "YOUR_API_KEY";
$url = $domain . "/v1/people_groups/daily_unreached.json?api_key=" . $api_key;
/**
 * open connection
 *
 * @author Johnathan Pulos
 */
$ch = curl_init();
/**
 * Setup cURL
 *
 * @author Johnathan Pulos
 */
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
?>
                    

     Here are the options that we set:

Option Description Value
CURLOPT_URL The URL to fetch http://api.joshuaproject.net/v1/people_groups/daily_unreached.json?api_key=YOUR_API_KEY
CURLOPT_RETURNTRANSFER Returns the response from CURL_EXEC as a string 1 (true)
CURLOPT_TIMEOUT The maximum number of seconds cURL should execute request 60 seconds
CURLOPT_CUSTOMREQUEST Set a custom HTTP request method GET

     Now we need to execute the cURL request using PHP's curl_exec() function ( PHP DOCS). If the request fails, we will call PHP's die() function ( PHP DOCS) to stop executing the script. If it is successful, we will assign the result to a variable so we can access the JSON response.

<?php
$domain = "http://api.joshuaproject.net";
$api_key = "YOUR_API_KEY";
$url = $domain . "/v1/people_groups/daily_unreached.json?api_key=" . $api_key;
/**
 * open connection
 *
 * @author Johnathan Pulos
 */
$ch = curl_init();
/**
 * Setup cURL
 *
 * @author Johnathan Pulos
 */
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
/**
 * execute request
 *
 * @author Johnathan Pulos
 */
$result = curl_exec($ch) or die(curl_error($ch));
?>
                    

     Now we need to clean up by closing the cURL request. We do this by using PHP's curl_close() function ( PHP DOCS).

<?php
$domain = "http://api.joshuaproject.net";
$api_key = "YOUR_API_KEY";
$url = $domain . "/v1/people_groups/daily_unreached.json?api_key=" . $api_key;
/**
 * open connection
 *
 * @author Johnathan Pulos
 */
$ch = curl_init();
/**
 * Setup cURL
 *
 * @author Johnathan Pulos
 */
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
/**
 * execute request
 *
 * @author Johnathan Pulos
 */
$result = curl_exec($ch) or die(curl_error($ch));
/**
 * close connection
 *
 * @author Johnathan Pulos
 */
curl_close($ch);
?>
                    

     We have now completed the request. Let's add some temporary code to verify we have the data. We will remove this code before moving forward.

<?php
$domain = "http://api.joshuaproject.net";
$api_key = "YOUR_API_KEY";
$url = $domain . "/v1/people_groups/daily_unreached.json?api_key=" . $api_key;
/**
 * open connection
 *
 * @author Johnathan Pulos
 */
$ch = curl_init();
/**
 * Setup cURL
 *
 * @author Johnathan Pulos
 */
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
/**
 * execute request
 *
 * @author Johnathan Pulos
 */
$result = curl_exec($ch) or die(curl_error($ch));
/**
 * close connection
 *
 * @author Johnathan Pulos
 */
curl_close($ch);
/**
 * TEMP: Print out the results
 *
 * @author Johnathan Pulos
 */
print_r($result);
exit();
?>
                    

     When you save and run this code, you will see something similar to the response code we showed up above. If you do not get a response, then you need to check if you created your URL structure correctly. As you can see in the response, we are receiving a PHP Array of a single JSON object. In order to use this JSON object in PHP, we need to convert it to a PHP multidimensional array. We can do this with a handy PHP function decoded_json() ( PHP DOCS)

<?php
$domain = "http://api.joshuaproject.net";
$api_key = "YOUR_API_KEY";
$url = $domain . "/v1/people_groups/daily_unreached.json?api_key=" . $api_key;
/**
 * open connection
 *
 * @author Johnathan Pulos
 */
$ch = curl_init();
/**
 * Setup cURL
 *
 * @author Johnathan Pulos
 */
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
/**
 * execute request
 *
 * @author Johnathan Pulos
 */
$result = curl_exec($ch) or die(curl_error($ch));
/**
 * close connection
 *
 * @author Johnathan Pulos
 */
curl_close($ch);
/**
 * decode the response JSON
 *
 * @author Johnathan Pulos
 */
$decoded_json = json_decode($result, true);
?>
                    

     We should also add error checking. If the multidimensional array is not an array, we will stop executing the code with a message. We will use PHP's is_array() function ( PHP Docs) to do the check.

<?php
$domain = "http://api.joshuaproject.net";
$api_key = "YOUR_API_KEY";
$url = $domain . "/v1/people_groups/daily_unreached.json?api_key=" . $api_key;
/**
 * open connection
 *
 * @author Johnathan Pulos
 */
$ch = curl_init();
/**
 * Setup cURL
 *
 * @author Johnathan Pulos
 */
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
/**
 * execute request
 *
 * @author Johnathan Pulos
 */
$result = curl_exec($ch) or die(curl_error($ch));
/**
 * close connection
 *
 * @author Johnathan Pulos
 */
curl_close($ch);
/**
 * decode the response JSON
 *
 * @author Johnathan Pulos
 */
$decoded_json = json_decode($result, true);
if (!is_array($decoded_json)) {
    echo "Unable to retrieve the JSON.";
    exit;
}
?>
                    

     Now that we created a multidimensional array, we can access the first object using its index like this: $decoded_json[0]. We will set this to a variable for easy access.

<?php
$domain = "http://api.joshuaproject.net";
$api_key = "YOUR_API_KEY";
$url = $domain . "/v1/people_groups/daily_unreached.json?api_key=" . $api_key;
/**
 * open connection
 *
 * @author Johnathan Pulos
 */
$ch = curl_init();
/**
 * Setup cURL
 *
 * @author Johnathan Pulos
 */
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
/**
 * execute request
 *
 * @author Johnathan Pulos
 */
$result = curl_exec($ch) or die(curl_error($ch));
/**
 * close connection
 *
 * @author Johnathan Pulos
 */
curl_close($ch);
/**
 * decode the response JSON
 *
 * @author Johnathan Pulos
 */
$decoded_json = json_decode($result, true);
if (!is_array($decoded_json)) {
    echo "Unable to retrieve the JSON.";
    exit;
}
/**
 * Assign the first object to a variable
 *
 * @author Johnathan Pulos
 */
$unreached = $decoded_json[0];
?>
                    

Creating the Widget

     Now we can access any of the supplied attributes of that JSON object using it's key. So if we want to get the people group's name, we can access it like this: $unreached['PeopNameInCountry'].

     There are a few attributes that need to be formatted correctly. The attribute percentage of Evangelicals in the people group can be set to null, if so then we should display 0.00. So let's add a check to evaluate the value, and set it to 0 if it is null. Here is the code:

<?php
$domain = "http://api.joshuaproject.net";
$api_key = "YOUR_API_KEY";
$url = $domain . "/v1/people_groups/daily_unreached.json?api_key=" . $api_key;
/**
 * open connection
 *
 * @author Johnathan Pulos
 */
$ch = curl_init();
/**
 * Setup cURL
 *
 * @author Johnathan Pulos
 */
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
/**
 * execute request
 *
 * @author Johnathan Pulos
 */
$result = curl_exec($ch) or die(curl_error($ch));
/**
 * close connection
 *
 * @author Johnathan Pulos
 */
curl_close($ch);
/**
 * decode the response JSON
 *
 * @author Johnathan Pulos
 */
$decoded_json = json_decode($result, true);
if (!is_array($decoded_json)) {
    echo "Unable to retrieve the JSON.";
    exit;
}
/**
 * Assign the first object to a variable
 *
 * @author Johnathan Pulos
 */
$unreached = $decoded_json[0];
/**
 * Handle the null value
 *
 * @author Johnathan Pulos
 */
if ($unreached['PercentEvangelical'] == null) {
    $unreached['PercentEvangelical'] = 0;
}
?>
                    

     Now we just need to add the data to the HTML widget code for displaying. We will use PHP's echo() function ( PHP DOCS) to display the data in the appropriate place. We will also use PHP's number_format() function ( PHP DOCS) to format the people group's population, and percent of Evangelicals. In the HTML portion of the index.php file, update the code to what is below:

<div id="jp_widget">
    <div class="upgotd upgotd-title">
        <a href="http://www.joshuaproject.net/upgotdfeed.php" class="upgotd-link">Unreached of the Day</a>
    </div>
    <div class="upgotd-image">
        <a href="
        <?php echo $unreached['PeopleGroupURL']; ?>
        " class="upgotd-link pg-link" id="people-group-image">
            <img src="
                <?php echo $unreached['PeopleGroupPhotoURL']; ?>
                " height="160" width="128" alt="Unreached of the Day Photo">
        </a>
    </div>
    <div class="upgotd upgotd-pray">Please pray for the ...</div>
    <div class="upgotd upgotd-people">
        <a href="<?php echo $unreached['PeopleGroupURL']; ?>"
        class="upgotd-link pg-link pg-name">
        <?php echo $unreached['PeopNameInCountry']; ?>
        </a> of
        <a href="<?php echo $unreached['CountryURL']; ?>"
        class="upgotd-link country-link country-name">
        <?php echo $unreached['Ctry']; ?>
        </a>
    </div>
    <table align="center" class="upgotd-table" cellpadding="0" cellspacing="0">
        <tbody>
        <tr>
            <td width="65">
                Population:
            </td>
            <td width="135" class="pg-population">
                <?php echo number_format($unreached['Population']); ?>
            </td>
        </tr>
        <tr>
            <td>
                Language:
            </td>
            <td class="pg-language">
                <?php echo $unreached['PrimaryLanguageName']; ?>
            </td>
        </tr>
        <tr>
            <td>
                Religion:
            </td>
            <td class="pg-religion">
                <?php echo $unreached['PrimaryReligion']; ?>
            </td>
        </tr>
        <tr>
            <td>
                Evangelical:
            </td>
            <td class="pg-evangelical">
            <?php echo number_format($unreached['PercentEvangelical'], 2); ?>%
            </td>
        </tr>
        <tr>
            <td>Status:</td>
            <td>
                <a href="http://www.joshuaproject.net/definitions.php?term=25" class="upgotd-link pg-scale-text">
                    <?php echo $unreached['JPScaleText']; ?>
                </a> (
                <a href="http://www.joshuaproject.net/global-progress-scale.php" class="upgotd-link pg-scale">
                    <?php echo $unreached['JPScale']; ?>
                </a>
                <a
                href="http://www.joshuaproject.net/global-progress-scale.php"
                class="upgotd-link"
                id="progress-scale-image">
                <img
                    src="<?php echo $unreached['JPScaleImageURL']; ?>"
                    alt="Progress Scale">
                </a>)
            </td>
        </tr>
    </tbody></table>
    <div class="upgotd upgotd-footer">
        Add this daily global vision feature to <br>
        <a href="/upgotdfeed.php" class="upgotd-link">your website</a> or get it
        <a href="http://www.unreachedoftheday.org/unreached-email.php" class="upgotd-link">by email</a>.
    </div>
</div>
                    

     If you reload the webpage, you should see the widget with all the API data. Your data might be different.

Snapshot of Final Widget

     Mine looks different! If you do not supply a month or day parameter, the API will return today's unreached people group of the day by default. Most likely you are not doing this tutorial the same day as I was.

     Congratulations! You have completed the PHP tutorial. If you would like to download the sample code, you can visit our Github Account.

Setup

     Before starting this tutorial, you will need to have some understanding of the Python programming language. We will be using Python version 3.3. You will also need Python running in your command line utility. This tutorial does not show how to install Python.

     In this tutorial, we will build a generator that creates the necessary HTML & CSS for the widget. Everytime you run the script from the command line, it will create the widget with the latest people group data. Once you have downloaded and unzipped the Python starting code, open it up and look around. Here is the basic code structure:

  • css - directory for CSS Stylesheets
    • styles.css - the basic styles for the widget
  • generated_code - directory for the code created by our generator
  • templates - directory for the HTML templates
    • index.html - the HTML template for the widget
  • generate_widget.py - the generator script we will build

     Go ahead and open the generate_widget.py file in your favorite text editor. We will begin by including several Python modules using the import statement ( Python Docs). We will need the following modules: json ( Python Docs), urllib.request ( Python Docs), urllib.error ( Python Docs), string ( Python Docs), and sys (Python Docs). The code looks like this:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
                    

Calling the API

     Now that we have imported the necessary modules, we will need to generate the API request. We will start by creating 3 variables for the API domain, API key, and the API URL for the request. Remember to add your API key! Here is the code:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
                    

     We will call the API within a try...except block. ( Python Docs) Using Python's urllib.error module ( Python Docs ), we will be warned if the API request returns aHTTPError or URLError. Here is the block:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
                    

     Now if there is a HTTPError or URLError, we will be able to see what happened. Now we need to make the request using the urllib.request module ( Python Docs) by calling the urlopen() function ( Python Docs). Here is the code:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
                    

     If everything is done correctly, we should be able to run the code from your command line utility, and see no errors. Let's add some temporary code to see if we got a response. Add the following code:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
    response = request.read()
    print(response)
                    

     If everything went according to plan, you should see something similar to the API response shown above. Using the response of the request, which is set to the request variable, we need to use the .read() function of the urllib.request module ( Python Docs). We will also need to use the decode() function of the module to decode it to UTF-8. Here is how it should be written:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
    # decode the response
    response = request.read().decode("utf8")
                    

     Next we need to convert the JSON to a Python object using the json module's (Python Docs ) loads() function ( Python Docs ). We will also print out the result temporarily so we can look at it. Here is how you will accomplish this:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
    # decode the response
    response = request.read().decode("utf8")
    # load the JSON
    data = json.loads(response)
    print(data)
                    

     If you look at the response, you can see that we have a Python list ( Python Docs) containing a single Python dict ( Python Docs). To access the first dict, we can refer to it using the index of 0 similar to data[0]. So let's set a variable to the first dict:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
    # decode the response
    response = request.read().decode("utf8")
    # load the JSON
    data = json.loads(response)
    unreached = data[0]
                    

Creating the Widget

     Now we can access any of the supplied attributes of that dict object using it's key. So if we want to get the people group's name, we can access it like this: unreached['PeopNameInCountry'].

     Let's now turn our attention to formating the data for proper displaying. The population of the people group needs to be a comma seperated number. We will first convert the population to an integer using Python's built-in int() function. ( Python Docs) We will then use Python's built-in format() function ( Python Docs) to format it into a comma seperated integer. Here is the resulting code:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
    # decode the response
    response = request.read().decode("utf8")
    # load the JSON
    data = json.loads(response)
    unreached = data[0]
    # format population to be a comma seperated integer
    unreached['Population'] = format(int(unreached['Population']), ',d')
                    

     Another formatting issue is related to the percent of Evangelicals. It is possible that it will be set to null. I would prefer to show 0.00 instead of null. So we will use Python's if condition to check if the percent of Evangelicals is None, if so we will set it to 0. We will then use Python's built-in float() function ( Python Docs) to format it as a floating point (decimal). Here is the code:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
    # decode the response
    response = request.read().decode("utf8")
    # load the JSON
    data = json.loads(response)
    unreached = data[0]
    # format population to be a comma seperated integer
    unreached['Population'] = format(int(unreached['Population']), ',d')
    # check if percent of Evangelicals is None
    if unreached['PercentEvangelical'] is None:
        unreached['PercentEvangelical'] = '0'
    # format percent of Evangelicals to percent
    unreached['PercentEvangelical'] = float(unreached['PercentEvangelical'])
                    

     So we are now on the last stretch! All we have to do now is generate the widget HTML file. We will use Python's Template strings ( Python Docs) in order to substitute unique $-based variables in our template file with the unreached people group information we already retrieved. After we have replaced everything, we will then save the final file as generated_code/widget.html. First, open the templates/index.html file. Now add the following $-based variables to the file:

<!DOCTYPE html>
<html>
    <head>
        <title>Joshua Project | Sample Code (Javascript)</title>
        <link rel="stylesheet" type="text/css" href="../../css/styles.css">
    </head>
    <body>
        <p>
            This Sample Code is designed to demonstrate how to retrieve the Daily Unreached from the
            <a href="" class="domain-link">Joshua Project API</a> using Python.
        </p>
        <div id="jp_widget">
            <div class="upgotd upgotd-title">
                <a href="http://www.joshuaproject.net/upgotdfeed.php" class="upgotd-link">
                Unreached of the Day
                </a>
            </div>
            <div class="upgotd-image">
                <a
                href="$PeopleGroupURL"
                class="upgotd-link pg-link"
                id="people-group-image">
                    <img
                    src="$PeopleGroupPhotoURL"
                    height="160"
                    width="128"
                    alt="Unreached of the Day Photo">
                </a>
            </div>
            <div class="upgotd upgotd-pray">Please pray for the ...</div>
            <div class="upgotd upgotd-people">
                <a
                href="$PeopleGroupURL"
                class="upgotd-link pg-link pg-name">
                $PeopNameInCountry
                </a> of
                <a
                href="$CountryURL"
                class="upgotd-link country-link country-name">
                $Ctry
                </a>
            </div>
            <table align="center" class="upgotd-table" cellpadding="0" cellspacing="0">
                <tbody><tr>
                    <td width="65">Population:</td>
                    <td width="135" class="pg-population">
                    $Population
                    </td>
                </tr>
                <tr>
                    <td>Language:</td>
                    <td class="pg-language">
                    $PrimaryLanguageName
                    </td>
                </tr>
                <tr>
                    <td>Religion:</td>
                    <td class="pg-religion">
                    $PrimaryReligion
                    </td>
                </tr>
                <tr>
                    <td>Evangelical:</td>
                    <td class="pg-evangelical">
                    $PercentEvangelical%
                    </td>
                </tr>
                <tr>
                    <td>Status:</td>
                    <td>
                        <a
                        href="http://www.joshuaproject.net/definitions.php?term=25"
                        class="upgotd-link pg-scale-text">
                            $JPScaleText
                        </a> (
                        <a
                        href="http://www.joshuaproject.net/global-progress-scale.php"
                        class="upgotd-link pg-scale">
                            $JPScale
                        </a>
                        <a
                        href="http://www.joshuaproject.net/global-progress-scale.php"
                        class="upgotd-link"
                        id="progress-scale-image">
                            <img src="$JPScaleImageURL" alt="Progress Scale">
                        </a>)
                    </td>
                </tr>
            </tbody></table>
            <div class="upgotd upgotd-footer">Add this daily global vision feature to
            <br><a href="/upgotdfeed.php" class="upgotd-link">your website</a> or
            get it <a href="http://www.unreachedoftheday.org/unreached-email.php" class="upgotd-link">
            by email</a>.</div>
        </div>
    </body>
</html>
                    

     As you can see in the code above, we will use Python's Template strings ( Python Docs) to replace $Population with unreached['Population'] in our generate_widget.py script. The first step is to retrieve the template file using Python's built-in open() function ( Python Docs) which will open the file. After opening the file, we want to use Python's file object .read() function ( Python Docs) to read the file contents into a variable. here is the code:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
    # decode the response
    response = request.read().decode("utf8")
    # load the JSON
    data = json.loads(response)
    unreached = data[0]
    # format population to be a comma seperated integer
    unreached['Population'] = format(int(unreached['Population']), ',d')
    # check if percent of Evangelicals is None
    if unreached['PercentEvangelical'] is None:
        unreached['PercentEvangelical'] = '0'
    # format percent of Evangelicals to percent
    unreached['PercentEvangelical'] = float(unreached['PercentEvangelical'])
    # get the template file
    index_file = open('templates/index.html').read()
                    

     Now that we have the template file's content, we can feed that to Python's string.Template function ( Python Docs) to initialize a new template. Here is the code:

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
    # decode the response
    response = request.read().decode("utf8")
    # load the JSON
    data = json.loads(response)
    unreached = data[0]
    # format population to be a comma seperated integer
    unreached['Population'] = format(int(unreached['Population']), ',d')
    # check if percent of Evangelicals is None
    if unreached['PercentEvangelical'] is None:
        unreached['PercentEvangelical'] = '0'
    # format percent of Evangelicals to percent
    unreached['PercentEvangelical'] = float(unreached['PercentEvangelical'])
    # get the template file
    index_file = open('templates/index.html').read()
    # initialize a new template
    template = string.Template(index_file)
                    

     Let's trigger the substitution of the $-based variables using Python's string.Template .substitute() function ( Python Docs) on the new template object we created. We will pass into it the unreached variable for replacement.

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
    # decode the response
    response = request.read().decode("utf8")
    # load the JSON
    data = json.loads(response)
    unreached = data[0]
    # format population to be a comma seperated integer
    unreached['Population'] = format(int(unreached['Population']), ',d')
    # check if percent of Evangelicals is None
    if unreached['PercentEvangelical'] is None:
        unreached['PercentEvangelical'] = '0'
    # format percent of Evangelicals to percent
    unreached['PercentEvangelical'] = float(unreached['PercentEvangelical'])
    # get the template file
    index_file = open('templates/index.html').read()
    # initialize a new template
    template = string.Template(index_file)
    # make the substitution
    final_code = template.substitute(unreached)
                    

     The variable final_code now holds the final code we need to write into our generated_code/widget.html file. We will use Python's built-in open() function ( Python Docs) to open the new file. You will notice that we added a second parameter ('w') to make the file writable. We will finally write the file using Python's file object .write() function ( Python Docs) passing it the final_code variable.

#!/usr/bin/python
# import the necessary libraries
import json
import urllib.request
import urllib.error
import string
import sys
# set some important variables
domain = "http://api.joshuaproject.net"
api_key = "YOUR_API_KEY"
url = domain+"/v1/people_groups/daily_unreached.json?api_key="+api_key
try:
    # request the API for the Daily Unreached People Group
    request = urllib.request.urlopen(api_url)
except urllib.error.HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
    exit
except urllib.error.URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
    exit
else:
    # Everything worked
    # decode the response
    response = request.read().decode("utf8")
    # load the JSON
    data = json.loads(response)
    unreached = data[0]
    # format population to be a comma seperated integer
    unreached['Population'] = format(int(unreached['Population']), ',d')
    # check if percent of Evangelicals is None
    if unreached['PercentEvangelical'] is None:
        unreached['PercentEvangelical'] = '0'
    # format percent of Evangelicals to percent
    unreached['PercentEvangelical'] = float(unreached['PercentEvangelical'])
    # get the template file
    index_file = open('templates/index.html').read()
    # initialize a new template
    template = string.Template(index_file)
    # make the substitution
    final_code = template.substitute(unreached)
    # create the widget.html file
    widget_file = open('generated_code/widget.html','w')
    widget_file.write(final_code)
                    

     If you run this script from your command line utility, you will see that it generates the generated_code/widget.html file. Now open that file in your favorite web browser. You should see something similar to this:

Snapshot of Final Widget

     Mine looks different! If you do not supply a month or day parameter, the API will return today's unreached people group of the day by default. Most likely you are not doing this tutorial the same day as I was.

     Congratulations! You have completed the Python tutorial. If you would like to download the sample code, you can visit our Github Account.

Setup

     Before starting this tutorial, you will need to have a basic understanding of the Ruby programming language. We will be using Ruby version 2.0 in this tutorial. You will also need to be able to run ruby scripts in your command line utility. This tutorial does not discuss how to install Ruby.

     In this tutorial, we will build a generator that creates the necessary HTML & CSS for the widget. Everytime you run the script from the command line, it will create the widget with the latest people group data. Once you have downloaded and unzipped the Ruby starting code, open it up and look around. Here is the basic code structure:

  • css - directory for CSS Stylesheets
    • styles.css - the basic styles for the widget
  • generated_code - directory for the code created by our generator
  • templates - directory for the HTML/ERB templates
    • index.html.erb - the HTML/ERB template for the widget
  • generate_widget.rb - the generator script we will build

     Go ahead and open the generate_widget.rb file in your favorite text editor. We will begin by including any modules/gems we will need for the script. We will use Ruby's require method ( Ruby Docs) to include the Net/HTTP module ( Ruby Docs), and JSON module ( Ruby Docs). We will also need the Erubis gem. You will need to install Erubis using to command gem install erubis. Here is the start of our code:

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
                    

Calling the API

     Now that we have required the necessary gems/modules, we need to generated the API request. We will start by creating 3 variables for the API domain, API key, and the API path for the request. Remember to add your API key! Here is the code:

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
                    

     We will call the API in a Ruby begin...end block. ( Ruby Docs) This will allow us the opportunity to rescue from a failed request, and print out the error. Here is the block:

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
begin
    # Make the request to the Joshua Project API
rescue Exception => e
    # We had an error
    puts "Unable to get the API data"
    puts e.message
    abort
end
                    

     We will now use the Net/HTTP module ( Ruby Docs) to send the GET request to the API. We will use it's .get() method for this. ( Ruby Docs). We will then set the response to the variable response. Here is the code to accomplish this:

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
begin
    # Make the request to the Joshua Project API
    response = Net::HTTP.get(domain, api_path)
rescue Exception => e
    # We had an error
    puts "Unable to get the API data"
    puts e.message
    abort
end
                    

     Now that we have a response, we need to parse the JSON into a Ruby object. This is where the JSON module ( Ruby Docs) comes in handy. Weill use it's .parse() method ( Ruby Docs) to accomplish this. Let us also add some temporary code to display what we receive back. Here is the code:

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
begin
    # Make the request to the Joshua Project API
    response = Net::HTTP.get(domain, api_path)
    # Parse the response
    data = JSON.parse(response)
    puts data
rescue Exception => e
    # We had an error
    puts "Unable to get the API data"
    puts e.message
    abort
end
                    

     Now run this code in your command line utility, and you should see something very similar to the API response we showed you up top. The .parse() method ( Ruby Docs) converted the JSON to a Ruby Array ( Ruby Docs) of Hashes (Ruby Docs). To access the first Hash, we can use the Array index of the first object 0 like this: data[0].

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
begin
    # Make the request to the Joshua Project API
    response = Net::HTTP.get(domain, api_path)
    # Parse the response
    data = JSON.parse(response)
    unreached = data[0]
rescue Exception => e
    # We had an error
    puts "Unable to get the API data"
    puts e.message
    abort
end
                    

Creating the Widget

     Now we can access any of the supplied attributes of that Hash object using it's key. So if we want to get the people group's name, we can access it like this: unreached['PeopNameInCountry'].

     In order to display the information properly, we need to format the population and percent of Evangelicals. For the population, we want to format it as a comma seperated number. To do this, we will convert the population to a string using Ruby's .to_s method. ( Ruby Docs ) After converting it to a string, we will use Ruby's String .gsub() method ( Ruby Docs ) to use a Regular Expression to format the string. Here is the code to format the population:

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
begin
    # Make the request to the Joshua Project API
    response = Net::HTTP.get(domain, api_path)
    # Parse the response
    data = JSON.parse(response)
    unreached = data[0]
rescue Exception => e
    # We had an error
    puts "Unable to get the API data"
    puts e.message
    abort
end
# format the population to a comma seperated value
unreached['Population'] = unreached['Population'].to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,')
                    

     Sometimes the percent of Evangelicals can be nil. I would prefer to display 0.00 rather then nil. To do this, we will use Ruby's if...end block and the .nil? method ( Ruby Docs) to check it's value.

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
begin
    # Make the request to the Joshua Project API
    response = Net::HTTP.get(domain, api_path)
    # Parse the response
    data = JSON.parse(response)
    unreached = data[0]
rescue Exception => e
    # We had an error
    puts "Unable to get the API data"
    puts e.message
    abort
end
# format the population to a comma seperated value
unreached['Population'] = unreached['Population'].to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,')
# Lets handle the evangelical number since it can be nil
if unreached['PercentEvangelical'].nil?
    unreached['PercentEvangelical'] = "0.00"
else
    # format the percent to a floating point (decimal)
end
                    

     If the percent of Evangelicals is not nil, then we want to convert it to a floating point (decimal).

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
begin
    # Make the request to the Joshua Project API
    response = Net::HTTP.get(domain, api_path)
    # Parse the response
    data = JSON.parse(response)
    unreached = data[0]
rescue Exception => e
    # We had an error
    puts "Unable to get the API data"
    puts e.message
    abort
end
# format the population to a comma seperated value
unreached['Population'] = unreached['Population'].to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,')
# Lets handle the evangelical number since it can be nil
if unreached['PercentEvangelical'].nil?
    unreached['PercentEvangelical'] = "0.00"
else
    # format the percent to a floating point (decimal)
    unreached['PercentEvangelical'] = '%.2f' % unreached['PercentEvangelical']
end
                    

     Now that all the attributes have been formatted, we are ready to create the generated_code/widget.html file. We will use a common Ruby templating gem called Erubis. This templating engine gives us the ability to embed Ruby in a HTML template file. All Ruby is wrapped with a <% %> tag. Any ruby within those tags will be run when the template is processed. Open the templates/index.html.erb file and update with the following Erubis code:

<html>
    <head>
        <title>Joshua Project</title>
        <link rel="stylesheet" type="text/css" href="../css/styles.css">
    </head>
    <body>
        <div id="jp_widget">
            <div class="upgotd upgotd-title">
                <a href="http://www.joshuaproject.net/upgotdfeed.php" class="upgotd-link">
                Unreached of the Day</a>
            </div>
            <div class="upgotd-image">
                <a
                href="<%= unreached['PeopleGroupURL'] %>"
                class="upgotd-link pg-link"
                id="people-group-image">
                    <img
                    src="<%= unreached['PeopleGroupPhotoURL'] %>"
                    height="160"
                    width="128"
                    alt="Unreached of the Day Photo">
                </a>
            </div>
            <div class="upgotd upgotd-pray">Please pray for the ...</div>
            <div class="upgotd upgotd-people">
                <a
                href="<%= unreached['PeopleGroupURL'] %>"
                class="upgotd-link pg-link pg-name">
                <%= unreached['PeopNameInCountry'] %>
                </a> of
                <a
                href="<%= unreached['CountryURL'] %>"
                class="upgotd-link country-link country-name">
                <%= unreached['Ctry'] %>
                </a>
            </div>
            <table align="center" class="upgotd-table" cellpadding="0" cellspacing="0">
                <tbody><tr>
                    <td width="65">Population:</td>
                    <td width="135" class="pg-population">
                        <%= unreached['Population'] %>
                    </td>
                </tr>
                <tr>
                    <td>Language:</td>
                    <td class="pg-language">
                        <%= unreached['PrimaryLanguageName'] %>
                    </td>
                </tr>
                <tr>
                    <td>Religion:</td>
                    <td class="pg-religion">
                        <%= unreached['PrimaryReligion'] %>
                    </td>
                </tr>
                <tr>
                    <td>Evangelical:</td>
                    <td class="pg-evangelical">
                        <%= unreached['PercentEvangelical'] %>%
                    </td>
                </tr>
                <tr>
                    <td>Status:</td>
                    <td>
                        <a
                        href="http://www.joshuaproject.net/definitions.php?term=25"
                        class="upgotd-link pg-scale-text">
                            <%= unreached['JPScaleText'] %>
                        </a> (
                        <a
                        href="http://www.joshuaproject.net/global-progress-scale.php"
                        class="upgotd-link pg-scale">
                            <%= unreached['JPScale'] %>
                        </a>
                        <a
                        href="http://www.joshuaproject.net/global-progress-scale.php"
                        class="upgotd-link"
                        id="progress-scale-image">
                            <img
                            src="<%= unreached['JPScaleImageURL'] %>"
                            alt="Progress Scale">
                        </a>)
                    </td>
                </tr>
            </tbody></table>
            <div class="upgotd upgotd-footer">Add this daily global vision feature to
            <br><a href="/upgotdfeed.php" class="upgotd-link">your website</a>
            or get it <a
            href="http://www.unreachedoftheday.org/unreached-email.php"
            class="upgotd-link">
            by email
            </a>.
            </div>
        </div>
    </body>
</html>
                    

     As you can see in the code above, we will use Erubis to replace <% unreached['Population'] %> with unreached['Population'] in our generate_widget.rb script. So why does the Erubis code start with <%=? The equal (=) sign tells Erubis to print out the variable.

     We now need to read the templating file code into a variable using Ruby's File .read() method. ( Ruby Docs ) After we have the content in the variable, we need to pass it to a new instance of Erubis. We will finally use Erubis' .result() method to replace all the tags with the appropriate variables. Go back to the generate_widget.rb file and add the following code:

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
begin
    # Make the request to the Joshua Project API
    response = Net::HTTP.get(domain, api_path)
    # Parse the response
    data = JSON.parse(response)
    unreached = data[0]
rescue Exception => e
    # We had an error
    puts "Unable to get the API data"
    puts e.message
    abort
end
# format the population to a comma seperated value
unreached['Population'] = unreached['Population'].to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,')
# Lets handle the evangelical number since it can be nil
if unreached['PercentEvangelical'].nil?
    unreached['PercentEvangelical'] = "0.00"
else
    # format the percent to a floating point (decimal)
    unreached['PercentEvangelical'] = '%.2f' % unreached['PercentEvangelical']
end
# Generate the template
template_file = File.read("templates/index.html.erb")
template = Erubis::Eruby.new(template_file)
# run the Erubis substitution
widget_code = template.result({unreached: unreached})

                    

     We can now write the new templated code to the generated_code/widget.html file. In order to ensure that the file is written correctly, we will use Ruby's begin...rescue...ensure block. This will ensure that the file is closed in case something goes wrong. Add the following code:

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
begin
    # Make the request to the Joshua Project API
    response = Net::HTTP.get(domain, api_path)
    # Parse the response
    data = JSON.parse(response)
    unreached = data[0]
rescue Exception => e
    # We had an error
    puts "Unable to get the API data"
    puts e.message
    abort
end
# format the population to a comma seperated value
unreached['Population'] = unreached['Population'].to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,')
# Lets handle the evangelical number since it can be nil
if unreached['PercentEvangelical'].nil?
    unreached['PercentEvangelical'] = "0.00"
else
    # format the percent to a floating point (decimal)
    unreached['PercentEvangelical'] = '%.2f' % unreached['PercentEvangelical']
end
# We will write the final HTML file
begin
    # write the new file
rescue IOError => e
    # We had an error
    puts "Unable to write the HTML file"
    puts e.message
    abort
ensure
    # ensure the file closes happens if this fails
end
                    

     As you can see in the code, if an error occurs it will display on the screen. We now need to open the new file generated_code/widget.html for writing using Ruby's File .open() method. ( Ruby Docs) We will pass it the 'w' option to make it writable. We will also use Ruby's File .close() method ( Ruby Docs) in the ensure block to close the file. Here is the code:

# We will use Erubis for the templating
require "erubis"
# We need net/http to handle the request to the API
require "net/http"
# We will need to parse the JSON response
require "json"
# set some important variables
domain = "jpapi.codingstudio.org"
api_key = "YOUR_API_KEY"
api_path = "/v1/people_groups/daily_unreached.json?api_key=#{api_key}"
begin
    # Make the request to the Joshua Project API
    response = Net::HTTP.get(domain, api_path)
    # Parse the response
    data = JSON.parse(response)
    unreached = data[0]
rescue Exception => e
    # We had an error
    puts "Unable to get the API data"
    puts e.message
    abort
end
# format the population to a comma seperated value
unreached['Population'] = unreached['Population'].to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,')
# Lets handle the evangelical number since it can be nil
if unreached['PercentEvangelical'].nil?
    unreached['PercentEvangelical'] = "0.00"
else
    # format the percent to a floating point (decimal)
    unreached['PercentEvangelical'] = '%.2f' % unreached['PercentEvangelical']
end
# We will write the final HTML file
begin
    # write the new file
    # open the final file
    file = File.open("generated_code/widget.html", "w")
    file.write(widget_code)
rescue IOError => e
    # We had an error
    puts "Unable to write the HTML file"
    puts e.message
    abort
ensure
    # ensure the file closes happens if this fails
    file.close unless file == nil
end
                    

     Now run the script from your command line utility. Everytime you run it, it should generate a new generated_code/widget.html file with the latest people group. Open the generated_code/widget.html file in your favorite web browser, and you should see something similar to this:

Snapshot of Final Widget

     But why different data! If you do not supply a month or day parameter, the API will return today's unreached people group of the day by default. Most likely you are not doing this tutorial the same day as I was.

     Congratulations! You have completed the Ruby tutorial. If you would like to download the sample code, you can visit our Github Account.

     If you find any errors within these tutorials, or would like to suggest a new language/approach, please submit your request at our Github issue tracker.