Giter VIP home page Giter VIP logo

timmyomahony / django-pagedown Goto Github PK

View Code? Open in Web Editor NEW
572.0 16.0 88.0 515 KB

A django app that allows the easy addition of Stack Overflow's "PageDown" markdown editor to a django form field, whether in a custom app or the Django Admin

License: BSD 3-Clause "New" or "Revised" License

Python 32.91% CSS 29.93% JavaScript 28.48% HTML 8.68%
django-pagedown django django-admin django-project pagedown markdown markdown-editor

django-pagedown's Introduction

Django Pagedown

Add Stack Overflow's "Pagedown" Markdown editor to your Django Admin or custom form.

Screenshot of Django Admin with Pagedown initialised

Requirements

Version >= 2.0.0 of django-pagedown requires Django 2.1.0 or above (previous versions should support Django all the way back to around 1.1).

Installation

  1. Get the code: pip install django-pagedown
  2. Add pagedown.apps.PagedownConfig to your INSTALLED_APPS in settings.py
  3. Configure and collect the static files: python manage.py collectstatic

Usage

The widget can be used both inside the django admin or independendly.

Inside the Django Admin:

If you want to use the pagedown editor in a django admin field, there are numerous possible approaches:

  • To use it in all TextField's in your admin form:

    from django.contrib import admin
    from django.db import models
    
    from pagedown.widgets import AdminPagedownWidget
    
    
    class AlbumAdmin(admin.ModelAdmin):
        formfield_overrides = {
            models.TextField: {'widget': AdminPagedownWidget },
        }
  • To only use it on particular fields, first create a form (in forms.py):

    from django import forms
    
    from pagedown.widgets import AdminPagedownWidget
    
    from music.models import Album
    
    class AlbumForm(forms.ModelForm):
        name = forms.CharField(widget=AdminPagedownWidget())
        description = forms.CharField(widget=AdminPagedownWidget())
    
        class Meta:
            model = Album
            fields = "__all__"

    and in your admin.py:

    from django.contrib import admin
    
    from forms import FooModelForm
    from models import FooModel
    
    @admin.register(FooModel)
    class FooModelAdmin(admin.ModelAdmin):
        form = FooModelForm
        fields = "__all__"

Outside the Django Admin:

To use the widget outside of the django admin, first create a form similar to the above but using the basic PagedownWidget:

from django import forms

from pagedown.widgets import PagedownWidget

from music.models import Album


class AlbumForm(forms.ModelForm):
    name = forms.CharField(widget=PagedownWidget())
    description = forms.CharField(widget=PagedownWidget())

    class Meta:
        model = Album
        fields = ["name", "description"]

Then define your urls/views:

from django.views.generic import FormView
from django.conf.urls import patterns, url

from music.forms import AlbumForm

urlpatterns = patterns('',
    url(r'^$', FormView.as_view(template_name="baz.html",
                                form_class=AlbumForm)),)

then create the template and load the javascipt and css required to create the editor:

<html>
    <head>
        {{ form.media }}
    </head>
    <body>
        <form ...>
            {{ form }}
        </form>
    </body>
</html>

Customizing the Widget

If you want to customize the widget, the easiest way is to simply extend it:

from pagedown.widgets import PagedownWidget


class MyNewWidget(PagedownWidget):
    template_name = '/custom/template.html'

    class Media:
        css = {
            'all': ('custom/stylesheets.css',)
        }
        js = ('custom/javascript.js',)

Rendering Markdown

contrib.markdown was deprecated in Django 1.5 meaning you can no longer use the markdown filter in your template by default.

@wkcd has a good example of how to overcome by installing django-markdown-deux:

{% extends 'base.html' %}
{% load markdown_deux_tags %}

...
<p>{{ entry.body|markdown }}</p>
...

Image Uploads

You can enable image uploads, allowing your users to upload new images to the server and have them automatically inserted into the Pagedown widget (instead of just adding image URLs):

Screenshot of Django Admin with image upload enabled

