Coder Social home page Coder Social logo

django-distill's Introduction

Hi

My GitHub profile hosts any public project that is polished enough to be released and used by others. Feel free to drop me an email, create issues or make contributions. A special massive thank you to anyone who sponsors me.

Cheers!

//meeb

🔗 meeb.org    |    📧 [email protected]


meeb's GitHub stats

django-distill's People

Contributors

anentropic avatar debdolph avatar dellsystem avatar ezra-risq avatar franckboyer avatar henhuy avatar jayfk avatar jesusanaya avatar lexifdev avatar lolcatrix avatar lukelambert avatar meeb avatar miguelgr avatar nkantar avatar parkan avatar tback avatar thatch avatar truetug avatar veselosky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-distill's Issues

ModuleNotFoundError: No module named 'future'

Traceback (most recent call last):
  File "manage.py", line 23, in <module>
    execute_from_command_line(sys.argv)
  File "/home/travis/virtualenv/python3.6.3/lib/python3.6/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "/home/travis/virtualenv/python3.6.3/lib/python3.6/site-packages/django/core/management/__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/travis/virtualenv/python3.6.3/lib/python3.6/site-packages/django/core/management/__init__.py", line 216, in fetch_command
    klass = load_command_class(app_name, subcommand)
  File "/home/travis/virtualenv/python3.6.3/lib/python3.6/site-packages/django/core/management/__init__.py", line 36, in load_command_class
    module = import_module('%s.management.commands.%s' % (app_name, name))
  File "/home/travis/virtualenv/python3.6.3/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/travis/virtualenv/python3.6.3/lib/python3.6/site-packages/django_distill/management/commands/distill-local.py", line 14, in <module>
    from django_distill.renderer import (run_collectstatic, render_to_dir)
  File "/home/travis/virtualenv/python3.6.3/lib/python3.6/site-packages/django_distill/renderer.py", line 11, in <module>
    from future.utils import raise_from
ModuleNotFoundError: No module named 'future'

the files out without extension

from django.urls import path
from . import views
from blog.models import Post, Category
from django_distill import distill_path
from django.template.defaultfilters import slugify

def get_index():
return None

def get_all_blogposts():
# This function needs to return an iterable of dictionaries. Dictionaries
# are required as the URL this distill function is for has named parameters.
# You can just export a small subset of values here if you wish to
# limit what pages will be generated.
for post in Post.objects.all():

    yield {'pk': post.id, 'slug': slugify(post.title)}

urlpatterns = [
distill_path('post/int:pk/slug:slug',
views.PostDetailView.as_view(),
name='post',
distill_func=get_all_blogposts,
),

distill_path('',
             views.home,
             name='home',
             # Note that for paths which have no paramters
             # distill_func is optional
             distill_func=get_index,
             # / is not a valid file name! override it to index.html
             distill_file='index.html'),

# path('', views.home, name="home"),
    
path('author/', views.author, name="author"),
# path('post/<int:pk>/<slug:slug>/', views.PostDetailView.as_view(), name="post"),
]

Single file output support

Distill should support writing out single files to disk with a similar interface to Django's urls.reverse. This would allow signals to save single files to disk on saving a model and other convenient interfaces.

Make `distill_func` optional

I find that I very often create a function that does nothing:

def return_none() -> None:
    return None

just so I can provide it to distill_func:

urlpatterns = [
    distill_path('', TemplateView.as_view(template_name='home.html'), name='home',
                 distill_func=return_none),
    # ... (the same repeating many times)
]

It seems that using a return_none-like function by default (and defaulting to it when it is not provided for distill_path) would be a more elegant approach in these cases.

Unable to install via pip

The packages setup.py imports __version__ from django_distill/__init__.py which imports url from django.conf.urls.

This is problematic if Django is not installed, e.g. when using pip to install all the packages in a requirements.txt and pip decides to install django-distill before it is installing Django.

Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-pr2k64s3/django-distill/setup.py", line 6, in <module>
        from django_distill import __version__ as version
      File "/tmp/pip-build-pr2k64s3/django-distill/django_distill/__init__.py", line 4, in <module>
        from django_distill.distill import distill_url
      File "/tmp/pip-build-pr2k64s3/django-distill/django_distill/distill.py", line 4, in <module>
        from django.conf.urls import url
    ModuleNotFoundError: No module named 'django'

