diff --git a/_config.yml b/_config.yml
index 0e55e8c35..3662c857b 100644
--- a/_config.yml
+++ b/_config.yml
@@ -23,3 +23,5 @@ support_url: https://www.parse.com/help
# Build settings
markdown: kramdown
exclude: [ Gemfile, Gemfile.lock, README.md, config.codekit ]
+sass:
+ sass_dir: css
diff --git a/_includes/android/push-notifications.md b/_includes/android/push-notifications.md
index 47b1d2d5f..47198206f 100644
--- a/_includes/android/push-notifications.md
+++ b/_includes/android/push-notifications.md
@@ -72,7 +72,7 @@ Sending notifications is often done from the Parse.com push console, the [REST A
However, be sure you understand that enabling Client Push can lead to a security vulnerability in your app, as outlined [on our blog](http://blog.parse.com/2014/09/03/the-dangerous-world-of-client-push/). We recommend that you enable Client Push for testing purposes only, and move your push notification logic into Cloud Code when your app is ready to go into production.
-
+
You can view your past push notifications on the Parse.com push console for up to 30 days after creating your push. For pushes scheduled in the future, you can delete the push on the push console as long as no sends have happened yet. After you send the push, the push console shows push analytics graphs.
@@ -95,7 +95,7 @@ By default, the main activity for your app will be run when a user responds to n
Once subscribed to the "Giants" channel, your `Installation` object should have an updated `channels` field.
-
+
Unsubscribing from a channel is just as easy:
@@ -389,15 +389,15 @@ Our web push console guides you through every step of setting up an A/B test.
For each push campaign sent through the Parse web push console, you can allocate a subset of your devices to be in the experiment's test audience, which Parse will automatically split into two equally-sized experiment groups. For each experiment group, you can specify a different push message. The remaining devices will be saved so that you can send the winning message to them later. Parse will randomly assign devices to each group to minimize the chance for a test to affect another test's results (although we still don't recommend running multiple A/B tests over the same devices on the same day).
-
+
After you send the push, you can come back to the push console to see in real time which version resulted in more push opens, along with other metrics such as statistical confidence interval. It's normal for the number of recipients in each group to be slightly different because some devices that we had originally allocated to that experiment group may have uninstalled the app. It's also possible for the random group assignment to be slightly uneven when the test audience size is small. Since we calculate open rate separately for each group based on recipient count, this should not significantly affect your experiment results.
-
+
If you are happy with the way one message performed, you can send that to the rest of your app's devices (i.e. the “Launch Group”). This step only applies to A/B tests where you vary the message.
-
+
Push experiments are supported on all recent Parse SDKs (iOS v1.2.13+, Android v1.4.0+, .NET v1.2.7+). Before running experiments, you must instrument your app with [push open tracking](#push-notifications-tracking-pushes-and-app-opens).
diff --git a/_includes/common/errors.md b/_includes/common/errors.md
index e981db1b1..99c7fd18e 100644
--- a/_includes/common/errors.md
+++ b/_includes/common/errors.md
@@ -45,6 +45,7 @@ The following is a list of all the error codes that can be returned by the Parse
| `AppNameInvalid` | 256 | App name is invalid. |
| `MissingAPIKeyError` | 902 | The request is missing an API key. |
| `InvalidAPIKeyError` | 903 | The request is using an invalid API key. |
+{: .docs_table}
## Push related errors
@@ -66,6 +67,7 @@ The following is a list of all the error codes that can be returned by the Parse
| `InvalidExpirationError` | 138 | Invalid expiration value. |
| `MissingPushIdError` | 156 | A push id is missing. Deprecated. |
| `MissingDeviceTypeError` | 157 | The device type field is missing. Deprecated. |
+{: .docs_table}
## File related errors
@@ -78,6 +80,7 @@ The following is a list of all the error codes that can be returned by the Parse
| `FileTooLarge` | 129 | File size exceeds maximum allowed. |
| `FileSaveError` | 130 | Error saving a file. |
| `FileDeleteError` | 131 | File could not be deleted. |
+{: .docs_table}
## Installation related errors
@@ -88,6 +91,7 @@ The following is a list of all the error codes that can be returned by the Parse
| `InvalidChannelsArrayError` | 134 | Invalid channels array value. |
| `MissingRequiredFieldError` | 135 | Required field is missing. |
| `ChangedImmutableFieldError` | 136 | An immutable field was changed. |
+{: .docs_table}
## Purchase related errors
@@ -100,6 +104,7 @@ The following is a list of all the error codes that can be returned by the Parse
| `ProductNotFoundInAppStore` | 147 | The product is not found in the App Store. |
| `InvalidServerResponse` | 148 | The Apple server response is not valid. |
| `ProductDownloadFilesystemError` | 149 | The product fails to download due to file system error. |
+{: .docs_table}
## User related errors
@@ -115,6 +120,7 @@ The following is a list of all the error codes that can be returned by the Parse
| `MustCreateUserThroughSignup` | 207 | A user can only be created through signup. |
| `AccountAlreadyLinked` | 208 | An account being linked is already linked to another user. |
| `InvalidSessionToken` | 209 | The device's session token is no longer valid. The application should ask the user to log in again. |
+{: .docs_table}
## Linked services errors
@@ -138,6 +144,7 @@ The following is a list of all the error codes that can be returned by the Parse
| `TwitterSigninDisabled` | 252 | Authentication by Twitter is not supported for this application. Check your Parse app's authentication settings. |
| `InvalidAuthDataError` | 253 | An invalid authData value was passed. Check error message for more details. |
| `LinkingNotSupportedError` | 999 | Linking to an external account not supported yet with signup_or_login. Use update instead. |
+{: .docs_table}
## Client-only errors
@@ -147,6 +154,7 @@ The following is a list of all the error codes that can be returned by the Parse
| `AggregateError` | 600 | There were multiple errors. Aggregate errors have an "errors" property, which is an array of error objects with more detail about each error that occurred. |
| `FileReadError ` | 601 | Unable to read input for a %{ParseFile} on the client. |
| `XDomainRequest` | 602 | A real error code is unavailable because we had to use an XDomainRequest object to allow CORS requests in Internet Explorer, which strips the body from HTTP responses that have a non-2XX status code. |
+{: .docs_table}
## Operational issues
@@ -157,6 +165,7 @@ The following is a list of all the error codes that can be returned by the Parse
| `RequestLimitExceeded` | 155 | This application has exceeded its request limit. Please retry in one minute or raise your request limit at https://parse.com/account. Check error message for more details. |
| `TemporaryRejectionError` | 159 | An application's requests are temporary rejected by the server. |
| `DatabaseNotMigratedError` | 428 | You should migrate your database as soon as possible. |
+{: .docs_table}
If your requests are rejected with a 155 error code, your application may be [exceeding its request limit](/plans/faq#request-limit-exceeded). You can learn more about [how the request limit is calculated in the Pricing FAQ](/plans/faq#how-are-requests-per-second-calculated). If waiting one minute or [increasing the request limit](/plans/faq#increasing-request-limit) does not resolve the issue, [please file a bug report](https://parse.com/help#report). If your requests are being rejected with a 159 error code, [please file a bug report](https://parse.com/help#report) for further instructions on how to resolve the issue. If your requests are rejected with a 428 error code, please [migrate your database](https://parse.com/migration) as soon as possible.
@@ -168,3 +177,4 @@ If your requests are rejected with a 155 error code, your application may be [ex
| `InternalServerError` | 1 | Internal server error. No information available. |
| `ServiceUnavailable` | 2 | The service is currently unavailable. |
| `ClientDisconnected` | 4 | Connection failure. |
+{: .docs_table}
diff --git a/_includes/common/security.md b/_includes/common/security.md
index 0cee77d13..9492177e2 100644
--- a/_includes/common/security.md
+++ b/_includes/common/security.md
@@ -34,7 +34,7 @@ Almost every class that you create should have these permissions tweaked to some
As a start, you can configure your application so that clients cannot create new classes on Parse. This is done from the Settings tab on the Data Browser. Scroll down to the **App Permissions** section and turn off **Allow client class creation**. Once enabled, classes may only be created from the Data Browser. This will prevent attackers from filling your database with unlimited, arbitrary new classes.
-
+
### Configuring Class-Level Permissions
@@ -323,7 +323,7 @@ Note that this ACL is not actually created on each object. Any existing ACLs wil
Class-Level Permissions (CLPs) and Access Control Lists (ACLs) are both powerful tools for securing your app, but they don't always interact exactly how you might expect. They actually represent two separate layers of security that each request has to pass through to return the correct information or make the intended change. These layers, one at the class level, and one at the object level, are shown below. A request must pass through BOTH layers of checks in order to be authorized. Note that despite acting similarly to ACLs, [Pointer Permissions](#security-pointer-permissions) are a type of class level permission, so a request must pass the pointer permission check in order to pass the CLP check.
-
+
As you can see, whether a user is authorized to make a request can become complicated when you use both CLPs and ACLs. Let's look at an example to get a better sense of how CLPs and ACLs can interact. Say we have a `Photo` class, with an object, `photoObject`. There are 2 users in our app, `user1` and `user2`. Now lets say we set a Get CLP on the `Photo` class, disabling public Get, but allowing `user1` to perform Get. Now let's also set an ACL on `photoObject` to allow Read - which includes GET - for only `user2`.
diff --git a/_includes/head.html b/_includes/head.html
index c5c94352c..f06883dc0 100644
--- a/_includes/head.html
+++ b/_includes/head.html
@@ -1,26 +1,83 @@
+
diff --git a/_includes/ios/config.md b/_includes/ios/config.md
index f534878bc..244c1d2f5 100644
--- a/_includes/ios/config.md
+++ b/_includes/ios/config.md
@@ -4,7 +4,7 @@
`PFConfig` is a way to configure your applications remotely by storing a single configuration object on Parse. It enables you to add things like feature gating or a simple "Message of the Day". To start using `PFConfig` you need to add a few key/value pairs (parameters) to your app on the Parse Config Dashboard.
-
+
After that you will be able to fetch the `PFConfig` on the client, like in this example:
diff --git a/_includes/ios/push-notifications.md b/_includes/ios/push-notifications.md
index 195f8a3c0..30f43ad98 100644
--- a/_includes/ios/push-notifications.md
+++ b/_includes/ios/push-notifications.md
@@ -76,7 +76,7 @@ Sending notifications is often done from the Parse.com push console, the [REST A
However, be sure you understand that enabling Client Push can lead to a security vulnerability in your app, as outlined [on our blog](http://blog.parse.com/2014/09/03/the-dangerous-world-of-client-push/). We recommend that you enable Client Push for testing purposes only, and move your push notification logic into Cloud Code when your app is ready to go into production.
-
+
You can view your past push notifications on the Parse.com push console for up to 30 days after creating your push. For pushes scheduled in the future, you can delete the push on the push console as long as no sends have happened yet. After you send the push, the push console shows push analytics graphs.
@@ -105,7 +105,7 @@ currentInstallation.saveInBackground()
Once subscribed to the "Giants" channel, your `Installation` object should have an updated `channels` field.
-
+
Unsubscribing from a channel is just as easy:
@@ -770,11 +770,11 @@ Our web push console guides you through every step of setting up an A/B test.
For each push campaign sent through the Parse web push console, you can allocate a subset of your devices to be in the experiment's test audience, which Parse will automatically split into two equally-sized experiment groups. For each experiment group, you can specify a different push message. The remaining devices will be saved so that you can send the winning message to them later. Parse will randomly assign devices to each group to minimize the chance for a test to affect another test's results (although we still don't recommend running multiple A/B tests over the same devices on the same day).
-
+
After you send the push, you can come back to the push console to see in real time which version resulted in more push opens, along with other metrics such as statistical confidence interval. It's normal for the number of recipients in each group to be slightly different because some devices that we had originally allocated to that experiment group may have uninstalled the app. It's also possible for the random group assignment to be slightly uneven when the test audience size is small. Since we calculate open rate separately for each group based on recipient count, this should not significantly affect your experiment results.
-
+
If you are happy with the way one message performed, you can send that to the rest of your app's devices (i.e. the “Launch Group”). This step only applies to A/B tests where you vary the message.
diff --git a/_includes/ios/user-interface.md b/_includes/ios/user-interface.md
index 88981d7e6..cd08dd2af 100644
--- a/_includes/ios/user-interface.md
+++ b/_includes/ios/user-interface.md
@@ -31,7 +31,7 @@ self.presentViewController(logInController, animated:true, completion: nil)
### Configuring the Log In Elements
-
+
`PFLogInViewController` can be configured to provide a variety of log in options. By default, `PFLogInViewController` presents the following UI:
@@ -240,7 +240,7 @@ That is all you need to do to get a functional sign up screen.
### Configuring the Sign Up Elements
-
+
`PFSignUpViewController` can be configured to provide a variety of sign up options. By default, it presents the following UI:
@@ -485,7 +485,7 @@ The easiest way to understand this class is with an example. This subclass of `P
```
```swift
class SimpleTableViewController : PFQueryTableViewController {
-
+
override init(style: UITableViewStyle, className: String?) {
super.init(style: style, className: className)
parseClassName = "Todo"
@@ -501,36 +501,36 @@ class SimpleTableViewController : PFQueryTableViewController {
paginationEnabled = true
objectsPerPage = 25
}
-
+
override func queryForTable() -> PFQuery {
let query = PFQuery(className: self.parseClassName!)
-
+
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if self.objects!.count == 0 {
query.cachePolicy = .CacheThenNetwork
}
-
+
query.orderByDescending("createdAt")
-
+
return query
}
-
+
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
let cellIdentifier = "cell"
-
+
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? PFTableViewCell
if cell == nil {
cell = PFTableViewCell(style: .Subtitle, reuseIdentifier: cellIdentifier)
}
-
+
// Configure the cell to show todo item with a priority at the bottom
- if let object = object {
+ if let object = object {
cell!.textLabel?.text = object["text"] as? String
let priority = object["priority"] as? String
cell!.detailTextLabel?.text = "Priority \(priority)"
}
-
+
return cell
}
}
diff --git a/_includes/menu.html b/_includes/menu.html
new file mode 100644
index 000000000..60d5eb0f5
--- /dev/null
+++ b/_includes/menu.html
@@ -0,0 +1,39 @@
+
diff --git a/_includes/rest/quick-reference.md b/_includes/rest/quick-reference.md
index 46ee902b5..c8796a3d5 100644
--- a/_includes/rest/quick-reference.md
+++ b/_includes/rest/quick-reference.md
@@ -11,6 +11,7 @@ All API access is over HTTPS, and accessed via the `https://api.parse.com` domai
| `/1/classes//` | PUT | [Updating Objects](#objects-updating-objects) |
| `/1/classes/` | GET | [Queries](#queries) |
| `/1/classes//` | DELETE | [Deleting Objects](#objects-deleting-objects) |
+{: .docs_table}
## Users
@@ -25,6 +26,7 @@ All API access is over HTTPS, and accessed via the `https://api.parse.com` domai
| `/1/users` | GET | [Querying Users](#users-querying) |
| `/1/users/` | DELETE | [Deleting Users](#users-deleting-users) |
| `/1/requestPasswordReset` | POST | [Requesting A Password Reset](#users-requesting-a-password-reset) |
+{: .docs_table}
## Sessions
@@ -37,6 +39,7 @@ All API access is over HTTPS, and accessed via the `https://api.parse.com` domai
| `/1/sessions` | GET | [Querying Sessions](#sessions-querying-sessions) |
| `/1/sessions/` | DELETE | [Deleting Sessions](#sessions-deleting-sessions) |
| `/1/sessions/me` | PUT | [Pairing with Installation](#sessions-pairing-session-with-installation) |
+{: .docs_table}
## Roles
@@ -46,12 +49,14 @@ All API access is over HTTPS, and accessed via the `https://api.parse.com` domai
| `/1/roles/` | GET | [Retrieving Roles](#roles-retrieving-roles) |
| `/1/roles/` | PUT | [Updating Roles](#roles-updating-roles) |
| `/1/roles/` | DELETE | [Deleting Roles](#roles-deleting-roles) |
+{: .docs_table}
## Files
| URL | HTTP Verb | Functionality |
|-----------------------|-----------|-------------------------------------------|
| `/1/files/` | POST | [Uploading Files](#files-uploading-files) |
+{: .docs_table}
## Analytics
@@ -59,12 +64,14 @@ All API access is over HTTPS, and accessed via the `https://api.parse.com` domai
|-------------------------|-----------|-------------------------------------------------|
| `/1/events/AppOpened` | POST | [Analytics](#analytics-app-open-analytics) |
| `/1/events/` | POST | [Custom Analytics](#analytics-custom-analytics) |
+{: .docs_table}
## Push Notifications
| URL | HTTP Verb | Functionality |
|-----------|-----------|------------------------------|
| `/1/push` | POST | [Push Notifications](#push-notifications) |
+{: .docs_table}
## Installations
@@ -75,13 +82,15 @@ All API access is over HTTPS, and accessed via the `https://api.parse.com` domai
| `/1/installations/` | PUT | [Updating Installations](#push-notifications-updating-installations) |
| `/1/installations` | GET | [Querying Installations](#push-notifications-querying-installations) |
| `/1/installations/` | DELETE | [Deleting Installations](#push-notifications-deleting-installations) |
+{: .docs_table}
## Cloud Functions
| URL | HTTP Verb | Functionality |
|-----------------------|-----------|-----------------------------------------------------------|
-| `/1/functions/` | POST | [Calling Cloud Functions](#cloud-code-cloud-functions) |
+| `/1/functions/` | POST | [Calling Cloud Functions](#cloud-code-cloud-functions) |
| `/1/jobs/` | POST | [Triggering Background Jobs](#cloud-code-background-jobs) |
+{: .docs_table}
## Schemas
@@ -92,6 +101,7 @@ All API access is over HTTPS, and accessed via the `https://api.parse.com` domai
| `/1/schemas/`| POST | [Create Schema](#schema-adding-a-schema) |
| `/1/schemas/`| PUT | [Modify Schema](#schema-modifying-the-schema) |
| `/1/schemas/`| DELETE | [Delete Schema](#schema-removing-a-schema) |
+{: .docs_table}
## Apps
@@ -101,6 +111,7 @@ All API access is over HTTPS, and accessed via the `https://api.parse.com` domai
| `/1/apps/`| GET | [Fetch App](#apps-fetching-apps) |
| `/1/apps/`| POST | [Create App](#apps-creating-apps) |
| `/1/apps/`| PUT | [Modify App](#apps-updating-apps) |
+{: .docs_table}
## Function Hooks
@@ -110,6 +121,7 @@ All API access is over HTTPS, and accessed via the `https://api.parse.com` domai
| `/1/hooks/functions/` | POST | [Create Cloud Function](#hooks-create-function-webhook) |
| `/1/hooks/functions/` | PUT | [Edit Cloud Function](#hooks-edit-function-webhook) |
| `/1/hooks/functions/` | DELETE | [Delete Cloud Function](#hooks-delete-function-webhook) |
+{: .docs_table}
## Trigger Hooks
@@ -119,6 +131,7 @@ All API access is over HTTPS, and accessed via the `https://api.parse.com` domai
| `/1/hooks/triggers/` | POST | [Create Cloud Trigger](#hooks-create-trigger-webhook) |
| `/1/hooks/triggers//` | PUT | [Edit Cloud Trigger](#hooks-edit-trigger-webhook) |
| `/1/hooks/triggers//` | DELETE | [Delete Cloud Trigger](#hooks-delete-trigger-webhook) |
+{: .docs_table}
## Request Format
@@ -152,7 +165,7 @@ Whether a request succeeded is indicated by the HTTP status code. A 2xx status c
## Calling from Client Apps
-You should not use the REST API Key in client apps (i.e. code you distribute to your customers). If the Parse SDK is available for your client platform, we recommend using our SDK instead of the REST API. If you must call the REST API directly from the client, you should use the corresponding client-side Parse key for that plaform (e.g. Client Key for iOS/Android, or .NET Key for Windows/Xamarin/Unity).
+You should not use the REST API Key in client apps (i.e. code you distribute to your customers). If the Parse SDK is available for your client platform, we recommend using our SDK instead of the REST API. If you must call the REST API directly from the client, you should use the corresponding client-side Parse key for that plaform (e.g. Client Key for iOS/Android, or .NET Key for Windows/Xamarin/Unity).
If there is no Parse SDK for your client platform, please use your app's Client Key to call the REST API. Requests made with the Client Key, JavaScript Key, or Windows Key are restricted by client-side app settings that you configure in your Parse.com app dashboard. These settings make your app more secure. For example, we recommend that all production apps turn off the "Client Push Enabled" setting to prevent push notifications from being sent from any device using the Client Key, JavaScript Key, or .NET Key, but not the REST API Key. Therefore, if you plan on registering installations to enable Push Notifications for your app, you should not distribute any app code with the REST API key embedded in it.
diff --git a/_layouts/default.html b/_layouts/default.html
index f4c082d23..e12c85056 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -1,20 +1,5 @@
-
-
- {% include head.html %}
-
-
-
- {% include nav.html %}
- {% include header.html %}
- {% include nav-secondary.html %}
-
-