<commit_before>django-url-tracker
==================

.. image:: https://travis-ci.org/elbaschid/django-url-tracker.png
    :target: https://travis-ci.org/elbaschid/django-url-tracker

The ``django-url-tracker`` is meant to be a easy-to-use addition to
a website to enhance its SEO. This might seem slightly pointless
as `Cool URIs don't change
<http://www.w3.org/Provider/Style/URI.html>`_. I don't want to argue
with that and not changing URL should be the primary goal. In case,
a URL is changed for some reason, however, this can reflect badly in
terms of SEO as search engines do not appreciate ending up on a 404
page when crawling a known URL. To handle these situations nicely
``django-url-tracker`` keeps track of URL changes and when the *old*
URL is called provides a permanent redirect (HTTP 301) or a gone
response (HTTP 410) for deleted URLs.

The tracking is aimed at those URLs that are generated based on
model fields, e.g. a *slug* field. To start tracking URL changes
for a particular model, you simply have to register the model
with ``url_tracker`` and everytime a model is changed or deleted,
URL changes are recorded.

The HTTP repsonses that provide an ``HttpResponsePremanentRedirect``
or ``HttpResponseGone`` are handled similar to the ``flatpages``
middleware, intercepting ``404`` exceptions and checking for the
requested URLs in all existing ``URLChangeRecords``. Depending
on the recorded data the corresponding HTTP response is return or
a ``404`` is raised when no URL matching the requested one can be
found.

Installation
------------

Installation is as easy as::

    pip install django-url-tracker

Done!

Configuration
-------------

To start using ``url_tracker`` in your project. Just add the
following two lines to your ``settings.py``:

1. Add the middleware ``url_tracker.middleware.URLChangePermanentRedirectMiddleware``
   to the end of  ``MIDDLEWARE_CLASSES`` which should look similar
   to this afterwards::

        MIDDLEWARE_CLASSES = (
            'django.middleware.common.CommonMiddleware',
            'django.contrib.sessions.middleware.SessionMiddleware',
            'django.middleware.csrf.CsrfViewMiddleware',
            'django.contrib.auth.middleware.AuthenticationMiddleware',
            'django.contrib.messages.middleware.MessageMiddleware',
            'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
            'url_tracker.middleware.URLChangePermanentRedirectMiddleware',
        )

2. Add ``url_tracker`` to your ``INSTALLED_APPS`` ::

       INSTALLED_APPS = (
            "url_tracker",
       )



Now you are able to use ``url_tracker`` within you project. All that
remains to do is registering a model for tracking.

Tracking A Model
----------------

This is just a simple example of how to track a model. Let's assume we
have a model ``Project`` that hold details on this particular project and
is made available at the URL ``http://www.example.com/project/some-project/``.
The project's URL is based on the ``SlugField`` of our model. The model could
look like this::

    class Project(models.Model):
        name = models.CharField(max_length=20)
        slug = models.SlugField(max_length=20)
        description = models.CharField(max_length=500)


I will not go into details of how to create the slug as I think this is
common practise. So for now we just assume that ``slug`` is populated
automatically from ``name``. One other thing, however, is required for
the tracker to work, the ``get_absolute_url`` method. Let's add this to
the model::

    class Project(models.Model):
        ...

        @models.permalink
        def get_absolute_url(self):
            return ('project-detail', (), {'slug': self.slug})

And now the missing link to actually start tracking URL changes is adding
the following command to the bottom of the class definition, or the file
for that matter, after adding the mixin to the class. To change which
functions are called to tracks urls, add a ``url_tracking_methods`` 
attribute to the clast, which is a list of method names to track. By
default the the list contains ``get_absolute_url``::

    import url_tracker

    class Project(url_tracker.URLTrackingMixin, models.Model):
        ...

    url_tracker.track_url_changes_for_model(Project)

You are done. If you go to the admin interface, create a new project
and then change its slug (which changes its URL) you will see a new
``URLChangeRecord`` reflecting the change. Opening the ``old_url`` should
then redirect you to the ``new_url``.

Contributing
------------

If you find issues or would like to see a feature suppored, head over to
the `issues section:
<https://github.com/tangentlabs/django-url-tracker/issues>`_ and report it.

To contribute code in any form, fork the `github repository:
<https://github.com/tangentlabs/django-url-tracker>`_ and clone it locally.
Create a new branch for your feature::

    git commit -b feature/whatever-you-like

push the finished feature to github and open a pull request form the branch.

If you make a change to models.py that requires a database migration,
use ``django-mini.py -p --app url_tracker --app south schemamigration
url_tracker --auto`` to create a south migration.<commit_msg>Add minor change to updated docs<commit_after>django-url-tracker
==================

.. image:: https://travis-ci.org/elbaschid/django-url-tracker.png
    :target: https://travis-ci.org/elbaschid/django-url-tracker