Is it possible to customize rendering or add functionalities to existing rendering by getting pre/ post signals

Hi ,

I find the library easy to use and simple to understand. I have certain requirements and would be great if i can solve it with the django-distill library.
Some information on the usecases.

  • Currently during the rendering process, the settings.STATIC_URL is used during generation process. Is it possible to change during the rendering process, that it points to the settings.DISTILL_DIR/static ?... currently the complete folder structure is generated and it works as long as i am opening the project in the same OS env(Ubuntu) but doesnt work when i change to windows for e.g.,

  • Currently media files used in the web project, are hosted in azure web services. I would like to have a pre signal so that i can also deploy the media files inside the settings.DISTILL_DIR. This will help in using the static files in an environment which is not connected to the internet.
    Thanks in advance

BR
SK

worki with multiple models

Hi, I try to understand how can I generate my project in static files. It has multiple class objects in views and to be honest I don't know how pass them to distill_func . For example my index looks like this:

def index(request, *args, **kwargs):
    multilanguage = Multilanguage.objects.exclude(multilanguage_marker=False)
    site_seo_tools = SiteSeoTools.objects.first()
    carousel = Carousel.objects.all()
    homepage = Homepage.objects.first()
    box = Box.objects.exclude(display=False)
    subpage_sorted = Subpage.objects.exclude(is_active=False).order_by('display_order')
    context = {
        'carousel':carousel, 
        'multilanguage':multilanguage,
        'site_seo_tools':site_seo_tools, 
        'homepage': homepage,
        'box': box,
        'subpage_sorted': subpage_sorted,
        'recaptcha':settings.GOOGLE_RECAPTCHA
    }
    return render(request, 'home.html', context)

How can I do that ?

 character being generated by distill-local

Hello, I am using django-distill to build a site locally and when I generate the site, every time I use the builtin humanize "naturaltime" filter an "Â" character is inserted in between the number and the time (e.g. "19Â hours ago"). This is not occurring on either my development server, or the production apache server I am using - only during the local generation of django-distill.

Any ideas where I might be able to go to fix this? Do I need to specify utf8 encoding somewhere for django-distill to use?
Thanks so much for the help!

Django 2.0 replaced django.core.urlresolvers with django.urls

setup.py & requirements.txtdo not pin the version of Django, and Django 2.0 is out, and Django distill is broken.

  File "/home/travis/virtualenv/python3.6.3/lib/python3.6/site-packages/django_distill/management/commands/distill-local.py", line 14, in <module>
    from django_distill.renderer import (run_collectstatic, render_to_dir)
  File "/home/travis/virtualenv/python3.6.3/lib/python3.6/site-packages/django_distill/renderer.py", line 17, in <module>
    from django.core.urlresolvers import reverse
ModuleNotFoundError: No module named 'django.core.urlresolvers'

Refer to "django.core.urlresolvers" entry on their deprecation doc.

Remove the Rackspace Cloud Files backend

The Rackspace Cloud Files backend currently depends on Pyrax, which is Python2 only and depreciated. While there is an apparent replacement in the form of rackspacesdk all documentation is still for Pyrax and has not been updated. It's quite likely no-one uses this backend anyway any more given the popularity of S3 and Google Cloud Storage.

General plan at the moment is to remove the Rackspace Cloud Files backend and if anyone complains re-implement it with the openstacksdk, likely at quite some time expense given the sparse documentation and awkward testing.

Generate Sitemap

i have set up a django project following the documentation on the django site.

Everything works great in my dev setup.

I use distill to output HTML for the pages in the site so i can upload to an SFTP that only serves static html files.

I've the basic django sitemap framework and it also works great and i can navigate to it in the browser, but when i distill:

i get this error:

CommandError: Failed to render view "/sitemap.xml": sitemap() missing 1 required positional argument: 'sitemaps'

Im pretty new at this stuff, but any help would be much appreciated!

Does minification work with django-distill?

I have essentially copied your example site and started tweaking it (demo | repo),

I have django-htmlmin installed and it works just fine until I try to distill the site, then it is just ignored, and nothing is minified. I've tried different ideas from their docs to make it work for the distilled site as well, but I just cannot seem to figure anything out.