To do so:

  1. Make sure you have set a MEDIA_URL and MEDIA_ROOT so that uploads will be propertly saved
  2. Add PAGEDOWN_IMAGE_UPLOAD_ENABLED=True to your settings
  3. Include the pagedown paths in your urls.py so that the upload endpoint is available
 # ...
 urlpatterns = [
     path('', include('pagedown.urls')),
     # ...
 ]

This will add the URL /pagedown/image-upload/ endpoint to your project. You can see the default view that handles the upload here

The following options are available via your settings to tweak how the image upload works:

  • PAGEDOWN_IMAGE_UPLOAD_PATH can be used to change the path within your media root (default is pagedown-uploads)
  • PAGEDOWN_IMAGE_UPLOAD_EXTENSIONS can be used to limit the extensions allowed for upload (default is jpg, jpeg, png, webp)
  • PAGEDOWN_IMAGE_UPLOAD_UNIQUE can be used to ensure all uploads are stored in a uniquely named subfolder, e.g. f748e009-c3cb-40f3-abf2-d103ab0ad259/my-file.png (default is False)

Check out the pagedown_init.js script to see how the upload is being performed on the client side.

Example

You can see a fully-fledged example of the widget in django-pagedown-example

django-pagedown's People

Contributors

anno1337 avatar brianhicks avatar d3x avatar danirus avatar dnit avatar dureyingenieria avatar eillarra avatar fin avatar flipperpa avatar franksalad avatar igorkf avatar ivanvenosdel avatar jmerdich avatar mbeijen avatar monarchchakri avatar ninjaclasher avatar nkunihiko avatar ondrejsika avatar quantum5 avatar sabberworm avatar schinckel avatar shadytradesman avatar shangdahao avatar sobolevn avatar stefanw avatar timmyomahony 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  avatar  avatar  avatar  avatar  avatar  avatar

django-pagedown's Issues

have way to describe code language?

for example
i insert json fragment to content

i use pygments for code lang detection and colorize.
but code lang mostly undetected if code is short or it's not code like this json data

{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}

secondly if i manually add

[
  {"foo": "bar"}
]

i see pretty colorized json

I do not find it very difficult to arrange backticks, but if there is another solution, please tell me

Uncaught TypeError: Cannot read property 'attachEvent' of null

I installed django-pagedown and followed the instructions for usage outside the Django admin. However, with the given template

<html>
    <head>
        {{ form.media }}
    </head>
    <body>
        <form>
            {{ form }}
        </form>
    </body>
</html>

the pagedown editor does not render. The static files generated by form.media are

<script type="text/javascript" src="/static/pagedown/Markdown.Converter.js"></script>
<script type="text/javascript" src="/static/pagedown-extra/pagedown/Markdown.Converter.js"></script>
<script type="text/javascript" src="/static/pagedown/Markdown.Sanitizer.js"></script>
<script type="text/javascript" src="/static/pagedown/Markdown.Editor.js"></script>
<script type="text/javascript" src="/static/pagedown-extra/Markdown.Extra.js"></script>
<script type="text/javascript" src="/static/pagedown_init.js"></script>

and are reachable. Inspecting via Chrome yiels

Markdown.Editor.js:324 Uncaught TypeError: Cannot read property 'attachEvent' of null

The preview text-areas are rendered correctly. Any suggestions?

Having Trouble Running 'django-pagedown' with Python 3.4

Great app, I just hope I can get it to work. It'd be nice to see all the requirements on the github page, BTW... (Python support?)

I'm running Django 1.9 with Python 3.4. I installed django-pagedown, and started editing a textarea in the Django admin. The preview worked, and showed the rendering correctly. At this time, the result on the web page didn't have the correct rendering.

I then installed django-markdown-deux, and got it to work on the web page. But then, after trying to save the textarea in the Django admin, I got weird error. The field showed some CSS and replaced what was in there. No matter what I put in the field, this same CSS appeared and the field wouldn't validate.

