# Pretty URLs

A Pretty URL is designed to transform a default URL with query strings into a more user-friendly and search engine-optimized format, enhancing both readability and SEO performance.

### Pretty URL Model

| Parameter         | Type               | Description                                                                                      |
| ----------------- | ------------------ | ------------------------------------------------------------------------------------------------ |
| `old_path`        | `string`           | The original URL containing query strings.                                                       |
| `new_path`        | `string`           | The new SEO-optimized URL.                                                                       |
| `func_name`       | `string`           | The view function used to serve the URL (e.g., `ProductDetailPageApiView`).                      |
| `func_module`     | `string`           | The file name where `func_name` is defined.                                                      |
| `func_initkwargs` | `JSON`             | Keyword arguments passed to the view function.                                                   |
| `viewname`        | `string`           | The URL name associated with `old_path` (e.g., `product`).                                       |
| `args`            | `list`             | The positional arguments parsed from the URL and passed to the view.                             |
| `kwargs`          | `JSON`             | The keyword arguments parsed from the URL and passed to the view.                                |
| `query_params`    | `JSON`             | The query parameters extracted from `old_path`.                                                  |
| `parent`          | `Pretty URL Model` | The generated Pretty URL for the default language in multi-language setups.                      |
| `language`        | `string`           | The language used to slugify values of `UrlGeneratorConfig` placeholders to generate `new_path`. |

### Automatic Pretty URL Generation

When an object of any of the following data models is created, a Pretty URL object is automatically generated for the default language. If multi-language support is enabled, a Pretty URL is generated for each language, with the default language's Pretty URL serving as the parent. These Pretty URLs are then attached to the created object.

Supported data models:

* `Product`
* `CategoryNode`
* `SpecialPage`
* `LandingPage`
* `CategoryNodeLandingPage`
* `Form`

### URL Generation with UrlGeneratorConfig

If a `UrlGeneratorConfig` object exists, the `new_path` is generated using the `template` and `config` fields of that object. The placeholders in the template are slugified and interpolated with corresponding values.

**Example `UrlGeneratorConfig` object:**

```json
{
    "template": "{test}-{test2}",
    "config": {
        "test": "name",
        "test2": "sku"
    },
    "content_type": {
        "pk": 1,
        "model": "product"
    }
}
```

* The `content_type` field specifies the model to which the configuration applies, indicating the type of content or entity that the configuration settings will affect. When a request is made to Omnitron using the endpoint `/api/v1/remote/{channel_id}/content_types/`, Omnitron processes the request and returns a response that includes the `content_type` field.
* The keys in the `config` field correspond to placeholders in the `template`, and the values map to the fields of the created object.

**Example:** For a product created with the following attributes:

```json
{
    "name": "Kırmızı Erkek Gömlek",
    "sku": "5649202702"
}
```

The `new_path` for the generated Pretty URL would be `kirmizi-erkek-gomlek-5649202702`.

### Default Templates for Data Models

If no `UrlGeneratorConfig` is provided, default templates are used for each data model:

| Data model                | Template         |
| ------------------------- | ---------------- |
| `Product`                 | `{slug}-{color}` |
| `CategoryNode`            | `{slug}`         |
| `SpecialPage`             | `{url}`          |
| `LandingPage`             | `{url}`          |
| `CategoryNodeLandingPage` | `{url}`          |
| `Form`                    | `{url}`          |

:::infoNOTE\
All endpoints require authentication. Ensure the header is set as specified before sending a request.

Refer to the Login documentation to obtain the authorization key.\
:::

### `GET` List Pretty URLs

This method is used to retrieve a list of Pretty URL objects.

**Path:** `https://{commerce_url}/api/v1/pretty_urls/`

**Headers:**

```json
{
    "Authorization": "Token {key}",
    "Content-Type": "application/json"
}
```

**Request Parameters**

| Parameter            | Type     | Description                                                         |
| -------------------- | -------- | ------------------------------------------------------------------- |
| `created_date__gt`   | `date`   | Retrieve objects created after this date.                           |
| `created_date__gte`  | `date`   | Retrieve objects created on or after this date.                     |
| `created_date__lt`   | `date`   | Retrieve objects created before this date.                          |
| `created_date__lte`  | `date`   | Retrieve objects created on or before this date.                    |
| `modified_date__gt`  | `date`   | Retrieve objects modified after this date.                          |
| `modified_date__gte` | `date`   | Retrieve objects modified on or after this date.                    |
| `modified_date__lt`  | `date`   | Retrieve objects modified before this date.                         |
| `modified_date__lte` | `date`   | Retrieve objects modified on or before this date.                   |
| `language`           | `string` | Filter by language.                                                 |
| `new_path`           | `string` | Filter by the new URL path.                                         |
| `new_path__exact`    | `string` | Filter by the exact value of the new URL path.                      |
| `old_path`           | `string` | Filter by the old URL path.                                         |
| `path`               | `string` | Looks up in `new_path` first; if not found, searches in `old_path`. |
| `parent`             | `int`    | Filter by the id of the parent Pretty URL.                          |

