neutronx / django-markdownx Goto Github PK
View Code? Open in Web Editor NEWComprehensive Markdown plugin built for Django
Home Page: https://neutronx.github.io/django-markdownx/
License: Other
Comprehensive Markdown plugin built for Django
Home Page: https://neutronx.github.io/django-markdownx/
License: Other
Hi,
i'm currently using your package for writing blog posts in markdown. Having set CSRF_COOKIE_HTTPONLY = True
in my settings.py file, the preview and image insertion don't seem to work.
I guess it has to do with the retrieval of the csrftoken in your javascript as this returns empty in this case.
Django 2.0 is removing Python 2.x support, so as we should do...
Hi, I was going through your documentation and after a while I was able to display markdownx fields, but I'm still having issues trying to get the form field to appear and have the markdownx preview effects. Would you be able to add some information around this? I'm currently uses model forms and crispy forms.
Also I'm on sure how to use this markdown preview which may help solve my problem.
<div class="markdownx">
{{ markdownx_editor }}
<div class="markdownx-preview"></div>
</div>
I'm also happy to add what I've learned to your documentation as a few parts confused me, once I get my head all wrapped around it. I'll submit a PR soon.
Is there any way to connect "editor" and "preview" containers separately from the parent?
I've found out that markdownx.js triggers lookup for ".markdownx" container with ".markdownx-preview" and "markdownx-editor".
Is there any way to prevent this and manually setup ".markdownx-preview" and "markdownx-editor" with different parents for both of them?
Markdown URL patterns are not reversible. I suggest to
markdown.urls
MARKDOWNX_*_PATH
settingsI added markdownx/widget.html to my TEMPLATES_DIR but I am still unable to see the changes I have made. However when I make changes to widget.html found in markdownx\templates\markdownx\widget.html that is found in the package, I am able to change it.
This is how my project structure looks like:
I am trying to have the side-by-side panels as shown in the picture on the README.md of this repo. Also, I'm using Django 1.9 and python 3.5.1.
The url of the preview view is changeable because it's retrieved from a data-attribute of the widget, however the url of the image upload view isn't as it is hardcoded in the javascript.
Shall I make a pull-request for this?
Currently the markdown editor widget eats the tab keypress in a way that prevents element focus change. This seems to be intended behaviour as a tab character is inserted.
There should be a way to opt-out of this behaviour and instead use tab for changing the focused element like normally. Right now the only way to opt-out seems to be by overriding the entire javascript file with a modified version of it.
Hi again!
Is there any way to center an image? When I push a new image to my current post, the image is on the left side. Can I center the image? and in the right side?
Thanks in advance!
Hi,
will there be a solution for update views? If I update one article, I get plain HTML Text and this is exhausting for normal users..
Hi!
Is there any way to add images with absolute path? I'm having issues with relative path.
I propose to add a small section to the documentation about markup extensions.
I tracked an issue where preview events were not triggering updates to the preview form that only appeared when I deployed to heroku. It appears that when CSRF_COOKIE_HTTPONLY = True the events will not be able to update the page due to a 403 error.
It would be good that storing the pre-rendered markdown in the db, since content only changes when markup field changed. Why should we render the markdown content over and over?
Is the file upload magic supposed to work in the admin interface?
That would be great but I get:
Internal Server Error: /markdownx/upload/
Traceback (most recent call last):
File "/opt/env/lib/python3.5/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/opt/env/lib/python3.5/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, _callback_args, *_callback_kwargs)
File "/opt/env/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, _args, *_kwargs)
File "/opt/env/lib/python3.5/site-packages/django/views/generic/base.py", line 88, in dispatch
return handler(request, _args, *_kwargs)
File "/opt/env/lib/python3.5/site-packages/django/views/generic/edit.py", line 221, in post
if form.is_valid():
File "/opt/env/lib/python3.5/site-packages/django/forms/forms.py", line 161, in is_valid
return self.is_bound and not self.errors
File "/opt/env/lib/python3.5/site-packages/django/forms/forms.py", line 153, in errors
self.full_clean()
File "/opt/env/lib/python3.5/site-packages/django/forms/forms.py", line 363, in full_clean
self._clean_form()
File "/opt/env/lib/python3.5/site-packages/django/forms/forms.py", line 390, in _clean_form
cleaned_data = self.clean()
File "/opt/env/lib/python3.5/site-packages/markdownx/forms.py", line 45, in clean
upload = self.cleaned_data['image']
KeyError: 'image'
[09/Aug/2016 17:13:23] "POST /markdownx/upload/ HTTP/1.1" 500 14558
I get the following error in the browser console when dragging an image to the editor:
Uncaught TypeError: this.inhibitDefault is not a function
at HTMLTextAreaElement.onDragEnter (markdownx.js:48)
onDragEnter @ markdownx.js:48
markdownx.js:48 Uncaught TypeError: this.inhibitDefault is not a function
at HTMLTextAreaElement.onDragEnter (markdownx.js:48)
onDragEnter @ markdownx.js:48
The image uploads successfully and is displayed in the preview despite of this error.
Actually I'm new to django and Python.
I added the markdownx/widget.html to my TEMPLATES_DIR according to the instruction:
but it didn't make any sense. It could not show as the preview image, and just looked as below:
I've tried to use django debug toolbar, which showed that the widget.html had been rendered:
But I still don't understand where it went wrong...Did I missing something or misunderstood the method to change the custom widget? If so , plz tell me:)
Could any one help me...
Thx!
ps: My Django version is 1.8.8 and the Python version is 3.5.0
on_init()
on_refresh()
I'm using markdownx to render markdown for a blog. Some blog posts contain images such as:
![picture](http://i.imgur.com/xxxx.png)
The images appear when rendering the blog post, but the problem is that I can't control the size of the images. I tried adding the following to the settings.py file as described in the documentation. :
MARKDOWNX_IMAGE_MAX_SIZE = {
'size': (500, 500),
'quality': 90
}
I suspect that this variable only controls the size of images uploaded to the site? Does anyone know how I can control the size of images that are linked in the blog post?
This results in many useless requests (like in the case of formsets).
Well, I know less about front end. I want to change my code block to another color(such as black or grey or something else), which css file should be modified? I could just find the .css in the markdownx/static/markdownx/admin, but the files in this directory seems to change the widget textarea of admin. So, I feel very confused and don't know how to deal with it...
Could anyone help me?
Thanks!
Hello,
I would expect line breaks to be parsed in code blocks.
For example, the markdown
```javascript
var x = 1;
var y = 2;
```
should render, much like it does on Github, as
var x = 1;
var y = 2;
Instead, markdownx renders it as
var x = 1; var y = 2;
Is that intentional or am I missing something?
Thank you for building markdownx!
-- Niko
I'm trying to upload gif but i can't do it.
I put this in settings:
MARKDOWNX_UPLOAD_CONTENT_TYPES = ['image/jpeg', 'image/png', 'image/gif']
How can we make a propperly configuration to upload gif?
I have a problem to develop using this package.
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
field_classes = {'content': MarkdownxFormField,}
widgets = {'content': MarkdowxWidget(attrs={'class':'form-control'})}
So I override your function 'render' and merge attrs and self.attrs and it works.
Also, I think it will handle this problem.
class MarkdownxWidgetImproved(MarkdownxWidget):
def render(self, name, value, attrs=None):
allAttrs = {**attrs, **self.attrs}
return super(MarkdownxWidgetImproved, self).render(name, value, allAttrs)
I request pull, but canceled because I expect that that code doesn't work when attrs is None.
I am using markdownx with django-storages, storing media files in Google storage. Since django-storages
returns an Url that expires after some time when using this storage backend, the media Url that was returned after the file is uploaded will not work to load images after that expiry time has passed.
I suggest using default_storage.url()
when rendering HTML out of markdown. I have created a fork with very naive implementation of this style at aatishnn@9b0585b
What are your views on this? If this is ok, I will be happy to improve on this and send a pull request.
Hi,
I've setup markdownx in the admin, but when writing inline HTML, it gets escaped e.g. <a class="btn-contact">
becomes <a class="btn-contact">
. Is this expected, and is there another way around it?
I'm using django-markdownx==1.3.
Hi, looking at the code it would be easy to add a custom template tag that calls markdownify.
The use case is that when you use a Markdown editor, you'd probably want to show rendered Markdown text somewhere in your app. MArkdownX provides a utils function (markdownify) to convert Markdown to HTML in a view, but not i na template. The benefit of adding this would be that a project using MarkdownX would not require a Markdown renderer such as django-markdown-deux to show the rendered markdown in templates.
Would a PR that implements this be appreciated, or is this project aimed at being a MD editor only?
I'm interested in the ability to drag and drop other files besides images into a markdownx admin field. In my case, it is pdfs in specifically.
So far, I see these things to work on...
![]...
when what we probably want in this case is a linkIf these changes sound like something you might be interested in, I'd be glad to try putting together a PR (although I am rusty at python and new to django).
I see something like this when images are rendered:
Any idea why that's the case? The image itself is presented, but tilted and covering other elements. Why is it presented like this?
I have a standard set-up. In views.py
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
post.text = markdownify(post.text)
return render(request, 'tex/post_detail.html', {'post': post})
and in post_detail.html
<p>{{ post.text | safe }}</p>
Other than that, I simply installed with pip, added to my settings, used as a field, etc.. Nothing fancy and no overrides. I added the image with the standard ![]()
syntax.
When I open a saved model the text is displayed in one line and the markdown format is lost.
Specs:
Python 3.5.2
Django 1.11
Markdownx 2.0.17 (from pypi)
I´m trying to overwrite the widget to get a side-by-side pane.
According to the docs, I need to override widget.html
since I have Django 1.11, although, markdownx is loading widget2.html
When I try to override widget2.html
, Python crashes with the following traceback:
Traceback: https://gist.github.com/busla/41b3bf67178118a7f13b99ff30cf9f58
My template config is fine, it works for other overridden templates without any problem but here is my template config:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'core.context_processors.global_data.global_data',
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
I´ve tried:
myapp/templates/markdownx/widget2.html
myapp/templates/markdownx/widget.html
myproject/templates/markdownx/widget2.html
myproject/templates/markdownx/widget.html
The traceback looks like an infinite recursion and I checked if I was loading widget2.html in multiple places but that was not the case.
Hi, I am new to Django, so please bear with my ineptitude. I am currently building a blog and I want to use the markdown widget in my form for adding posts (not through the admin). I have run through the install instructions in the documentation. The markdown editor and preview work in my admin page, but I am unsure of how I can implement this into a template that has a submission form for posts. Any and all help is greatly appreciated. Again, sorry for being relatively unfamiliar with Django.
Specs:
The uploaded images are never resized. Here is my config:
MARKDOWNX_IMAGE_MAX_SIZE = {
'size': (500, 500),
'quality': 90
}
This markdownx use drag & drop to upload the image. but how i can implement it with html choose image? example:
{% extends 'base.html' %}
{% block content %}
<form role="form" method="POST" action="">{% csrf_token %}
{{ form.as_p }}
<input type="file" class="upload-img" accept="image/*" placeholder="Choose image or drag & drop...">
</form>
{{ form.media }}
<script>
$('.upload-img').on('change', function() {
//what i can do here?
});
</script>
{% endblock %}
Another problem, how i can implement it at django admin page?
Django 1.11 provides template-based widget rendering.
That's good news, because django-markdownx no longer needs to roll its own, but also bad news, because the current implementation breaks.
I made a quick implementation that appears to work on Django 1.11b1 with the following changes.
widget2.html
template next to widget.html
with the following content:<div class="markdownx">
{% include 'django/forms/widgets/textarea.html' %}
<div class="markdownx-preview"></div>
</div>
MarkdownxWidget
with:class MarkdownxWidget(forms.Textarea):
template_name = 'markdownx/widget2.html'
def get_context(self, name, value, attrs=None):
if attrs is None:
attrs = {}
if 'class' in attrs:
attrs['class'] += ' markdownx-editor'
else:
attrs.update({'class': 'markdownx-editor'})
attrs['data-markdownx-editor-resizable'] = MARKDOWNX_EDITOR_RESIZABLE
attrs['data-markdownx-urls-path'] = MARKDOWNX_URLS_PATH
attrs['data-markdownx-upload-urls-path'] = MARKDOWNX_UPLOAD_URLS_PATH
return super(MarkdownxWidget, self).get_context(name, value, attrs)
class Media:
js = (
'markdownx/js/markdownx.js',
)
In order to keep compatibility with earlier version of django, you'll probably want to do something like:
class MarkdownxWidget(forms.Textarea):
if django.VERSION[:2] >= (1, 11):
"""new implementation goes here"""
else:
"""current implementation stays here"""
It's a bit too late here to turn this suggestion into a proper pull request, but I hope this helps anyway!
Having a manage.py
file with testapp settings will help beginners like me. Is there any reason to avoid it ?
Pardon me for being naive.
You can subclass AdminMarkdownxWidget
(for example to change css/js) and use that widget in formfield_overrides
like that:
class CustomMarkdownWidget(AdminMarkdownxWidget):
class Media:
css = {
'all': ('other.css',)
}
js = (
'other.js',
)
class BaseAdmin(admin.ModelAdmin):
formfield_overrides = {
MarkdownxField: {'widget': CustomMarkdownWidget}
}
In that case the new widget won't be used. Instead the widget will be overwritten with markdownx.widgets.MarkdownxWidget
. This happens because in markdownx\fields.py
theMarkdownxFormField
is checking if class of current widget is != AdminMarkdownxWidget
. If the condition is true it overrides the widget with MarkdownxWidget
(the non-admin one):
class MarkdownxFormField(forms.CharField):
def __init__(self, *args, **kwargs):
super(MarkdownxFormField, self).__init__(*args, **kwargs)
if self.widget.__class__ != AdminMarkdownxWidget:
self.widget = MarkdownxWidget()
It should check if self.widget.class is not subclass of MarkdownxWidget instead of the !=
comparison.
Hi,
first of all: Thank you very much for this great django package! I was desperately searching for a decent editor and this just blew all of my expectations out of the water!
Is it possible to aviod that gap i.e. to extend the editor's width?
I'm using this very basic template from the readme, basically the editor should just be as wide as the
<div class="markdownx row">
<div class="col-md-6">
{{ markdownx_editor }}
</div>
<div class="col-md-6">
<div class="markdownx-preview"></div>
</div>
</div>
~
I'm using MarkdownxFormField()
within a ModelForm.
On a sidenote: The editor is not resizeable at all (i.e. by drag the frame). Is that an issue on my side?
Hi, I followed the docs and I created a new BASE_DIR/templates/markdownx/widget2.html file with the following:
<div class="markdownx row">
<div class="col-md-6">
{{ markdownx_editor }}
</div>
<div class="col-md-6">
<div class="markdownx-preview"></div>
</div>
</div>
Nothing happen when I visit my page, I don't see the new class added.
The form is defined in forms.py as follow:
class ForumThreadForm(forms.Form):
content = MarkdownxFormField()
and in the views.py I have:
def forum_new_thread(request):
form = ForumThreadForm()
context = {'form': form}
return render(request, 'forum/new_thread.html', context)
My settings.py is:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'frontend.custom_context.track_seen_today',
'frontend.custom_context.track_seen_always',
'frontend.custom_context.user_avatar',
],
},
},
]
What am I doing wrong? Thanks!
Hello, can you help me ? 😄
I don`t know how to show my markdown data on template.
I have something like
<h1>{{ post.title }}</h1>
<p>{{ post.text }}</p>
<p>{{ post.markdown }}</p>
and i see only
title
text
#text1 ![](/media/markdownx/ab3bfac7-7509-411a-96c8-11aebc20b873.jpg)
but i want compiled version (with image)
Could you explain how templates with markdownx work ? Or create some exaple with that ? 😄
Class Model1(models.Model):
content = MarkdownxField(u"Content")
@admin.register(Model1)
class Model1Admin(admin.ModelAdmin):
formfield_overrides = {
models.TextField: {'widget': AdminMarkdownxWidget}
}
Got TypeError
:
build_attrs() got an unexpected keyword argument 'name'
in widgets.py line 15
PIL is a very old and problematic module. I think this project must use pillow instead of PIL.
How can i use a remote image (as imgur...)
pip installation of the latest markdownx package raises exception below when I try to upload an image.
Internal Server Error: /markdownx/upload/
Traceback (most recent call last):
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
response = self._get_response(request)
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/views/generic/base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/views/generic/edit.py", line 182, in post
if form.is_valid():
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/forms/forms.py", line 183, in is_valid
return self.is_bound and not self.errors
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/forms/forms.py", line 175, in errors
self.full_clean()
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/forms/forms.py", line 385, in full_clean
self._clean_form()
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/django/forms/forms.py", line 412, in _clean_form
cleaned_data = self.clean()
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/markdownx/forms.py", line 183, in clean
and has_javascript(upload.read())):
File "/Users/ksanderer/.pyenv/versions/django_boiler/lib/python3.5/site-packages/markdownx/utils.py", line 131, in has_javascript
flags=IGNORECASE | MULTILINE
File "/Users/ksanderer/.pyenv/versions/3.5.1/lib/python3.5/re.py", line 173, in search
return _compile(pattern, flags).search(string)
TypeError: cannot use a string pattern on a bytes-like object
You can see that "has_javascript" executes in this piece of code:
# markdownx/forms.py (line: 183)
if content_type not in MARKDOWNX_UPLOAD_CONTENT_TYPES:
raise MarkdownxImageUploadError.unsupported_format()
elif file_size > MARKDOWNX_UPLOAD_MAX_SIZE:
raise MarkdownxImageUploadError.invalid_size(
current=file_size,
expected=MARKDOWNX_UPLOAD_MAX_SIZE
)
elif (content_type.lower() != self._SVG_TYPE
and MARKDOWNX_SVG_JAVASCRIPT_PROTECTION
and has_javascript(upload.read())):
When we trying to upload JPEG file the last "elif" always will fire with "has_javascript" check.
Shouldn't it be content_type.lower() == self._SVG_TYPE
?
I'd propose a new settings witch holds the path to the markdownify definition:
# Markdownify
MARKDOWNX_FUNCTION = getattr(settings, 'MARKDOWNX_FUNCTION', 'markdownx.utils.markdownify_default')
In utils.py you'd then have:
def markdownify_default(content):
return markdown.markdown(
content,
extensions=MARKDOWNX_MARKDOWN_EXTENSIONS,
extension_configs=MARKDOWNX_MARKDOWN_EXTENSION_CONFIGS)
And the post definition of MarkdownifyView will load request.POST['content'] into that function.
The idea is that you now have an option to keep the code DRY, because you can refer to the exact same markdownify function (e.g. for database caching of the rendered html).
Installed markdownx version is 1.2. Python version is 3.4.0, project is in virtualenv.
drag'n'drop image from local folder shows 500 error on request to server in developer console:
TypeError at /markdownx/upload/
string argument expected, got 'bytes'
Request Method: POST
Request URL: http://localhost:8000/markdownx/upload/
Django Version: 1.8.5
Python Executable: /home/kraplax/noslack/bin/python3
Python Version: 3.4.0
Python Path: ['/home/kraplax/noslack/src', '/home/kraplax/noslack/lib/python3.4', '/home/kraplax/noslack/lib/python3.4/plat-i386-linux-gnu', '/home/kraplax/noslack/lib/python3.4/lib-dynload', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-i386-linux-gnu', '/home/kraplax/noslack/lib/python3.4/site-packages']
Server time: Sat, 17 Oct 2015 22:59:28 +0000
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'time_sections',
'account',
'markdownx',
'ublog',
'pinax_theme_bootstrap',
'bootstrapform')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'account.middleware.LocaleMiddleware',
'account.middleware.TimezoneMiddleware')
Traceback:
File "/home/kraplax/noslack/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/kraplax/noslack/lib/python3.4/site-packages/django/views/generic/base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "/home/kraplax/noslack/lib/python3.4/site-packages/django/views/generic/base.py" in dispatch
89. return handler(request, *args, **kwargs)
File "/home/kraplax/noslack/lib/python3.4/site-packages/django/views/generic/edit.py" in post
215. return self.form_valid(form)
File "/home/kraplax/noslack/lib/python3.4/site-packages/markdownx/views.py" in form_valid
30. image_path = form.save()
File "/home/kraplax/noslack/lib/python3.4/site-packages/markdownx/forms.py" in save
28. img.save(thumb_io, self.files['image'].content_type.split('/')[-1].upper())
File "/home/kraplax/noslack/lib/python3.4/site-packages/PIL/Image.py" in save
1665. save_handler(self, fp, filename)
File "/home/kraplax/noslack/lib/python3.4/site-packages/PIL/PngImagePlugin.py" in _save
690. fp.write(_MAGIC)
Exception Type: TypeError at /markdownx/upload/
Exception Value: string argument expected, got 'bytes'
Request information:
GET: No GET data
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.