I then uninstalled django-markdown-deux, and now I can't get django-pagedown to work correctly. Not sure if this is a bug or something I'm doing wrong. Any ideas?

Pip install not working

pip install -e git+https://github.com/pastylegs/django_pagedown.git#egg=django-pagedown
fatal: https://github.com/pastylegs/django_pagedown.git/info/refs not found: did you run git update-server-info on the server?

Write some tests

Need some tests for basic rendering. Django has some good examples in their test suits for widgets

Markdown rendering inaccuracy

My clients got confused as the preview rendered headings which were not correctly formatted.

The markdown spec requires a space after the ## but the preview renders them as headings without the space, but on my live pages (rendered through markdown-deux) they appeared as normal paragraphs with hash marks visible.

Is this coming from the javascript dependency?

Widget rendering issue

widgets.py render(...) function has this code:

def render(self, name, value, attrs=None):
    if value is None:
        value = ''
    if 'class' not in attrs:
        attrs['class'] = ""
    attrs['class'] += " wmd-input"
    final_attrs = self.build_attrs(attrs, name=name)
    ...

build_attrs(...) uses python dict.update function, so in this case widget's attrs['class'] value is overwritten with the value you submit to build_attrs(...). After this final_attrs['class'] will always be " wmd-input".

I don't know if this behavior is by design (i.e. you only want one class defined) but it narrows developer's ability to customize the field. For example Django-adminfiles adds "adminfilespicker" class to attrs, it is used to add file manager to the field. As django-pagedown replaces class with it's own, these two apps can't be used together without modification.

I propose changing the code in question to

def render(self, name, value, attrs=None):
    if value is None:
        value = ''
    final_attrs = self.build_attrs(attrs, name=name)
    if 'class' not in final_attrs:
        final_attrs['class'] = ""
    final_attrs['class'] += " wmd-input"

so that all the attrs are preserved.

Django 1.8 Admin Form CSS Conflict

Opening this just to note that I had an issue dropping this into an existing Django 1.8.18 project.

screen shot 2017-10-24 at 2 05 59 pm

See how the first scooby line is really indented in the preview?
Looks like the model admin css is providing markup that is adding padding and margin to <p> elements created by the editor under the form .aligned p selector.

This selector was removed in a later commit - the current version of Django doesn't have it.

Needed JS?

In the README you've mentioned some needed JS files I couldn't find! What are those?

Where do you put the widget customization?

If we would like to customize Pagedown, where in our project do we extend the widget? Which file does the code down below belong?

from pagedown.widgets import PagedownWidget

class MyNewWidget(PagedownWidget):
template_name = '/custom/template.html'