The ``django-url-tracker`` is meant to be a easy-to-use addition to
a website to enhance its SEO. This might seem slightly pointless
as `Cool URIs don't change
<http://www.w3.org/Provider/Style/URI.html>`_. I don't want to argue
with that and not changing URL should be the primary goal. In case,
a URL is changed for some reason, however, this can reflect badly in
terms of SEO as search engines do not appreciate ending up on a 404
page when crawling a known URL. To handle these situations nicely
``django-url-tracker`` keeps track of URL changes and when the *old*
URL is called provides a permanent redirect (HTTP 301) or a gone
response (HTTP 410) for deleted URLs.

The tracking is aimed at those URLs that are generated based on
model fields, e.g. a *slug* field. To start tracking URL changes
for a particular model, you simply have to register the model
with ``url_tracker`` and everytime a model is changed or deleted,
URL changes are recorded.

The HTTP repsonses that provide an ``HttpResponsePremanentRedirect``
or ``HttpResponseGone`` are handled similar to the ``flatpages``
middleware, intercepting ``404`` exceptions and checking for the
requested URLs in all existing ``URLChangeRecords``. Depending
on the recorded data the corresponding HTTP response is return or
a ``404`` is raised when no URL matching the requested one can be
found.

Installation
------------

Installation is as easy as::

    pip install django-url-tracker

Done!

Configuration
-------------

To start using ``url_tracker`` in your project. Just add the
following two lines to your ``settings.py``:

1. Add the middleware ``url_tracker.middleware.URLChangePermanentRedirectMiddleware``
   to the end of  ``MIDDLEWARE_CLASSES`` which should look similar
   to this afterwards::

        MIDDLEWARE_CLASSES = (
            'django.middleware.common.CommonMiddleware',
            'django.contrib.sessions.middleware.SessionMiddleware',
            'django.middleware.csrf.CsrfViewMiddleware',
            'django.contrib.auth.middleware.AuthenticationMiddleware',
            'django.contrib.messages.middleware.MessageMiddleware',
            'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
            'url_tracker.middleware.URLChangePermanentRedirectMiddleware',
        )

2. Add ``url_tracker`` to your ``INSTALLED_APPS`` ::

       INSTALLED_APPS = (
            "url_tracker",
       )



Now you are able to use ``url_tracker`` within you project. All that
remains to do is registering a model for tracking.

Tracking A Model
----------------

This is just a simple example of how to track a model. Let's assume we
have a model ``Project`` that hold details on this particular project and
is made available at the URL ``http://www.example.com/project/some-project/``.
The project's URL is based on the ``SlugField`` of our model. The model could
look like this::

    class Project(models.Model):
        name = models.CharField(max_length=20)
        slug = models.SlugField(max_length=20)
        description = models.CharField(max_length=500)


I will not go into details of how to create the slug as I think this is
common practise. So for now we just assume that ``slug`` is populated
automatically from ``name``. One other thing, however, is required for
the tracker to work, the ``get_absolute_url`` method. Let's add this to
the model::

    class Project(models.Model):
        ...

        @models.permalink
        def get_absolute_url(self):
            return ('project-detail', (), {'slug': self.slug})

And now the missing link to actually start tracking URL changes. Add the
``URLTrackingMixin`` to your model and add the following command to the
bottom of the class definition (or the file if you prefer that)::

    import url_tracker

    class Project(url_tracker.URLTrackingMixin, models.Model):
        ...

    url_tracker.track_url_changes_for_model(Project)


To change which functions are called to tracks urls, add a
``url_tracking_methods`` attribute to the clast, which is a list of
method names to track. By default the the list contains
``get_absolute_url``.

You are done. If you go to the admin interface, create a new project
and then change its slug (which changes its URL) you will see a new
``URLChangeRecord`` reflecting the change. Opening the ``old_url`` should
then redirect you to the ``new_url``.

Contributing
------------

If you find issues or would like to see a feature suppored, head over to
the `issues section:
<https://github.com/tangentlabs/django-url-tracker/issues>`_ and report it.

To contribute code in any form, fork the `github repository:
<https://github.com/tangentlabs/django-url-tracker>`_ and clone it locally.
Create a new branch for your feature::

    git commit -b feature/whatever-you-like

push the finished feature to github and open a pull request form the branch.

If you make a change to models.py that requires a database migration,
use ``django-mini.py -p --app url_tracker --app south schemamigration
url_tracker --auto`` to create a south migration.
{'fraction_non_alphanumeric': 0.09172302124011811, 'fraction_numerical': 0.004762358319839985, 'mean_word_length': 3.679144385026738, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 8, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '40283', 'n_tokens_mistral': 2968, 'n_tokens_neox': 2841, 'n_words': 1262}