diff --git a/docs/deployment.rst b/docs/deployment.rst index 615842c..6f55b02 100644 --- a/docs/deployment.rst +++ b/docs/deployment.rst @@ -108,6 +108,24 @@ Adding Redis caching on Heroku 3. The application will automatically start caching if you used the redis cloud addon described above. You can use a different Redis caching add-on, but you'll need to change the setup of the caching layer in `cache.py` appropriately. 4. See docs related to `using Python with redis on Heroku `_ +Using Redis to store Featured Guide +----------------------------------- + +By default, the featured guide is stored in an environment variable called +`FEATURED_TITLE`. This environment variable must be set in a way that will +persist across all running instances of the application. You can do this with +the Heroku CLI or admin panel, if you're running on Heroku. + +A better solution for managing the featured guide is to use Redis. The CMS +will automatically use a single key in the 'caching' Redis database mentioned +above if you're using the `REDISCLOUD_URL` setup. So, there's no need to worry +about this if you are using the standard caching setup with `REDISCLOUD_URL`. + +**You will not be able to set the featured guide via the CMS UI if you're not +using Redis to store the featured guide.** This is because setting an +environment variable via the application itself is unreliable if you're running +multiple instances of the application on multiple dynos or servers. + Useful Heroku add-ons --------------------- diff --git a/pskb_website/lib.py b/pskb_website/lib.py index 6a4d564..061c142 100644 --- a/pskb_website/lib.py +++ b/pskb_website/lib.py @@ -115,29 +115,3 @@ def lookup_url_redirect(requested_url): pass return new_url - - -def find_featured_article(articles=None): - """ - Find featured article in list of articles or published articles - - :params articles: List of article objects to search for featured article or - use published articles if no list is given - :returns: Article object of featured article or None if not found - """ - - featured = os.environ.get('FEATURED_TITLE') - if featured is None: - return None - - if articles is None: - # FIXME: This should only fetch the most recent x number. - articles = list(models.get_available_articles(status=PUBLISHED)) - - featured = featured.strip() - - for article in articles: - if article.title.strip() == featured: - return article - - return None diff --git a/pskb_website/models/__init__.py b/pskb_website/models/__init__.py index f257e3c..214cddb 100644 --- a/pskb_website/models/__init__.py +++ b/pskb_website/models/__init__.py @@ -19,6 +19,10 @@ from .file import read_redirects from .file import update_article_listing +from .featured import allow_set_featured_article +from .featured import set_featured_article +from .featured import get_featured_article + from .user import find_user from .email_list import add_subscriber diff --git a/pskb_website/models/featured.py b/pskb_website/models/featured.py new file mode 100644 index 0000000..931827f --- /dev/null +++ b/pskb_website/models/featured.py @@ -0,0 +1,75 @@ +""" +Handle storing and retrieving featured article + +The FEATURED_TITLE can only be set via the UI when there's an available +persistent storage mechanism like Redis configured. Otherwise the +FEATURED_TITLE is stored in an environment variable that cannot be set from the +UI. We do not allow setting of the environment variable from the UI because +the application could be running on multiple instances so setting a single +environment variable will only affect a single instance. + +You can use Heroku's admin panel or CLI to set environment variables for all +instances of your application, if you're running on Heroku without Redis. +""" + +import os + +from .. import PUBLISHED +from .. import cache +from . import get_available_articles + +KEY = 'FEATURED_TITLE' + + +def allow_set_featured_article(): + """ + Return True or False if the ability to set the featured article is allowed + from the UI. If False, then the featured guide should be set via an + environment variable called FEATURED_TITLE. + """ + + return cache.is_enabled() + + +def set_featured_article(title): + """ + Set featured article + + :param title: Title of featured article + """ + + # None for timeout b/c this should never expire + cache.save(KEY, title, timeout=None) + + +def get_featured_article(articles=None): + """ + Find featured article in list of articles or published articles + + :params articles: List of article objects to search for featured article or + use published articles if no list is given + :returns: Article object of featured article or None if not found + """ + + featured = None + if allow_set_featured_article(): + featured = cache.get(KEY) + + if featured is None: + featured = os.environ.get(KEY) + + if featured is None: + return None + + if articles is None: + # FIXME: This should only fetch the most recent x number. + articles = list(get_available_articles(status=PUBLISHED)) + + featured = featured.strip() + + for article in articles: + # Don't allow surrounding spaces to mismatch + if article.title.strip() == featured: + return article + + return None diff --git a/pskb_website/templates/article.html b/pskb_website/templates/article.html index ac03458..d554c4f 100644 --- a/pskb_website/templates/article.html +++ b/pskb_website/templates/article.html @@ -155,20 +155,17 @@

Contributors

{% endif %} - {% if collaborator %} - {% if article.published %} -
- - - -
- {% endif %} + {% if allow_set_featured %} +
+ + + +
{% endif %} - {% if branches %}
Community suggestions