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.
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
. Warning: This is not a valid key. You must request
your own key to the API. API keys are free and you are allowed to have multiple of them.
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:
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.
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.
https://api.joshuaproject.net/v1/people_groups/daily_unreached.json?api_key=233f76f4c84e&month=01&day=11
Here is a breakdown of the URL structure:
https://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 &. |
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": "SF", "PeopleID3": 18995, "PeopNameInCountry": "Malay, Cape", "ROG2": "AFR", "Continent": "Africa", "RegionName": "Africa, East and Southern", "PeopleID1": 17, "AffinityBloc": "Malay Peoples", "PeopleID2": 215, "PeopleCluster": "Malay", "PeopNameAcrossCountries": "Malay, Cape", "Population": 324000, "ROL3": "afr", "PrimaryLanguageName": "Afrikaans", "BibleYear": "1933-2022", "NTYear": "1941-1980", "PortionsYear": "1893-1929", "JPScale": "1", "LeastReached": "Y", "JF": "Y", "AudioRecordings": "Y", "NTOnline": "AFRLPF", "RLG3": 6, "PrimaryReligion": "Islam", "LRofTheDayMonth": 11, "LRofTheDaySet": null, "LRofTheDayDay": 1, "PhotoAddress": "p18995.jpg", "PhotoCredits": "Anonymous", "PhotoCreditURL": null, "PhotoCreativeCommons": "N", "PhotoCopyright": "N", "PhotoPermission": "N", "CountOfCountries": 1, "Longitude": 21.61887, "Latitude": -30.62109, "Ctry": "South Africa", "PercentAdherents": 0.5, "PercentEvangelical": 0.2, "RegionCode": 7, "ROP3": 114855, "ISO3": "ZAF", "LocationInCountry": "Principally Pretoria and Bloemfontein. Cape Malays mainly in Cape Town; some in Johannesburg, Pretoria, Durban, and Port Elizabeth", "ROP1": "A008", "ROP2": "C0123", "Category": "3", "PrimaryLanguageDialect": null, "NumberLanguagesSpoken": 2, "OfficialLang": "English", "SpeakNationalLang": null, "BibleStatus": 5, "TranslationNeedQuestionable": null, "JPScalePC": "4", "JPScalePGAC": "1", "LeastReachedPC": "N", "LeastReachedPGAC": "Y", "GSEC": "", "RLG3PC": 6, "RLG3PGAC": 6, "PrimaryReligionPC": "Islam", "PrimaryReligionPGAC": "Islam", "RLG4": null, "ReligionSubdivision": null, "PCIslam": 99.5, "PCNonReligious": 0, "PCUnknown": 0, "SecurityLevel": 0, "LRTop100": "N", "ProfileTextExists": "Y", "CountOfProvinces": null, "IndigenousCode": "Y", "PercentChristianPC": "7.590", "PercentChristianPGAC": "0.500", "PercentEvangelicalPC": "3.677", "PercentEvangelicalPGAC": "0.200", "PCBuddhism": 0, "PCEthnicReligions": 0, "PCHinduism": 0, "PCOtherSmall": 0, "PopulationPGAC": 324000, "Frontier": "N", "MapAddress": "m18995_sf.png", "MapCreditURL": "https://www.cartomission.com", "MapCopyright": "N", "MapCredits": "Bryan Nicholson / cartoMission", "MapCCVersionText": "", "MapCCVersionURL": "", "PhotoCCVersionText": "", "PhotoCCVersionURL": "", "Window1040": "N", "PeopleGroupMapURL": "https://joshuaproject.net/assets/media/profiles/maps/m18995_sf.png", "PeopleGroupMapExpandedURL": "https://joshuaproject.net/assets/media/profiles/maps/m18995_sf.pdf", "PeopleGroupURL": "https://joshuaproject.net/people_groups/18995/SF", "PeopleGroupPhotoURL": "https://joshuaproject.net/assets/media/profiles/photos/p18995.jpg", "CountryURL": "https://joshuaproject.net/countries/SF", "JPScaleText": "Unreached", "JPScaleImageURL": "https://joshuaproject.net/images/scale1.jpg", "Summary": "Ancestors of the Cape Malay came as hired workers and slaves to serve the Dutch settlement, coming largely from Indonesia and Malaysia. Later, since Islam was introduced in Indonesia as a way of protest against the colonial powers, Islamic leaders from Indonesia were brought to the Cape for imprisonment. They taught their fellow countrymen a lot about Islam and helped to spread it at the Cape. The Cape Malay define themselves as Muslims. If a person comes to know Jesus, he is no longer considered to be a Cape Malay." } ]
And here is the XML response:
<?xml version="1.0"?> <api> <people_groups> <people_group> <ROG3>SF</ROG3> <PeopleID3>18995</PeopleID3> <PeopNameInCountry>Malay, Cape</PeopNameInCountry> <ROG2>AFR</ROG2> <Continent>Africa</Continent> <RegionName>Africa, East and Southern</RegionName> <PeopleID1>17</PeopleID1> <AffinityBloc>Malay Peoples</AffinityBloc> <PeopleID2>215</PeopleID2> <PeopleCluster>Malay</PeopleCluster> <PeopNameAcrossCountries>Malay, Cape</PeopNameAcrossCountries> <Population>324000</Population> <ROL3>afr</ROL3> <PrimaryLanguageName>Afrikaans</PrimaryLanguageName> <BibleYear>1933-2022</BibleYear> <NTYear>1941-1980</NTYear> <PortionsYear>1893-1929</PortionsYear> <JPScale>1</JPScale> <LeastReached>Y</LeastReached> <JF>Y</JF> <AudioRecordings>Y</AudioRecordings> <NTOnline>AFRLPF</NTOnline> <RLG3>6</RLG3> <PrimaryReligion>Islam</PrimaryReligion> <LRofTheDayMonth>11</LRofTheDayMonth> <LRofTheDaySet/> <LRofTheDayDay>1</LRofTheDayDay> <PhotoAddress>p18995.jpg</PhotoAddress> <PhotoCredits>Anonymous</PhotoCredits> <PhotoCreditURL/> <PhotoCreativeCommons>N</PhotoCreativeCommons> <PhotoCopyright>N</PhotoCopyright> <PhotoPermission>N</PhotoPermission> <CountOfCountries>1</CountOfCountries> <Longitude>21.61887</Longitude> <Latitude>-30.62109</Latitude> <Ctry>South Africa</Ctry> <PercentAdherents>0.5</PercentAdherents> <PercentEvangelical>0.2</PercentEvangelical> <RegionCode>7</RegionCode> <ROP3>114855</ROP3> <ISO3>ZAF</ISO3> <LocationInCountry>Principally Pretoria and Bloemfontein. Cape Malays mainly in Cape Town; some in Johannesburg, Pretoria, Durban, and Port Elizabeth</LocationInCountry> <ROP1>A008</ROP1> <ROP2>C0123</ROP2> <Category>3</Category> <PrimaryLanguageDialect/> <NumberLanguagesSpoken>2</NumberLanguagesSpoken> <OfficialLang>English</OfficialLang> <SpeakNationalLang/> <BibleStatus>5</BibleStatus> <TranslationNeedQuestionable/> <JPScalePC>4</JPScalePC> <JPScalePGAC>1</JPScalePGAC> <LeastReachedPC>N</LeastReachedPC> <LeastReachedPGAC>Y</LeastReachedPGAC> <GSEC/> <RLG3PC>6</RLG3PC> <RLG3PGAC>6</RLG3PGAC> <PrimaryReligionPC>Islam</PrimaryReligionPC> <PrimaryReligionPGAC>Islam</PrimaryReligionPGAC> <RLG4/> <ReligionSubdivision/> <PCIslam>99.5</PCIslam> <PCNonReligious>0</PCNonReligious> <PCUnknown>0</PCUnknown> <SecurityLevel>0</SecurityLevel> <LRTop100>N</LRTop100> <ProfileTextExists>Y</ProfileTextExists> <CountOfProvinces/> <IndigenousCode>Y</IndigenousCode> <PercentChristianPC>7.590</PercentChristianPC> <PercentChristianPGAC>0.500</PercentChristianPGAC> <PercentEvangelicalPC>3.677</PercentEvangelicalPC> <PercentEvangelicalPGAC>0.200</PercentEvangelicalPGAC> <PCBuddhism>0</PCBuddhism> <PCEthnicReligions>0</PCEthnicReligions> <PCHinduism>0</PCHinduism> <PCOtherSmall>0</PCOtherSmall> <PopulationPGAC>324000</PopulationPGAC> <Frontier>N</Frontier> <MapAddress>m18995_sf.png</MapAddress> <MapCreditURL>https://www.cartomission.com</MapCreditURL> <MapCopyright>N</MapCopyright> <MapCredits>Bryan Nicholson / cartoMission</MapCredits> <MapCCVersionText/> <MapCCVersionURL/> <PhotoCCVersionText/> <PhotoCCVersionURL/> <Window1040>N</Window1040> <PeopleGroupMapURL>https://joshuaproject.net/assets/media/profiles/maps/m18995_sf.png</PeopleGroupMapURL> <PeopleGroupMapExpandedURL>https://joshuaproject.net/assets/media/profiles/maps/m18995_sf.pdf</PeopleGroupMapExpandedURL> <PeopleGroupURL>https://joshuaproject.net/people_groups/18995/SF</PeopleGroupURL> <PeopleGroupPhotoURL>https://joshuaproject.net/assets/media/profiles/photos/p18995.jpg</PeopleGroupPhotoURL> <CountryURL>https://joshuaproject.net/countries/SF</CountryURL> <JPScaleText>Unreached</JPScaleText> <JPScaleImageURL>https://joshuaproject.net/images/scale1.jpg</JPScaleImageURL> <Summary>Ancestors of the Cape Malay came as hired workers and slaves to serve the Dutch settlement, coming largely from Indonesia and Malaysia. Later, since Islam was introduced in Indonesia as a way of * Connection #0 to host localhost left intact protest against the colonial powers, Islamic leaders from Indonesia were brought to the Cape for imprisonment. They taught their fellow countrymen a lot about Islam and helped to spread it at the Cape. The Cape Malay define themselves as Muslims. If a person comes to know Jesus, he is no longer considered to be a Cape Malay.</Summary> </people_group> </people_groups> </api>
Once you have a response, you can use and manipulate the provided data.
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.
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="https://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="https://joshuaproject.net/definitions.php?term=25" class="upgotd-link pg-scale-text"> </a> ( <a href="https://joshuaproject.net/global-progress-scale.php" class="upgotd-link pg-scale"> </a> <a href="https://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.
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.
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 = 'https://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 = 'https://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 | https://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.
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 = 'https://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.
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 = 'https://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 = 'https://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="https://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="https://joshuaproject.net/definitions.php?term=25" class="upgotd-link pg-scale-text"> </a> (<a href="https://joshuaproject.net/global-progress-scale.php" class="upgotd-link pg-scale"> </a> <a href="https://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 = 'https://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:
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 = 'https://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 = 'https://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:
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 = 'https://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:
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 = 'https://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 = 'https://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:
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="https://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="https://joshuaproject.net/definitions.php?term=25"
class="upgotd-link pg-scale-text">
</a> (
<a
href="https://joshuaproject.net/global-progress-scale.php"
class="upgotd-link pg-scale">
</a>
<a
href="https://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 = 'https://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 .
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.
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 = "https://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 = "https://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 = "https://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 | https://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 = "https://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 = "https://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 = "https://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 = "https://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 = "https://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 = "https://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];
?>
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 = "https://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="https://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="https://joshuaproject.net/definitions.php?term=25" class="upgotd-link pg-scale-text"> <?php echo $unreached['JPScaleText']; ?> </a> ( <a href="https://joshuaproject.net/global-progress-scale.php" class="upgotd-link pg-scale"> <?php echo $unreached['JPScale']; ?> </a> <a href="https://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.
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.
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 widgetgenerated_code
- directory for the code created by our generator
templates
- directory for the HTML templates
index.html
- the HTML template for the widgetgenerate_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
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 = "https://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 = "https://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 = "https://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 = "https://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 = "https://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 = "https://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 = "https://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]
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 = "https://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 = "https://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="https://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="https://joshuaproject.net/definitions.php?term=25" class="upgotd-link pg-scale-text"> $JPScaleText </a> ( <a href="https://joshuaproject.net/global-progress-scale.php" class="upgotd-link pg-scale"> $JPScale </a> <a href="https://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 = "https://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 = "https://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 = "https://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 = "https://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:
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.
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 widgetgenerated_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 widgetgenerate_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"
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
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="https://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="https://joshuaproject.net/definitions.php?term=25" class="upgotd-link pg-scale-text"> <%= unreached['JPScaleText'] %> </a> ( <a href="https://joshuaproject.net/global-progress-scale.php" class="upgotd-link pg-scale"> <%= unreached['JPScale'] %> </a> <a href="https://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:
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.