Browse Source

Add parent/child relations to pages

JoostSijm 6 years ago
parent
commit
52cf4951fc

+ 16 - 10
app/models.py

@@ -11,17 +11,10 @@ from flask_login import UserMixin
 from app import db, argon2, login_manager
 
 
-class Base():
-    """Base class for models"""
-    id = db.Column(db.Integer, primary_key=True)
-
-    def __repr__(self):
-        return "<%s(%s)>" % (type(self).__name__, self.id)
-
-
-class User(Base, db.Model, UserMixin):
+class User(db.Model, UserMixin):
     """Model for User"""
 
+    id = db.Column(db.Integer, primary_key=True)
     name = db.Column(db.String, unique=True, nullable=False)
     email = db.Column(db.String(255), unique=True)
     _password = db.Column("password", db.String(255))
@@ -49,13 +42,15 @@ class User(Base, db.Model, UserMixin):
         return argon2.check_password_hash(self.password, password)
 
 
-class Page(Base, db.Model):
+class Page(db.Model):
     """Model for Page"""
 
+    id = db.Column(db.Integer, primary_key=True)
     title = db.Column(db.String, nullable=False)
     datetime = db.Column(db.DateTime, default=datetime.utcnow)
     source = db.Column(db.String)
 
+
     def content(self):
         """Render page source"""
         return Markup(markdown.markdown(self.source))
@@ -68,3 +63,14 @@ class Page(Base, db.Model):
         "User",
         backref=db.backref("Pages", lazy="dynamic")
     )
+
+    parent_id = db.Column(
+        db.Integer,
+        db.ForeignKey("page.id")
+    )
+    parent = db.relationship(
+        "Page",
+        backref=db.backref("children", lazy="dynamic"),
+        uselist=False,
+        remote_side=id
+    )

+ 11 - 3
app/modules/backend/app.py

@@ -101,7 +101,7 @@ def logout():
 @login_required
 def index():
     """Show homepage"""
-    pages = Page.query.all()
+    pages = Page.query.filter(Page.parent_id == None).all()
     return render_template('site/index.j2', pages=pages)
 
 
@@ -110,18 +110,20 @@ def index():
 @login_required
 def create_page():
     """Page creating"""
+    pages = Page.query.all()
     if request.method == 'POST':
         page = Page()
         page.title = request.form['title']
         page.source = request.form['source']
         page.user_id = current_user.id
+        page.parent_id = request.form['parent_id'] if request.form['parent_id'] else None
 
         db.session.add(page)
         db.session.commit()
 
         flash('Page "%s" successfully created' % page.title, 'success')
 
-    return render_template('page/create.j2')
+    return render_template('page/create.j2', pages=pages)
 
 
 @BLUEPRINT.route('/page/edit/<int:page_id>', methods=["GET", "POST"])
@@ -129,10 +131,12 @@ def create_page():
 def edit_page(page_id):
     """Page editing"""
     page = Page.query.get(page_id)
+    pages = Page.query.filter(Page.id != page.id).all()
 
     if request.method == 'POST':
         page.title = request.form['title']
         page.source = request.form['source']
+        page.parent_id = request.form['parent_id'] if request.form['parent_id'] else None
         page.user_id = current_user.id
 
         db.session.add(page)
@@ -140,7 +144,11 @@ def edit_page(page_id):
 
         flash('Page "%s" successfully edit' % page.title, 'success')
 
-    return render_template('page/edit.j2', page=page)
+    return render_template(
+        'page/edit.j2',
+        page=page,
+        pages=pages
+    )
 
 
 @BLUEPRINT.route('/page/view/<int:page_id>')

+ 18 - 7
app/templates/page/create.j2

@@ -17,13 +17,15 @@
 	{% endfor %}
 	{% endif %}
 	{% endwith %}
-	{%- for item in current_menu.children recursive -%}
-	<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ item.text }}">
-	    <a class="nav-link" href="{{ item.url}}">
-	        <span class="nav-link-text">{{ item.text }}</span>
-	    </a>
-	</li>
-	{%- endfor -%}
+	<ul>
+		{%- for item in current_menu.children recursive -%}
+		<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ item.text }}">
+		    <a class="nav-link" href="{{ item.url}}">
+		        <span class="nav-link-text">{{ item.text }}</span>
+		    </a>
+		</li>
+		{%- endfor -%}
+	</ul>
 	<h1>Page create</h1>
 	<form method="post">
 		<div class="form-group">
@@ -34,6 +36,15 @@
 			<label class="text-normal text-dark">Source</label>
 			<textarea class="form-control" name="source"></textarea>
 		</div>
+		<div class="form-group">
+			<label class="text-normal text-dark">Parent</label>
+			<select class="form-control" name="parent_id">
+				<option></option>
+				{% for page in pages %}
+				<option value="{{ page.id }}">{{ page.title }}</option>
+				{% endfor %}
+			</select>
+		</div>
 		<div class="form-group pull-right">
 			<button class="btn btn-primary">Create</button>
 		</div>

