Giter Site home page Giter Site logo

mgaitan / waliki Goto Github PK

View Code? Open in Web Editor NEW
308.0 12.0 56.0 1.66 MB

A wiki engine powered by Django and Git

Home Page: http://waliki.pythonanywhere.com

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

Makefile 0.38% Python 57.62% HTML 17.05% CSS 8.87% JavaScript 15.00% XSLT 1.08%
django wiki-engine git markdown restructuredtext

waliki's Introduction

Waliki is an extensible wiki app for Django with a Git backend.

Attention

It's in an early development stage. I'll appreciate your feedback and help.

image

image

image

Documentation Status

Wheel Status

home

https://github.com/mgaitan/waliki/

demo

http://waliki.pythonanywhere.com

documentation

http://waliki.rtfd.org

twitter

@Waliki_ // @tin_nqn_

group

https://groups.google.com/forum/#!forum/waliki-devs

license

BSD

At a glance, Waliki has these features:

  • File based content storage.
  • UI based on Bootstrap and CodeMirror
  • Version control and concurrent edition for your content using git
  • An extensible architecture through plugins
  • reStructuredText or Markdown support, configurable per page (and it's easy to add extensions)
  • A very simple per slug ACL system
  • A nice attachments manager (that respects the permissions over the page)
  • Realtime collaborative edition via togetherJS
  • Wiki content embeddable in any django template (as a "dummy CMS")
  • Few helpers to migrate content (particularly from MoinMoin, using moin2git)
  • It works with Python 2.7, 3.4 or PyPy in Django 1.8, 1.9 (and 1.10, most probably)

It's easy to create a site powered by Waliki using the preconfigured project which is the same code that motorize the demo.

Waliki was inspired in Github's wikis, but it tries to be a bit smarter than many others git backed wiki engines at handling changes: instead of a hard "newer wins" or "page blocking" approaches, Waliki uses git's merge facilities on each save. So, if there was another change during an edition and git can merge them automatically, it's done and the user is notified. If the merge fails, the last edition is still saved but the editor is reloaded asking the user to fix the conflict.

Getting started

Install it with pip:

$ pip install waliki[all]

Or the development version:

$ pip install https://github.com/mgaitan/waliki/tarball/master

Add waliki and the optionals plugins to your INSTALLED_APPS:

INSTALLED_APPS = (
    ...
    'waliki',
    'waliki.git',           # optional but recommended
    'waliki.attachments',   # optional but recommended
    'waliki.pdf',           # optional
    'waliki.search',        # optional, additional configuration required
    'waliki.slides',        # optional
    'waliki.togetherjs',    # optional
    ...
)

Include waliki.urls in your project's urls.py. For example:

urlpatterns = patterns('',
    ...
    url(r'^wiki/', include('waliki.urls')),
    ...
)

Sync your database:

$ python manage.py migrate

Tip

Do you already have some content? Put it in your WALIKI_DATA_DIR (or set it to the actual path) and run:

$ python manage.py sync_waliki

Do you want everybody be able to edit your wiki? Set:

WALIKI_ANONYMOUS_USER_PERMISSIONS = ('view_page', 'add_page', 'change_page')

in your project's settings.

Contribute

This project is looking for contributors. If you have a feature you'd like to see implemented or a bug you'd liked fixed, the best and fastest way to make that happen is to implement it and submit it back upstream for consideration. All contributions will be given thorough consideration.

Everyone interacting in the Waliki project's codebases, issue trackers and mailing lists is expected to follow the PyPA Code of Conduct.

Why Waliki ?

Waliki is an Aymara word that means all right, fine. It sounds a bit like wiki, has a meaningful sense and also plays with the idea of using a non-mainstream language1 .

And last but most important, it's a humble tribute to the president Evo Morales and the Bolivian people.


  1. wiki itself is a hawaiian word

waliki's People

Contributors

aszepieniec avatar chuna avatar dmascialino avatar fpytloun avatar gilgamezh avatar gkadillak avatar goggin avatar humitos avatar loganchien avatar luzik avatar martenson avatar mgaitan avatar movermeyer avatar ostrokach avatar pardo avatar ralsina avatar santiavenda2 avatar wagnerflo 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

waliki's Issues

templatetag to render content of a page

{% render_page_content "slug" %}

or

{% render_page_content page.slug %}

In this way, we could use waliki as a very simple CMS.

from django.conf.urls import patterns, url
from django.views.generic.base import TemplateView

urlpatterns = patterns('',
    url(r'^home/$', TemplateView.as_view(template_name='home.html')),
)

this template could have many {% render_page_content page.slug %}

<div id="welcome">
   {% render_page_content "welcome" %}
</div>
<div id="news">
   {% render_page_content "news" %}
</div>

Long wait when running tests

When I run:

python runtests.py

I get this output:

/home/humitos/.virtualenvs/waliki/local/lib/python2.7/site-packages/django/test/_doctest.py:59: RemovedInDjango18Warning: The django.test._doctest module is deprecated; use the doctest module from the Python standard library instead.
  RemovedInDjango18Warning)

