Way to hook into convert_body_to_html

Issue #8 wontfix
Björn Lindqvist
created an issue

Often it would be nice to be able to apply your own text transformations to the source in addition to the rest formatting. For example, if you want to link certain keywords in the text. A hook of some kind to do this would be very useful.

Comments (10)

  1. H3n0xek
    • changed status to open

    Hi, Björn. How would you have implemented this?

    I see two (perhaps not so bad) solutions. They don't require to modify diario's code at all:

    1. just implement custom_convert_to_html handler in ur own app and replace diario's default with it
    2. make a template filter, in ur own app.
  2. Björn Lindqvist reporter

    I don't see how #1 is possible since convert_body_to_html is connected using signals to the Entitys save event. Preferably the hook should also be in addition to diario's regular code, not replace it.

  3. H3n0xek

    mmm, by replacing I meant such code snippet:

    def custom_convert_to_html(instance, **kwargs):
        body = unicode(markuping(instance.markup, instance.body_source))
        instance.body = own_proc(body)
    signals.pre_save.disconnect(convert_body_to_html, sender=Entry)
    signals.pre_save.connect(custom_convert_to_html, sender=Entry)

    Preferably the hook should also be in addition to diario's regular code, not replace it.

    Seriously, I don't see something terrible in copy&pasting of only one code line from convert_body_to_html. But if it does, here's an example of patch:

    ----- fragment of diario.signals module -----
    body_preprocess = django.dispatch.Signal(providing_args=["entry"])
    body_postprocess = django.dispatch.Signal(providing_args=["entry"])
    def convert_body_to_html(instance, **kwargs): # diario's signal handler
        body_preprocess.send(sender=instance, entry=instance)
        instance.body = unicode(markuping(instance.markup, instance.body_source))
        body_postprocess.send(sender=instance, entry=instance)
    ----- end of the fragment -----

    Feel free to suggest your vision on this.

  4. semente repo owner

    Hello Bjorn,

    As H3n0xek said, you are able to hook this connecting a different signal or using template filters with the field body_source, as for example:

    {% load markup %} {# django.contrib.markup #}
    {{ entry.body_source|my_linkify|markup:markdown }}

    That are your best options.

    Of course we can try improve this, to be easier to a user provide his own markuping function, but definitively is not priority now, I would do other things in Diario first. Anyway, if you find it useful, write your thoughts here and we can give a look when possible. :-)

  5. James Rivett-Carnac

    The problem with using filters in templates is that you loose the benefit of storing the parsed HTML code, as you have to do the conversion every time, which is more expensive. Another method would be to implement something like the middleware system in django, where `markuping` recieves a list of functions. This would also make it easier to apply multiple contributor transformations.

    Possibly doing this in dictionary form lets you apply different rules to different markups, randomly pulling an example implementation out of my head without deep consideration or checking:

        def markuping(markup, value):
                for transform in MARKUP_TRANSFORM[markup]:
                    value = transform(value)
            except KeyError:
            return value
  6. Björn Lindqvist reporter

    James is right. I did manage to override the default convert_body_to_html, but it's kind of hackish:

    from diario.utils import markuping
    from diario.signals import convert_body_to_html
    def my_convert_body_to_html(instance, **kwargs):
        body = unicode(markuping(instance.markup, source))
        # Stuff done to body here
        instance.body = body
    pre_save.connect(my_convert_body_to_html, sender = Entry)

    But it works good enough for me.

  7. semente repo owner

    Bjorn, that is the good way, since Diario's convert_body_to_html is connected by default.

    Diario 2.0 will let you provide a custom model and I have plans to move the markuping support to a contrib package. I will consider this ticket when creating this contrib package.

  8. Log in to comment