+ 22 - 7
app/templates/page/edit.j2

@@ -17,13 +17,15 @@
 	{% endfor %}
 	{% endif %}
 	{% endwith %}
-	{%- for item in current_menu.children recursive -%}
-	<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ item.text }}">
-	    <a class="nav-link" href="{{ item.url}}">
-	        <span class="nav-link-text">{{ item.text }}</span>
-	    </a>
-	</li>
-	{%- endfor -%}
+	<ul>
+		{%- for item in current_menu.children recursive -%}
+		<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ item.text }}">
+		    <a class="nav-link" href="{{ item.url}}">
+		        <span class="nav-link-text">{{ item.text }}</span>
+		    </a>
+		</li>
+		{%- endfor -%}
+	</ul>
 	<h1>Edit: {{ page.title }}</h1>
 	<form method="post">
 		<div class="form-group">
@@ -34,6 +36,19 @@
 			<label class="text-normal text-dark">Source</label>
 			<textarea class="form-control" name="source">{{ page.source }}</textarea>
 		</div>
+		<div class="form-group">
+			<label class="text-normal text-dark">Parent</label>
+			<select class="form-control" name="parent_id">
+				<option></option>
+				{% for parent_page in pages %}
+				{% if parent_page.id == page.parent_id %}
+				<option value="{{ parent_page.id }}" selected>{{ parent_page.title }}</option>
+				{% else %}
+				<option value="{{ parent_page.id }}">{{ parent_page.title }}</option>
+				{% endif %}
+				{% endfor %}
+			</select>
+		</div>
 		<div class="form-group pull-right">
 			<button class="btn btn-primary">Save</button>
 		</div>

+ 9 - 7
app/templates/page/view.j2

@@ -17,13 +17,15 @@
 	{% endfor %}
 	{% endif %}
 	{% endwith %}
-	{%- for item in current_menu.children recursive -%}
-	<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ item.text }}">
-	    <a class="nav-link" href="{{ item.url}}">
-	        <span class="nav-link-text">{{ item.text }}</span>
-	    </a>
-	</li>
-	{%- endfor -%}
+	<ul>
+		{%- for item in current_menu.children recursive -%}
+		<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ item.text }}">
+		    <a class="nav-link" href="{{ item.url}}">
+		        <span class="nav-link-text">{{ item.text }}</span>
+		    </a>
+		</li>
+		{%- endfor -%}
+	</ul>
 	<h1>Title: {{ page.title }}</h1>
 	<a href="{{ url_for('backend.edit_page', page_id=page.id) }}">Edit</a><br>
 	<p>{{ page.source }}</p>

+ 22 - 10
app/templates/site/index.j2

@@ -17,15 +17,27 @@
 	{% endfor %}
 	{% endif %}
 	{% endwith %}
-	{%- for item in current_menu.children recursive -%}
-	<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ item.text }}">
-	    <a class="nav-link" href="{{ item.url}}">
-	        <span class="nav-link-text">{{ item.text }}</span>
-	    </a>
-	</li>
-	{%- endfor -%}
+	<ul>
+		{%- for item in current_menu.children recursive -%}
+		<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ item.text }}">
+		    <a class="nav-link" href="{{ item.url}}">
+		        <span class="nav-link-text">{{ item.text }}</span>
+		    </a>
+		</li>
+		{%- endfor -%}
+	</ul>
 	<h1>Backend</h1>
-	{% for page in pages %}
-	<a href="{{ url_for('backend.view_page', page_id=page.id) }}">{{ page.title }}</a><br>
-	{% endfor %}
+	<h2>Pages</h2>
+	<ul>
+		{%- for page in pages recursive -%}
+		<li>
+			<a href="{{ url_for('backend.view_page', page_id=page.id) }}">{{ page.title if page.title else 'page %s' % page.id }}</a>
+		    {% if page.children.count() %}
+		    <ul>
+		    	{{ loop(page.children) }}
+		    </ul>
+		    {% endif %}
+		</li>
+		{%- endfor -%}
+	</ul>
 </body>

+ 26 - 0
migrations/versions/b87f52d28bb9_page_add_parent.py

@@ -0,0 +1,26 @@
+"""page_add_parent
+
+Revision ID: b87f52d28bb9
+Revises: 476b167aef80
+Create Date: 2019-02-19 22:38:47.415942
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = 'b87f52d28bb9'
+down_revision = '476b167aef80'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    op.add_column('page', sa.Column('parent_id', sa.Integer(), nullable=True))
+    op.create_foreign_key(None, 'page', 'page', ['parent_id'], ['id'])
+
+
+def downgrade():
+    op.drop_constraint(None, 'page', type_='foreignkey')
+    op.drop_column('page', 'parent_id')