/home/humitos/.virtualenvs/waliki/local/lib/python2.7/site-packages/django/test/simple.py:27: RemovedInDjango18Warning: The django.test.simple module and DjangoTestSuiteRunner are deprecated; use django.test.runner.DiscoverRunner instead.
  RemovedInDjango18Warning)

nosetests tests -s --nologcapture --nocapture --with-id --logging-clear-handlers --verbosity=1
Creating test database for alias 'default'...
................



^CE^C
======================================================================
ERROR: test_commit_existent_page_with_no_previous_commits (tests.test_git.TestGit)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/humitos/Source/waliki/tests/test_git.py", line 37, in test_commit_existent_page_with_no_previous_commits
    self.assertIn("testing :)", git.log('-s', '--format=%s', self.page.path))
  File "/home/humitos/.virtualenvs/waliki/local/lib/python2.7/site-packages/sh.py", line 769, in __call__
    return RunningCommand(cmd, call_args, stdin, stdout, stderr)
  File "/home/humitos/.virtualenvs/waliki/local/lib/python2.7/site-packages/sh.py", line 330, in __init__
    self.wait()
  File "/home/humitos/.virtualenvs/waliki/local/lib/python2.7/site-packages/sh.py", line 334, in wait
    self._handle_exit_code(self.process.wait())
  File "/home/humitos/.virtualenvs/waliki/local/lib/python2.7/site-packages/sh.py", line 1152, in wait
    pid, exit_code = os.waitpid(self.pid, 0)
OSError: [Errno 4] Interrupted system call

----------------------------------------------------------------------
Ran 18 tests in 59.265s

FAILED (errors=1)
Destroying test database for alias 'default'...

I have to cancel it with Control+C (twice) because it never returns the bash.

$ git --version
git version 1.9.1

Move page view

This view should allow to change the slug and/or path (and file extension) associated to a page. A signal is sent with sensitive data and a Git receiver should listen to it to run a git mv
#2 depends on this.

Document cache feature

waliki pages are cached via the standard django cache system. Tell it in the docs and give some clues to config it

Delete page view

Implement a view to delete a page. When the page instance is delete, the associated file is also removed.
Git should capture the signal and run git rm

Only accept POST and need a confirmation dialog wherever it is used

captura de pantalla de 2014-10-02 10 10 38

Raw content view

add a builtin view that return the raw content of a page, with a proper mime/contentype set in the response.
the url pattern should be <page_slug>/raw

In addition, the page in an specific version could be viewble as raw: <page_slug>/version/<version>/raw