:::infoNOTE\
If a parameter not listed above is provided, the first page of all objects will be returned.\
:::

**Example Response (200 OK)**

```json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
	{
  	"pk": 4180,
  	"new_path": "/testtest/",
  	"old_path": "/special-page/17/",
  	"parent": null,
  	"language": "tr-tr",
  	"func_module": "omnishop.cms.resources.views",
  	"func_name": "SpecialPageView",
  	"func_initkwargs": {},
  	"args": [],
  	"kwargs": {
    	"special_page_id": "17"
  	},
  	"query_params": {},
  	"viewname": "special-page-detail",
  	"created_date": "2019-11-05T08:18:19.488976Z",
  	"modified_date": "2019-11-05T08:18:19.489008Z",
  	"prettyurl_set": []
	}
  ]
}
```

### `GET` Retrieve a Pretty URL

This method is used to retrieve a single Pretty URL by its primary key (pk).

**Path:** `https://{commerce_url}/api/v1/pretty_urls/{pk}`

**Example Response (200 OK)**

```json
{
    "pk": "<pk>",
    "new_path": "<new_path>",
    "old_path": "<old_path>",
    "parent": null,
    "language": "tr-tr",
    "func_module": "omnishop.products.resources.views",
    "func_name": "ProductDetailPageApiView",
    "func_initkwargs": {},
    "args": [],
    "kwargs": {
        "product_id": "1924"
    },
    "query_params": {},
    "viewname": "product",
    "created_date": "2017-01-24T10:32:10.487793Z",
    "modified_date": "2017-01-30T17:05:10.327456Z",
    "prettyurl_set": []
}
```

### `POST` Create a Pretty URL

**Path:** `https://{commerce_url}/api/v1/pretty_urls/`

This method is used to create a new Pretty URL.

**Request Body**

```json
{
	"old_path": "<old_path>",
	"new_path": "<new_path>"
}
```

**Example Responses**

**200 OK:**

```json
{
    "pk": 4186,
    "new_path": "<new_path>",
    "old_path": "<old_path>",
    "parent": null,
    "language": "tr-tr",
    "func_module": "omnishop.products.resources.views",
    "func_name": "ProductDetailPageApiView",
    "func_initkwargs": {},
    "args": [],
    "kwargs": {
        "extra_query_params": {},
        "product_id": "4"
    },
    "query_params": {},
    "viewname": "product",
    "created_date": "2023-09-20T13:39:52.562534Z",
    "modified_date": "2023-09-20T13:39:52.562610Z",
    "prettyurl_set": []
}
```

**406 Not Acceptable:**

```json
{
    "non_field_errors": "Url <old_path> bulunmuyor.",
    "error_code": "pretty_url_100_2"
}
```

```json
{
    "non_field_errors": "<new_path> - <language> pretty url mevcut.",
    "error_code": "pretty_url_100_1"
}
```

### `PATCH` Update a Pretty URL

This method is used to ppdate the `new_path` and/or `old_path` fields of an existing Pretty URL.

:::infoNOTE\
The PUT method functions similarly to PATCH but requires both `new_path` and `old_path` to be provided.\
:::

**Path:** `https://{commerce_url}/api/v1/pretty_urls/{pk}`

**Request Body**

```json
{
	"old_path": "<old_path>",
	"new_path": "<new_path>",
}
```

**Example Responses**

**200 OK:**

```json
{
    "pk": 1432,
    "new_path": "<new_path>",
    "old_path": "<old_path>",
    "parent": null,
    "language": "tr-tr",
    "func_module": "omnishop.products.resources.views",
    "func_name": "ProductDetailPageApiView",
    "func_initkwargs": {},
    "args": [],
    "kwargs": {
        "product_id": "1924"
    },
    "query_params": {},
    "viewname": "product",
    "created_date": "2017-01-24T10:32:10.487793Z",
    "modified_date": "2023-09-20T19:37:52.976216Z",
    "prettyurl_set": []
}
```

**406 Not Acceptable:**

```json
{
    "non_field_errors": "Url <old_path> bulunmuyor.",
    "error_code": "pretty_url_100_2"
}
```

```json
{
    "non_field_errors": "<new_path> - <language> pretty url mevcut.",
    "error_code": "pretty_url_100_2"
}
```

### `DELETE` Delete a Pretty URL

This method is used to delete a Pretty URL by its primary key (pk).

**Path:** `https://{commerce_url}/api/v1/pretty_urls/{pk}`

**Example Responses**

**204 No Content:**

204 No Content successful response status code indicates that a Pretty URL has been deleted.

**406 Not Acceptable:**

```json
{
    "non_field_errors": "Cannot delete some instances of model 'PrettyUrl' because they are referenced through a protected foreign key: 'Product.pretty_url': <QuerySet [<Product: [Bad Unicode data]>]>"
}
```
