kakulukia / pypugjs

PugJS syntax adapter for Django, Jinja2 and Mako templates
MIT License
255 stars 40 forks source link

"The mixin blocks are not supported yet." #62

Closed johnmathews closed 4 years ago

johnmathews commented 4 years ago

Is mixin block support planned? If not, is there a workaround?

Description

I have some pug templates with the following mixin syntax:

+navbar({
    navbarBg: 'bg-transparent',
    navbarStyle: 'navbar-dark',
    navbarBrandColor: 'text-white',
    navbarBtnColor: 'btn-teal',
    navbarContainer: 'container',
    navbarPosition: 'fixed-top'
})

which gives the following error: unexpected token "attrs" in file sb-ui-kit-pro/src/pug/pages/index.pug on line 18

If I reformat the mixin block to the following (so that the mixin is all on one line):

+navbar({ navbarBg: 'bg-transparent', navbarStyle: 'navbar-dark', navbarBrandColor: 'text-white', navbarBtnColor: 'btn-teal', navbarContainer: 'container', navbarPosition: 'fixed-top' })

then I get the following error: The mixin blocks are not supported yet.

Traceback:

Request Method: GET
Request URL: http://0.0.0.0:8000/users/about2/

Django Version: 3.0.5
Python Version: 3.8.0
Installed Applications:
['whitenoise.runserver_nostatic',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.humanize',
 'django.contrib.admin',
 'django.forms',
 'rest_framework',
 'crispy_forms',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'django_celery_beat',
 'django_cleanup.apps.CleanupConfig',
 'ft5.users.apps.UsersConfig',
 'ft5.transactions.apps.TransactionsConfig',
 'compressor',
 'debug_toolbar',
 'django_extensions']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'whitenoise.middleware.WhiteNoiseMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.common.BrokenLinkEmailsMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'debug_toolbar.middleware.DebugToolbarMiddleware']

Traceback (most recent call last):
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/core/handlers/base.py", line 145, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/core/handlers/base.py", line 143, in _get_response
    response = response.render()
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/template/response.py", line 81, in rendered_content
    template = self.resolve_template(self.template_name)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/template/response.py", line 63, in resolve_template
    return select_template(template, using=self.using)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/template/loader.py", line 42, in select_template
    return engine.get_template(template_name)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/template/backends/django.py", line 34, in get_template
    return Template(self.engine.get_template(template_name), self)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/template/engine.py", line 143, in get_template
    template, origin = self.find_template(template_name)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/template/engine.py", line 125, in find_template
    template = loader.get_template(name, skip=skip)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/ext/django/loader.py", line 44, in get_template
    return super(cached.Loader, self).get_template(template_name, **kwargs)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/django/template/loaders/base.py", line 24, in get_template
    contents = self.get_contents(origin)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/ext/django/loader.py", line 33, in get_contents
    contents = process(
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/utils.py", line 234, in process
    return _compiler.compile().strip()
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/compiler.py", line 104, in compile
    self.visit(self.node)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/compiler.py", line 134, in visit
    self.visitNode(node, *args, **kwargs)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/compiler.py", line 142, in visitNode
    return getattr(self, 'visit%s' % name)(node, *args, **kwargs)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/compiler.py", line 149, in visitBlock
    self.visit(node)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/compiler.py", line 134, in visit
    self.visitNode(node, *args, **kwargs)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/compiler.py", line 142, in visitNode
    return getattr(self, 'visit%s' % name)(node, *args, **kwargs)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/ext/django/compiler.py", line 41, in visitCodeBlock
    self.visitBlock(block)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/compiler.py", line 149, in visitBlock
    self.visit(node)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/compiler.py", line 134, in visit
    self.visitNode(node, *args, **kwargs)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/compiler.py", line 142, in visitNode
    return getattr(self, 'visit%s' % name)(node, *args, **kwargs)
  File "/Users/john/.virtualenvs/ft5/lib/python3.8/site-packages/pypugjs/ext/django/compiler.py", line 56, in visitMixin
    raise CurrentlyNotSupported("The mixin blocks are not supported yet.")

Exception Type: CurrentlyNotSupported at /users/about2/
Exception Value: The mixin blocks are not supported yet.
johnmathews commented 4 years ago

Is it feasible to use pypugjs to convert the pug template to jinja, and then use django's jinja backend? I'm trying this now, but am having trouble with relative/absolute file paths for the include statements.

kakulukia commented 4 years ago

Thats the way it works anyway .. pypugjs ist just producing the jinja input, which is then replacing variables. But in general mixins are supported: https://github.com/kakulukia/pypugjs#notable-features How are you trying to use em?

kakulukia commented 4 years ago
Bildschirmfoto 2020-05-25 um 14 53 56

And it still works.

How are you trying to use mixins?

johnmathews commented 4 years ago

include statements with paths that were relative to the files wouldn't work. e.g.: ../bar.pug doesn't work

i got it to kind of work by making all include statements contain file paths relative to the template dir specified in django's settings.py. e.g.: templates/foo/bar.pug

Also, i needed to list all the mixin arguments on one line: this doesn't work:

+myMixin({ 
    var1: 'anything', 
    var2: 'something else', 
 })

but this does work

+myMixin({ var1: 'anything',  var2: 'something else',  })

however i think its going to be simpler to use DRF and render the pug templates client side.

kakulukia commented 4 years ago

include statements with paths that were relative to the files wouldn't work. e.g.: ../bar.pug doesn't work

This might be a pug feature, but since pypugjs reuses Django's template loaders, you have to add any additional mixin dirs to the template directories to be able to include em that way.

Also, i needed to list all the mixin arguments on one line: this doesn't work:

+myMixin({ 
    var1: 'anything', 
    var2: 'something else', 
 })

but this does work

+myMixin({ var1: 'anything',  var2: 'something else',  })

This looks weird. Jinja uses double curly braces and your example looks like the javascript version. Since pypugjs is just translating pug to html and then feeding it to Jinja for variable replacement, i fear what you are trying to do is just not possible with pypugjs. :(

Anyway for anything more complex in the frontend my recommendation is to use VueJS rather than creating complex templates in Django. So yes, DRF would be the way to go .. or GraphQL.