I'm just wondering if it is incompatible with django-distill, or if not, how would I make it work with the generated static site?

After I got this working, I was going to try using django-compressor for CSS, SASS and JS as well, but maybe you already know if this is is or is not compatible with django-distill too?

Thanks!

Django i18n support

Does django-distil generate i18n files. For example project.com/fr,project.com/de

'WSGIRequest' object has no attribute 'session'

Running python manage.py distill-local site-export produces the response CommandError: Failed to render view "/": 'WSGIRequest' object has no attribute 'session'
URLs.py config:

from django.urls import path
from django.contrib.auth.views import LoginView, LogoutView

from . import views

from django_distill import distill_path

def get_index():
    return None
def get_ageVerification():
    return None
def get_register():
    return None
def get_login():
    return None
def get_profile():
    return None
def get_message():
    return None
def get_messages():
    return None
def get_faq():
    return None
def get_legal():
    return None


urlpatterns = [
    distill_path('', views.index, name='index', distill_func=get_index, distill_file="index.html"),
    distill_path('ageVerification', views.ageVerification, name='ageVerification', distill_func=get_ageVerification),
    distill_path('register', views.register, name="register", distill_func=get_register),
    distill_path('login', LoginView.as_view(template_name='user/login.html'), name='login', distill_func=get_login),
    path('logout', LogoutView.as_view(), name='logout'),
    distill_path('accounts/profile/', views.profile, name="profileUser", distill_func=get_profile),
    distill_path('message/<str:username>', views.message, name="message", distill_func=get_message),
    distill_path('messages', views.messages, name="messages", distill_func=get_messages),
    distill_path('faq', views.faq, name="faq", distill_func=get_faq),
    distill_path('legal', views.legal, name="legal", distill_func=get_legal)
]

Keyword arguments are not utilized properly in distill_path

It looks like the following urlpatterns fails when the site is being generated:

urlpatterns = [
    distill_path(route='/', view=TemplateView.as_view(template_name='test.html'), name='index'),
]

It seems that runserver works fine though. I think the issue might be here: https://github.com/meeb/django-distill/blob/master/django_distill/renderer.py#L184, notice that k is not being used anywhere during the rendering, therefore neither the route nor the view gets forwarded properly in this case. It works fine when using positional arguments for the route and view instead of the named arguments. Nonetheless, in some cases using named arguments is unavoidable (e.g. if these arguments are coming from an unpacked dictionary).

Make copying of existing staticfiles and media optional

In my case, I want to serve distilled files as static files via Whitenoise.
Therefore I store disitilled files in my STATIC_ROOT.
Unfortunately, django-distill copies all existing staticfiles and media files into subfolder static in DISTILL_DIR when running distill-local - and thus all files are copied unnecessarily.

I created a PR in which copying of staticfiles and media can be suppressed by giving an extra option --exclude-staticfiles. Maybe this is also helpful for others?
See my branch https://github.com/henhuy/django-distill/tree/optional_static_and_media

Change Detection?

I think this may be a feature request, but does django-distill support generating static pages only for database records that have changed since the last generation, or does it re-generate all static pages every time the distill-local command is run?

How to protect .git directory with distill-local

I'm trying to turn a django site into a static site using https://github.com/mgrp/django-distill . I am outputting the static files into

/e/ENVS/STATIC/static1

on my win10 local system. As I make changes I want to overwrite all the non hidden files including the .git directory, the commit and push the changes to my github repo for deployment. Unfortunately the distill project overwrites the entire directory , deleting the .git/ files. I've tried to protect the git files with

$ chmod -R 707 .git/ 

using git-bash, but the output looks like:

drwxr-xr-x 1 me 197121     0 Oct 21 14:35 ./
drwxr-xr-x 1 me 197121     0 Oct 20 17:11 ../
drwxr-xr-x 1 me 197121     0 Oct 21 14:35 .git/
drwxr-xr-x 1 me 197121     0 Oct 21 14:36 .idea/
-rw-r--r-- 1 me 197121  9963 Oct 21 15:02 agreement.html
-rw-r--r-- 1 me 197121    17 Oct 21 15:02 contact.html
-rw-r--r-- 1 me 197121 14027 Oct 21 15:02 documents.html
-rw-r--r-- 1 me 197121 17048 Oct 21 15:02 form.html
-rw-r--r-- 1 me 197121 11060 Oct 21 15:02 index.html
-rw-r--r-- 1 me 197121  4921 Oct 21 15:02 slideshow.html
drwxr-xr-x 1 me 197121     0 Oct 21 15:02 static/