class Media:
    css = {
        'all': ('custom/stylesheets.css,)
    }
    js = ('custom/javascript.js',)

PAGEDOWN_DEFAULT_TEMPLATE not Working

I've set up the constant in my settings.py but template is not loading... Any hints on this?

PAGEDOWN_DEFAULT_TEMPLATE = PROJECT_ROOT + "/templates/pagedown.html"

content = forms.TextField(widget=PagedownWidget()) Doesn't work on Djnago 2.0

# content = forms.TextField(widget=PagedownWidget())

This code doesnt work. why?

from django import forms
from pagedown.widgets import PagedownWidget
from .models import Blog_Post

class PostForm(forms.ModelForm):

# content = forms.TextField(widget=PagedownWidget())
class Meta:
    model=Blog_Post
    fields = [
        "title",
        "image",
        "location",
        "content",
        "draft",          


    ]

Collectstatic pulling in demo project css

I have installed the package as described and want to use my own form.
The form seems to be using the css in demo.css, messing up the colours.
Not sure why. I can delete this file, but when I run collectstatic it returns.

image

Doesn't work with CachedStaticFilesStorage

When I enable CachedStaticFileStorage I get the following error:

ValueError: The file 'admin/css/pagedown.css' could not be found with <django.contrib.staticfiles.storage.CachedStaticFilesStorage object at 0x110410c50>.

Disable it and I'm fine.

Customise form site attributes doesn't seem to work

I tried

  models.TextField: {'widget': AdminPagedownWidget(attrs={'rows':20, 'cols':200,
                                                   'style': ' font-size: 1.2em;'
                                                    })},

but doesn't seem to work (it does for the font but not for the tows and columns. Thanks in advance for your help

Accidentally double-tapping the "save" button when adding an image

Accidentally double-tapping the "save" button when adding an image will trigger the save button for that model. But the new image will not be included in the saved model.

This happens when the admin/support staff is a bit impatient with the image upload and tries to click the "save" button again. Or they simply forgot that they already tapped on the "save" button before.

Steps to reproduce:

  1. Type in random content.
  2. Tap on the add image button.
  3. Upload a huge image (to introduce artificial delays).
  4. Tap on the "save" button.
  5. Immediately tap on the "save" button again.

Expected behavior:

After tapping the "save" button, there should be a loading indicator to let the users know that it is now trying to upload the image.

Space before URL results in malformed URL in markdown

See the screenshot attached to the bug we received. Basically it seems that what is happening is that if you click the globe icon to insert a link and your URL in the field has a space before it (which is hard to see) then the result will have http://%20 prepended to it. That is if you paste https://example.com into the field, then what is inserted into the document is http://%20https://example.com.

Not compatible with dark mode introduced in Django 3.2

As part of the Django 3.2 release, the admin now has a dark theme that is applied based on a prefers-color-scheme media query. Release Notes

The admin now supports theming, and includes a dark theme that is enabled according to browser settings.

This leads to light text on white input field background:

grafik

Additionally, the body background color is set to white by django-pagedown which doesn't interfere with the light theme but looks weird on model admins that have a pagedown widget.

Admin inlines not working

I tried subclassing admin.TabularInline and overriding the formfield but while the Markdown editor appears, none of the buttons work and no preview of the text appears.

Widget attachable to multiple instances of the same form?

Is it possible to have the widget attached to multiple instances of the same form on a page?
When i try i get:

I get: Pagedown editor already attached to element: <#id_text>.

Can the id be specified so it attaches to all instances?
eg. to comments and replies in a thread.
Or do i have to make seperate forms?

load markdown_deux_tags not working in django 1.11

I've followed the instructions given in the doc to render the markdown into my template.
Here's my code

{% include "Home/includes/snippets_navbar.html" %}
{% load markdown_deux_tags %}


{%  block content  %}

<h3>{{post.title}}</h3>
	<h6>{{post.date}}</h6>
	{{post.body|markdown}}
{% endblock %}



And It's not responding at all

Uncaught TypeError: Cannot read property 'init' of undefined

Pagedown is throwing this error in browser.

Uncaught TypeError: Cannot read property 'init' of undefined
 var init = function() {
        that.converter = Markdown.getSanitizingConverter();
        Markdown.Extra.init(that.converter, {      // ERROR HERE
            extensions: "all"
        });
        that.elements = document.getElementsByTagName("textarea");
        that.editors = {};
        for (var i = 0; i < that.elements.length; ++i){
            if ( isPagedownable(that.elements[i]) ) {
                createEditor(that.elements[i]);
            }
        }
    };

Here is the form

class ProposalCommentForm(forms.Form):
    comment = forms.CharField(widget=PagedownWidget(show_preview=True))

form markdown is not rendering when form is used twice

i am trying to use same form twice in the page. the first form is rendering correctly. but the second form is rendering without markdown.

forms.py

class ProposalCommentForm(forms.Form):

    '''
    Used to add comments
    '''
    comment = forms.CharField(widget=PagedownWidget(show_preview=True))

here is the screenshot:

pa

Mobile display issue

Hello.
I get this using my mobile phone.
Is there any fix in the coming release for mobile display?
Thank you.

image

image

Fenced code blocks do not receive pre tag

Suppose I have a database entry where I have the following "code block"

(triple back tick)
some fenced code block
another line
(triple back tick)

I also have the following model method in django models.py

def get_markdown(self):
        return mark_safe(markdown(self.body))

... where body = models.TextField()
Then the result being returned by the method is the following html code...

<p><code>
some fenced code block
another line
</code></p>

The <pre> tag is missing and it also displays inline rather than receiving the line break.

Change django-pagedown preview background

First, thanks for this wonderful Stack-like widget. I'm a good coder, but not good enough to code
an editor like this one. In time.

My problem is when I change .wmd-preview in demo.css, it changes back.
I went in to my static_cdn/pagedown/demo/demo.css and changed the value.
When I reload the page, it says it's;

`.wmd-preview 

{ 
    background-color: #c0e0ff; 
}

but I'm looking at it in sublime and it says;

`.wmd-preview 
{
    background: #000;
}`

I've studied JavaScript and know the syntax, but not well enough to decipher your code.
Help, please.

pagedown

I'd like to end up with something like this,

{ 
    background-color: #000; 
    border-radius: 5px;
    opacity: .6;
    padding: 5px

}

pagedown2

or no background at all.

pagedown3

Thanks in advance Tim.

'default_app_config' is deprecated in Django 3.2.X

Hello, thank you for your project!

After upgrading to Django 3.2, there's a new deprecation warning, related to default_app_config in __init__.py:

  /Users/.../lib/python3.9/site-packages/django/apps/registry.py:91: RemovedInDjango41Warning: 'pagedown' defines default_app_config = 'pagedown.apps.PagedownConfig'. Django now detects this configuration automatically. You can remove default_app_config.
    app_config = AppConfig.create(entry)

Looks like Django will be removing this option in Django 4.1 โ€” ref.

pagedown submodule version

Installing django-pagedown via pip install -e resets the pagedown submodule to an older version which breaks the editor.

The older version (commit d6656cfc6edab8d3dc55fd04478fd1ae4ccac6c9) has:

Markdown.Editor = function (markdownConverter, selectors, idPostfix, help)

while django-pagedown calls:

var editor = new Markdown.Editor(converter, "", selectors);

django-pagedown / pagedown / widgets.py : line 42
(https://github.com/timmyomahony/django-pagedown/blob/master/pagedown/widgets.py#L42)

which is compatible with the newer:

Markdown.Editor = function (markdownConverter, idPostfix, options)

Small problem on the pagedown widget

I think that on line 49 of widgets.py, it should be

            'id': final_attrs['id'],

instead of

            'id': attrs['id'],

since otherwise attrs['id'] could be not defined on (for instance if the render is called with attrs=None, but the init was called with attrs={'id': 'foo'}).

RemovedInDjango110Warning: render() must be called with a dict, not a Context.

.virtualenv/lib/python2.7/site-packages/pagedown/widgets.py:55: RemovedInDjango110Warning: render() must be called with a dict, not a Context.
return template.render(context)

Here's the part with the warning:

   context = Context({
        "attrs": flatatt(final_attrs),
        "body": conditional_escape(force_unicode(value)),
        "id": final_attrs["id"],
        "show_preview": self.show_preview,
    })
    return template.render(context)

https://github.com/timmyomahony/django-pagedown/blob/master/pagedown/widgets.py#L49

I will do a PR with a fix for this issue.

Django admin page raise TypeError

my code like this:
adminform.py:

class ArticleForm(forms.ModelForm):
    body = forms.CharField(widget=AdminPagedownWidget())

    class Meta:
        model = Article
        fields = '__all__'

admin.py:

class ArticlelAdmin(admin.ModelAdmin):
    search_fields = ('body',)
    form = ArticleForm
....others

Django Version:2.1
django-pagedown version:1.0.5
at admin page Django will raise TypeError:

render() got an unexpected keyword argument 'renderer'

Problem with Django v1.11

Hello,

There is some import error when using django-pagedown with the version 1.11 of Django:

File "/usr/lib/python2.7/site-packages/pagedown/widgets.py", line 3, in
from django.forms.widgets import flatatt

ImportError: cannot import name flatatt

Some changes occured in django maybe ?

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.