(the response shouldn't be as attachment . i.e. no "download" dialog).

Plugin "rest API"

A simple REST API to pages.

Basically, handle these endpoints:

  • retrieve a page: title, raw content
  • retrieve a page rendered
  • create or update a new page (title / raw content / log message)
  • append content to a page. Analog to the previous, but append the new content instead to replace it.

Redirections should apply to any view with slug

currently only detail handle redirections, prepending a code like this

    # handle redirects first
    try:
        redirect = Redirect.objects.get(old_slug=slug)      # noqa
        if redirect.status_code == 302:
            return HttpResponseRedirect(redirect.get_absolute_url())
        return HttpResponsePermanentRedirect(redirect.get_absolute_url())
    except Redirect.DoesNotExist:
        pass

this should be a decorator applied to every view based on the "slug" pattern.

So, for example, if there is a redirection from 'slug' to 'new-slug', any of this should work:

  • ../slug/raw -> ../new-slug/raw
  • ../slug/edit -> `../new-slug/edit
  • ../slug/version/X -> ../new-slug/version/X

and so on

Change action buttons

When the user is in "Edit Page" view, the "Edit" button and the dropdown with option shouldn't appear. Instead, we should show these two buttons:

  • Move (depends on #6)
  • History: this link should check if the user has modified the content of the page and in this case show an alert (or modal) to inform that he will loose these changes if the page is not saved before.

page history crash if message log break json

For example, a message containing a quotes or comma. It need at least escaping or a simpler parsing.

Environment:


Request Method: GET
Request URL: http://localhost:8000/home/history

Django Version: 1.7
Python Version: 3.4.2
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sites',
 'waliki_project',
 'waliki',
 'waliki.git',
 'waliki.pdf',
 'waliki.slides',
 'waliki.attachments',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'allauth.socialaccount.providers.github',
 'allauth.socialaccount.providers.twitter')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/home/tin/.virtualenvs/waliki/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/tin/lab/waliki/waliki/acl.py" in _wrapped_view
  63.                 return view_func(request, *args, **kwargs)
File "/home/tin/lab/waliki/waliki/git/views.py" in history
  22.     history = Git().history(page)
File "/home/tin/lab/waliki/waliki/git/__init__.py" in history
  82.                 history.append(json.loads(line))
File "/usr/lib/python3.4/json/__init__.py" in loads
  318.         return _default_decoder.decode(s)
File "/usr/lib/python3.4/json/decoder.py" in decode
  343.         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.4/json/decoder.py" in raw_decode
  359.             obj, end = self.scan_once(s, idx)

Exception Type: ValueError at /home/history
Exception Value: Expecting ',' delimiter: line 1 column 147 (char 146)

Add some techniques to prevent spam

It seems that the edition form is vulnerable to spam bots

captura de pantalla de 2015-03-18 09 40 56

add a honeypot (hidden field) with a value filled via javascript or any other antispam technique

can't view diffs on LMDE

Trying to view the diffs from a page's history causes a server error:

Exception Type: UnicodeDecodeError
Exception Value: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)
Exception Location: /usr/local/lib/python2.7/dist-packages/waliki/git/views.py in diff, line 56
Traceback:

File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/waliki/acl.py" in _wrapped_view
  63.                 return view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/waliki/git/views.py" in diff
  56.     old_content = Git().version(page, old).replace('\t', '    ').replace(' ', '\xA0')

I am running python 2.7.

Error when save a page after change the markup

I went to an existent page and change the markup. Then click save:

repo status

(waliki)17:03 ~/waliki_data (master)$ git status
# HEAD detached at b810a1e
# Unmerged paths:
# (use "git reset HEAD <file>..." to unstage)
# (use "git add <file>..." to mark resolution)
#
# both modified: test.rst
#
no changes added to commit (use "git add" and/or "git commit -a")
(waliki)17:05 ~/waliki_data ((detached from b810a1e))$ 

traceback

Environment:


Request Method: POST
Request URL: https://waliki.pythonanywhere.com/page/edit

Django Version: 1.7
Python Version: 3.3.2
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sites',
 'waliki',
 'waliki.git',
 'waliki.pdf',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'allauth.socialaccount.providers.github',
 'allauth.socialaccount.providers.twitter')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/home/waliki/.virtualenvs/waliki/lib/python3.3/site-packages/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/waliki/waliki/waliki/decorators.py" in _wrapped_view
  57.                 return view_func(request, *args, **kwargs)
File "/home/waliki/waliki/waliki/views.py" in edit
  54.                                                   form_extra_data=json.loads(form.cleaned_data["extra_data"] or "{}"))
File "/home/waliki/.virtualenvs/waliki/lib/python3.3/site-packages/django/dispatch/dispatcher.py" in send
  198.             response = receiver(signal=self, sender=sender, **named)
File "/home/waliki/waliki/waliki/git/models.py" in commit
  11.                                            parent=parent)
File "/home/waliki/waliki/waliki/git/__init__.py" in commit
  53.             git.commit(path, allow_empty_message=True, m=message, **kwargs)
File "/home/waliki/.virtualenvs/waliki/lib/python3.3/site-packages/sh.py" in __call__
  769.         return RunningCommand(cmd, call_args, stdin, stdout, stderr)
File "/home/waliki/.virtualenvs/waliki/lib/python3.3/site-packages/sh.py" in __init__
  330.                 self.wait()
File "/home/waliki/.virtualenvs/waliki/lib/python3.3/site-packages/sh.py" in wait
  334.         self._handle_exit_code(self.process.wait())
File "/home/waliki/.virtualenvs/waliki/lib/python3.3/site-packages/sh.py" in _handle_exit_code
  348.                 self.process.stderr

Exception Type: ErrorReturnCode_1 at /page/edit
Exception Value: 

  RAN: '/usr/bin/git --no-pager commit page.rst --author=Martín Gaitán <> -m  --allow-empty-message'

  STDOUT:
test.rst: needs merge
# �[31mHEAD detached at �[m17f9003
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   �[31mmodified:   test.rst�[m
#
no changes added to commit (use "git add" and/or "git commit -a")


  STDERR:

add RSS support

  • Global: 'what changed' in the wiki
  • Under a namespace: everything under /any-slug
  • Page only: analog to git log -p -- page.path

track scragg0x/realms-wiki#11 to see how they implement this.

Error when saving a page without editing it

The workflow:

  1. Create a new page
  2. Write some content
  3. Click on "Edit" this new page
  4. Do not change anything
  5. Click "Save"

This error occurs:

ErrorReturnCode_1 at /hola/edit
no se ha agregado nada al commit pero existen archivos sin seguimiento

Implement a cache for rendered content

At this moment, a page is rendered (twice, if there is implicit links to handle) on each request. We should cache it (via django cache framework) during a configurable amount of time (default to 12h ?)
and invalidate it only when the content change.

see django-wiki's implementation

Add user's link on project's navbar

on the right side of the navbar

  • Signup & Login if the user isn't authenticated.
  • A dropdown menu with 'Logout' if it is authenticated

currently there is this legacy jinja2 code commented in base.html


                            {% comment %}

                            <ul class="nav pull-right navbar-nav">
                                {% if current_user.is_anonymous() %}
                                    <li><a href="{{ url_for('user_login') }}">Login</a></li>
                                    <li><a href="{{ url_for('user_signup') }}">Signup</a></li>

                                {% else %}
                                    <li><a href="{{ url_for('user_logout') }}">Logout</a></li>
                                {% endif %}
                            </ul>
                            {% endcomment %}

Plugin attachments

a plugin that allow to attach files to pages.

the upload_to folder must have a pattern based on the slug (i.e : path.join(base_media_dir, slug, filename)) in order to facilitate the sync when migrating a wiki from other system or even for "out of the web" use case.

Check the original Waliki for details and useful code

captura de pantalla de 2014-10-02 10 02 33

Webhook to pull changes from a remote

A great thing to do with a git backend wiki is to edit it in your favourite editor (outside the browser) and then push it.

Add a view that receive a POST and trigger

  1. git pull
  2. waliki sync_command (need a refactor?).

So the flow will be like this:

  1. set a way that git send a post to our url ( for example as github webhook or directly from your local, via a git hook )
  2. commit changes
  3. the hook post to the url, that pull (fetch and merge) the remote changes and sync for new/deleted pages.

waliki_box fails with missing slug

Environment:


Request Method: GET
Request URL: http://beta.python.org.ar/lista/

Django Version: 1.7.1
Python Version: 3.3.6
Installed Applications:
('django.contrib.admin',
 'django.contrib.sites',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'community',
 'news',
 'pycompanies',
 'jobs',
 'events',
 'newbie',
 'projects',
 'faq',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'django_extensions',
 'disqus',
 'taggit',
 'taggit_autosuggest',
 'bootstrap3_datetime',
 'planet',
 'pagination',
 'tagging',
 'bootstrap3',
 'django_summernote',
 'sendfile',
 'crispy_forms',
 'email_obfuscator',
 'waliki',
 'waliki.git',
 'waliki.attachments')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.gzip.GZipMiddleware',
 'pagination.middleware.PaginationMiddleware')


Template error:
In template /home/www-pyar/pyarweb_beta/pyarweb_venv/src/waliki/waliki/templates/waliki/box.html, error at line 32
   Reverse for 'waliki_detail' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['wiki/(?P<slug>[a-zA-Z0-9-_\\/]+)$']
   22 :             </form>


   23 :             </div><!-- /.modal-content -->


   24 :           </div><!-- /.modal-dialog -->


   25 :         </div><!-- /.modal -->


   26 : {% endif %}


   27 : 


   28 : <div id="content_{{ label }}" class="content-box {% if form %}editable{% endif %}">


   29 :     {% if form %}


   30 :         <button type="button" data-toggle="modal" data-target="#edit_{{ label }}" class="btn btn-default" title="{% trans 'Edit this content' %}"><span class="glyphicon glyphicon-pencil"></span></button>


   31 :     {% endif %}


   32 :      {{ page.body|safe }} 


   33 : </div>

Traceback:
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/www-pyar/pyarweb_beta/pyarweb/pyarweb/views.py" in special_page
  19.     return render(request, 'special_page.html', kwargs)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/shortcuts.py" in render
  48.     return HttpResponse(loader.render_to_string(*args, **kwargs),
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/loader.py" in render_to_string
  178.         return t.render(context_instance)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in render
  148.             return self._render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in _render
  142.         return self.nodelist.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/loader_tags.py" in render
  126.         return compiled_parent._render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in _render
  142.         return self.nodelist.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/loader_tags.py" in render
  126.         return compiled_parent._render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in _render
  142.         return self.nodelist.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in render
  1231.                     return self.nodelist.render(new_context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/debug.py" in render
  90.             output = self.filter_expression.resolve(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in resolve
  596.                 obj = self.var.resolve(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in resolve
  734.             value = self._resolve_lookup(context)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/template/base.py" in _resolve_lookup
  770.                         current = getattr(current, bit)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/src/waliki/waliki/models.py" in body
  133.         return self.get_cached_content()
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/src/waliki/waliki/models.py" in get_cached_content
  152.             cached_content = self._get_part('get_document_body')
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/src/waliki/waliki/models.py" in _get_part
  127.             return getattr(self.markup_, part)(self.raw)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/src/waliki/waliki/_markups.py" in get_document_body
  91.                              for ref in refs)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/src/waliki/waliki/_markups.py" in <genexpr>
  91.                              for ref in refs)
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/src/waliki/waliki/utils.py" in get_url
  32.     return reverse('waliki_detail', args=(get_slug(text),))
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/core/urlresolvers.py" in reverse
  551.     return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "/home/www-pyar/pyarweb_beta/pyarweb_venv/lib/python3.3/site-packages/django/core/urlresolvers.py" in _reverse_with_prefix
  468.                              (lookup_view_s, args, kwargs, len(patterns), patterns))

Exception Type: NoReverseMatch at /lista/
Exception Value: Reverse for 'waliki_detail' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['wiki/(?P<slug>[a-zA-Z0-9-_\\/]+)$']

Wording para "empresas" es inconsistente

En muchos lados aparece la palabra "compania" que no existe. Lo correcto sería "compañía", pero más general y común es "empresa" .

Además, el namespace deberia ser /empresas y no /companies

Pandoc to convert content markup

When a page change its markup, not only the file extension should change but (optionally) the content should be converted to the new markup.

Pandoc could do it, at least beetween rst and markdown.

Implement a plugin that capture a signal when change the markup (page_move?) and ask for update the content.

Create New Page

We need a link in the navbar "Create New Page" that shows a modal with two inputs:

  • Title
  • Slug (autocompleted from title)

After the user accepts this modal, he/she is redirected to the "Edit Page" with the title pre-loaded.

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.