Do you have any advice on how to protect the .git/ directory or copy the new files without deleting the .git directory. This would really simplify the workflow, by allowing you to quickly stage and push to my github repo which is linked to (in my case) a netlify account.

Missing files in sdist

It appears that the manifest is missing at least one file necessary to build
from the sdist for version 1.7. You're in good company, about 5% of other
projects updated in the last year are also missing files.

+ /tmp/venv/bin/pip3 wheel --no-binary django-distill -w /tmp/ext django-distill==1.7
Looking in indexes: http://10.10.0.139:9191/root/pypi/+simple/
Collecting django-distill==1.7
  Downloading http://10.10.0.139:9191/root/pypi/%2Bf/21a/b421401e178b1/django-distill-1.7.tar.gz (20 kB)
    ERROR: Command errored out with exit status 1:
     command: /tmp/venv/bin/python3 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-wheel-467cbaw4/django-distill/setup.py'"'"'; __file__='"'"'/tmp/pip-wheel-467cbaw4/django-distill/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-wheel-467cbaw4/django-distill/pip-egg-info
         cwd: /tmp/pip-wheel-467cbaw4/django-distill/
    Complete output (5 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-wheel-467cbaw4/django-distill/setup.py", line 15, in <module>
        with open('requirements.txt', 'rt') as f:
    FileNotFoundError: [Errno 2] No such file or directory: 'requirements.txt'
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

static files are not being generated.

I am using latest version of django-distill. Whenever I use command: python .\manage.py distill-local --force --collectstatic, I can't see generated static folder.
my static root settings. STATIC_ROOT = BASE_DIR/"static".
What I want is the static folder to appear in folder setted in DISTILL_DIR.

Could you release a new version with changes on main

Because the current release has an import issue with the MiddlewareNotUsed not being defined but is fixed on main.

 File "/Users/tgsoverly/code/core/api/venv/lib/python3.10/site-packages/django_distill/renderer.py", line 404, in render_single_file
    page_uri, file_name, http_response = renderer.render(
  File "/Users/tgsoverly/code/core/api/venv/lib/python3.10/site-packages/django_distill/renderer.py", line 205, in render
    return self.render_file(view_name, status_codes, view_args, view_kwargs)
  File "/Users/tgsoverly/code/core/api/venv/lib/python3.10/site-packages/django_distill/renderer.py", line 181, in render_file
    render = self.render_view(uri, status_codes, args, a)
  File "/Users/tgsoverly/code/core/api/venv/lib/python3.10/site-packages/django_distill/renderer.py", line 272, in render_view
    handler.load_middleware()
  File "/Users/tgsoverly/code/core/api/venv/lib/python3.10/site-packages/django_distill/renderer.py", line 119, in load_middleware
    except MiddlewareNotUsed as exc:
NameError: name 'MiddlewareNotUsed' is not defined

Namespaces not taken into account

I wanted to distill views from an app (via python manage.py distill-local), but I think distill does not take namespaces into account...
I tried with following setup:

# base urls.py
urlpatterns = [
    ...
    path("", include("djagora.map.urls", namespace="map")),
]

# map/urls.py
app_name = "map"

urlpatterns = [
    ...
    distill_path(
        "some_view/",
        view=views.SomeView.as_view(),
        name="some",
    ),
]

But this lead to an error when generating uri:

uri = self.generate_uri(view_name, param_set)

as view_name only contains "some", but correct reverse name would be "map:some".
After setting view_name = "map:some" within debugging mode, script goes on without error (giving me some errors later, but this does not belong here).
Can you confirm this error, or am I missing something?

Django CMS

Hi, I am trying to install django-distil in a project with Django CMS. It's compatible ?

My problem is in the urls.py, in these lines:

urlpatterns = [
        distill_path('',
                 details,
                 name='blog-index',
                 distill_func=get_index,
                 # / is not a valid file name! override it to index.html
                 distill_file='index.html'),
    # e.g. /post/123-some-post-title using named parameters

I get the following error when running distil-local:

CommandError: Failed to render view "/": details() missing 1 required positional argument: 'slug'

if I pass slug = None on details() I get the following error:

TypeError: details() missing 1 required positional argument: 'request'

I don't know much about it, but I think the problem is class-based views and function-based views.

This is the code for the views.py of Django CMS:

from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login
from django.contrib.auth.views import redirect_to_login
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.utils.cache import patch_cache_control
from django.utils.http import is_safe_url, urlquote
from django.utils.timezone import now
from django.utils.translation import get_language_from_request
from django.views.decorators.http import require_POST

from cms.cache.page import get_page_cache
from cms.exceptions import LanguageError
from cms.forms.login import CMSToolbarLoginForm
from cms.models.pagemodel import TreeNode
from cms.page_rendering import _handle_no_page, render_page, render_object_structure, _render_welcome_page
from cms.toolbar.utils import get_toolbar_from_request
from cms.utils import get_current_site
from cms.utils.conf import get_cms_setting
from cms.utils.i18n import (get_fallback_languages, get_public_languages,
                            get_redirect_on_fallback, get_language_list,
                            get_default_language_for_site,
                            is_language_prefix_patterns_used)
from cms.utils.page import get_page_from_request
from cms.utils.page_permissions import user_can_change_page


def _clean_redirect_url(redirect_url, language):
    if (redirect_url and is_language_prefix_patterns_used() and redirect_url[0] == "/"
            and not redirect_url.startswith('/%s/' % language)):
        # add language prefix to url
        redirect_url = "/%s/%s" % (language, redirect_url.lstrip("/"))
    return redirect_url


def details(request, slug):
    """
    The main view of the Django-CMS! Takes a request and a slug, renders the
    page.
    """
    response_timestamp = now()
    if get_cms_setting("PAGE_CACHE") and (
        not hasattr(request, 'toolbar') or (
            not request.toolbar.edit_mode_active and
            not request.toolbar.show_toolbar and
            not request.user.is_authenticated
        )
    ):
        cache_content = get_page_cache(request)
        if cache_content is not None:
            content, headers, expires_datetime = cache_content
            response = HttpResponse(content)
            response.xframe_options_exempt = True
            response._headers = headers
            # Recalculate the max-age header for this cached response
            max_age = int(
                (expires_datetime - response_timestamp).total_seconds() + 0.5)
            patch_cache_control(response, max_age=max_age)
            return response

    # Get a Page model object from the request
    site = get_current_site()
    page = get_page_from_request(request, use_path=slug)
    toolbar = get_toolbar_from_request(request)
    tree_nodes = TreeNode.objects.get_for_site(site)

    if not page and not slug and not tree_nodes.exists():
        # render the welcome page if the requested path is root "/"
        # and there's no pages
        return _render_welcome_page(request)

    if not page:
        # raise 404
        _handle_no_page(request)

    request.current_page = page

    if hasattr(request, 'user') and request.user.is_staff:
        user_languages = get_language_list(site_id=site.pk)
    else:
        user_languages = get_public_languages(site_id=site.pk)

    request_language = get_language_from_request(request, check_path=True)

    if not page.is_home and request_language not in user_languages:
        # The homepage is treated differently because
        # when a request goes to the root of the site (/)
        # without a language, Django will redirect to the user's
        # browser language which might not be a valid cms language,
        # this means we need to correctly redirect that request.
        return _handle_no_page(request)

    # get_published_languages will return all languages in draft mode
    # and published only in live mode.
    # These languages are then filtered out by the user allowed languages
    available_languages = [
        language for language in user_languages
        if language in list(page.get_published_languages())
    ]

    own_urls = [
        request.build_absolute_uri(request.path),
        '/%s' % request.path,
        request.path,
    ]

    try:
        redirect_on_fallback = get_redirect_on_fallback(request_language, site_id=site.pk)
    except LanguageError:
        redirect_on_fallback = False

    if request_language not in user_languages:
        # Language is not allowed
        # Use the default site language
        default_language = get_default_language_for_site(site.pk)
        fallbacks = get_fallback_languages(default_language, site_id=site.pk)
        fallbacks = [default_language] + fallbacks
    else:
        fallbacks = get_fallback_languages(request_language, site_id=site.pk)

    # Only fallback to languages the user is allowed to see
    fallback_languages = [
        language for language in fallbacks
        if language != request_language and language in available_languages
    ]
    language_is_unavailable = request_language not in available_languages

    if language_is_unavailable and not fallback_languages:
        # There is no page with the requested language
        # and there's no configured fallbacks
        return _handle_no_page(request)
    elif language_is_unavailable and (redirect_on_fallback or page.is_home):
        # There is no page with the requested language and
        # the user has explicitly requested to redirect on fallbacks,
        # so redirect to the first configured / available fallback language
        fallback = fallback_languages[0]
        redirect_url = page.get_absolute_url(fallback, fallback=False)
    else:
        page_path = page.get_absolute_url(request_language)
        page_slug = page.get_path(request_language) or page.get_slug(request_language)

        if slug and slug != page_slug and request.path[:len(page_path)] != page_path:
            # The current language does not match its slug.
            # Redirect to the current language.
            return HttpResponseRedirect(page_path)
        # Check if the page has a redirect url defined for this language.
        redirect_url = page.get_redirect(request_language, fallback=False) or ''
        redirect_url = _clean_redirect_url(redirect_url, request_language)

    if redirect_url:
        if request.user.is_staff and toolbar.edit_mode_active:
            toolbar.redirect_url = redirect_url
        elif redirect_url not in own_urls:
            # prevent redirect to self
            return HttpResponseRedirect(redirect_url)

    # permission checks
    if page.login_required and not request.user.is_authenticated:
        return redirect_to_login(urlquote(request.get_full_path()), settings.LOGIN_URL)

    if hasattr(request, 'toolbar'):
        request.toolbar.set_object(page)

    structure_requested = get_cms_setting('CMS_TOOLBAR_URL__BUILD') in request.GET

    if user_can_change_page(request.user, page) and structure_requested:
        return render_object_structure(request, page)
    return render_page(request, page, current_language=request_language, slug=slug)


@require_POST
def login(request):
    redirect_to = request.GET.get(REDIRECT_FIELD_NAME)

    if not is_safe_url(url=redirect_to, allowed_hosts=request.get_host()):
        redirect_to = reverse("pages-root")

    if request.user.is_authenticated:
        return HttpResponseRedirect(redirect_to)

    form = CMSToolbarLoginForm(request=request, data=request.POST)

    if form.is_valid():
        auth_login(request, form.user_cache)
    else:
        redirect_to += u'?cms_toolbar_login_error=1'
    return HttpResponseRedirect(redirect_to)

I hope you can help me, thank you very much.

Triggering page generation manually?

Hi. Is there a way to trigger the generation of static pages manually? Eg. Trigger it to render on receiver save?

I've got 50000 mostly static pages that only need to be refreshed once a day. What's the best way to handle that? It would take too long to prerender 50K pages everytime I deploy.

Thanks

Why are 'admin' and 'grapelli' excluded from the static files copy?

I am really liking django-distill for a hobby project of mine.
Spent quite a while wondering why, after I had run collectstatic and then run distill-local, the static files for every application except admin were ending up in my target directory.

I now see that admin and grappelli are hard-coded in as exclusions - https://github.com/meeb/django-distill/blob/master/django_distill/renderer.py#L229

How come these are excluded? The comments in the file don't help me understand. If there is no reason, I'll happily try and submit a pull request that stops it happening. If there is a good reason, I'll submit a pull request that mentions it in the documentation!

Add an Azure blob store backend

Add a backend for Azure blob storage. This should be relatively easy and drop in next to the existing Google Cloud Files and S3 backends.

Switch to using boto3

The Amazon S3 backend needs to be updated to use the boto3 library rather than the now legacy boto library.

Usage of "include" in distill_url?

Hey @meeb I've been using django_distill in a project and we want to include another package that uses django_distill using include(). But I'm getting failed to do that because instead of passing a view_func example MyVIew.as_view(), I'm passing a tuple i.e. include(package_name.urls). Can you please help me out? Is there any way I can get that possible using include() ?

HttpResponse content not rendered in distill-local

When using distill-local I became following error:
django.template.response.ContentNotRenderedError: The response content must be rendered before it can be accessed.
in line:

content = http_response.content

because http_responseis not rendered yet.
After adding http_response.render() before that line, everything seems to work and distilled files are generated...
Is this fix correct?
I will post simple PR...

Feature: Propagate view_name to distill_func

I want to make my distill_func to be aware of given view_name.
Use case:

  • Generate multiple distill_paths in a for loop:
views = [("name", View), ("name2", View2)]
urlpatterns += [
    distill_path(
        f"{name}_url/",
        view.as_view(),
        name=name,
        distill_func=get_params
    )
    for name, view in views
]
  • get different params depending on view name:
def get_params(view_name):
     if view_name == "name":
         return 1
     else:
         return 2

This is very usefull for me. Maybe for others too?
Will provide PR if you want to merge...

Broken link on site

Went to the installation page - https://django-distill.com/install . At the bottom of the page is the link to the intergration
image

Clicked on the link and it went to the following incorrect address; https://django-distill.com/integration.html. This address should be https://django-distill.com/integration

How can I render the static generated html files without GET Request to CMS

Hello.
I'm trying to create a Django blog site using a headless CMS.
Today I found django-distill and succeeded in generating static html files.

python ./manage.py distill-local

I don't want to send a GET request every time I render, so I'm thinking of using django-distill.
How can I display the statically generated site when I run python manage.py runserver?
Is the static site delivered after deployment in the first place?
Sorry for the rudimentary question.

I'll paste the source code that I think is relevant below.

#project/settings.py

...

STATIC_ROOT = Path(BASE_DIR, 'static')
DISTILL_DIR = Path(BASE_DIR, 'dist')
#project/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls'))
]
#blog.urls.py

from django_distill import distill_path, distill_url
from . import views
from django.conf import settings
import requests

app_name = 'blog'


def get_index():
    return None


def get_posts():
    end_point = '/post'
    url = getattr(settings, "BASE_URL", None)
    api_key = getattr(settings, "API_KEY", None)
    headers = {'API-KEY': api_key}
    res = requests.request('GET', url=url + end_point, headers=headers)
    for data in res.json()['contents']:
        yield data['id']


urlpatterns = [
    distill_path('',
                 views.post_list,
                 name='index',
                 distill_func=get_index,
                 distill_file='index.html'),

    distill_path('post/<slug:slug>.html',
                 views.post_detail,
                 name='post_detail',
                 distill_func=get_posts),
]
# blog/views.py

from django.shortcuts import render
import requests
from django.conf import settings
from django.http import Http404


def post_list(request):
    end_point = '/post'
    url = getattr(settings, "BASE_URL", None)
    api_key = getattr(settings, "API_KEY", None)
    headers = {'API-KEY': api_key}
    res = requests.request('GET', url=url + end_point, headers=headers)
    context = {
        'post_list': res.json()['contents']
    }

    return render(request, 'blog/index.html', context)


def post_detail(request, slug):
    end_point = f'/post/{slug}'
    url = getattr(settings, "BASE_URL", None)
    api_key = getattr(settings, "API_KEY", None)
    headers = {'API-KEY': api_key}
    res = requests.request('GET', url=url + end_point, headers=headers)
    if res.status_code != 200:
        raise Http404

    context = {
        'post': res.json()
    }

    return render(request, 'blog/post_detail.html', context)

NoReverseMatch exception introduced in version 2.4

After upgrading django-distill from version 1.9 to the latest 3.0.2 admin views in my app started to crash with the following error

django.urls.exceptions.NoReverseMatch: Reverse for 'app_list' with keyword arguments '{'app_label': 'web'}' not found. 1 pattern(s) tried: ['__website_manager/(?P<app_label>auth)/$']

With a trial and error I found that versions prior to 2.3 are working normally, version 2.3 crashes the whole app on startup with:

File "/Users/ivan/.local/share/virtualenvs/adesk-website-mLhlACXX/lib/python3.8/site-packages/django_distill/renderer.py", line 40, in <module>
    nspath = ':'.join(namespaces)
TypeError: sequence item 1: expected str instance, NoneType found

and versions starting from 2.4 produce errors mentioned above.

Feature reuest: Option to ignore render errors

For me it would be nice to add option to ignore non-200 errors on rendering pages.
I have a view which is filled with many parameters, but not all pages return status 200 (but 204 instead).
For me it would be nice to add option ignore_errors (default False) to distill_path.
Will also provide PR if this is interesting for others too.

Keywords not supported in distill_path

I stumbled upon keywords in distill_path function when switching from default django.urls.path to distill_path.
My original path looked something like this:

path(
    "distilled_forest/<int:wind_distance>/<int:forest_usage>",
    view=views.DistilledForestListAPIView.as_view(),
    name="distilled_forest",
)

Simply changing it into:

distill_path(
    "distilled_forest/<int:wind_distance>/<int:forest_usage>",
    view=views.DistilledForestListAPIView.as_view(),
    name="distilled_forest",
    distill_func=models.Setup.get_possible_setups
)

gave me a strange error without stack trace:

Loading site URLs
CommandError: Invalid view arguments

But I could figure it out: distill_path expects first two arguments given as simple args (not kwargs) - See line:

if len(args) < 2:

This works:

distill_path(
    "distilled_forest/<int:wind_distance>/<int:forest_usage>",
    views.DistilledForestListAPIView.as_view(),
    name="distilled_forest",
    distill_func=models.Setup.get_possible_setups
)

Maybe this could be changed to support keyword args - or at least a better Exception with explanation could be thrown?

Getting a 301 error when running distill on server

Hi,

I am getting a strange 301 error which is not happening during local development, but only when running on an app server. The same distill action on a local server runs without any error.

Unfortunately, I cannot do a remote debug on the server. Some information on the error

image

image

image

I can add more debug information, but I don't know which would be of use here.

BR

SK

Configuring output of % static in django ?

enter image description here

I'm experimenting with django-distill (https://github.com/mgrp/django-distill) to generate a static site from a django project. i'm using django 1.10.8 . My main template contains:

<!-- Bootstrap Core CSS -->
{% load staticfiles %}
<link href="{% static "css/bootstrap.min.css" %}" rel="stylesheet" />

<!-- Custom CSS -->
<link href="{% static "css/landing-page.css" %}" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/jquery.slick/1.5.0/slick.css"/>

The paths to the css and js files are correct when I run the project locally on my windows system using a dev server. However when I look at the source html I see:

enter image description here

on my windows system this works with a running sever, i.e.

 http://127.0.0.1:8000/static/css/bootstrap.min.css

but it breaks with static files and I have to change these to

  <link href="./static/css/bootstrap.min.css" rel="stylesheet" />

Is there any way to set % static to render to

./static/ instead of /static/

Google Backend Remote path on windows

Hi, I'm using django-distill with the Google storage backend on windows. When uploading a file the remote path for the file becomes path\\to\\index.html. However Google storage interprets that literally and does not convert the windows path format. So the URL for the uploaded file becomes https://storage.googleapis.com/bucket/path%5Cto%5Cindex.html instead of the https://storage.googleapis.com/bucket/path/to/index.html that you would expect.

Would it be possible to convert the windows-style path format to the right url format before initiating the upload?

Prefix option for distill-local

Hi, I tried to use Django-distill to generate a site that I would like to host on Github Pages.
The problem is that Github pages for projects uses URLs that use the format https://<organization>.github.io/<repository> instead of serving from the root, and django-distill generates URLs that would only work if both the pages and the statics are served from the root.

Would it be possible to add a "prefix" option to distill-local.py to automatically fix the URLs to the matching format ?

(For example, if right now the command generates a path like "/tags/index.html" or "/static/css/main.css", with the --prefix=my-project parameter on the command line it would generate "/myproject/tags/index.html" and "/myproject/static/css/main.css" instead.)

i18n_patterns and django-distill

Hi,

I'm trying to use django-distill on my website that uses the function django.conf.urls.i18n.i18n_patterns to generate language dependent urls.

I got the exception django.core.exceptions.ImproperlyConfigured: Using i18n_patterns in an included URLconf is not allowed. that is raised by the django.conf.urls.include function. This is called in django-distill.renderer.load_urls.

Actually, I don't really understand what is the purpose of the call to the include command in load_urls since the result it returns is not used. As a matter of fact, everything seems to work well if I comment out this line in renderer.py

Is there a more suitable way to make this work ?

Best regards

how do i use django admin

i need to use django admin
It's possible ?
this distill_path generates error
distill_path('',
admin.site.urls,
name=''),

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.