placeholder, edit update
This commit is contained in:
2
content
2
content
Submodule content updated: f2bf62144f...182725bce2
@@ -1,181 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "090c7992",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# git entry and print\n",
|
||||
"def get_entry(file_path, id):\n",
|
||||
" # 1. Import the current list to get the latest ID\n",
|
||||
" # use a namespace to avoid path issues\n",
|
||||
" namespace = {}\n",
|
||||
"\n",
|
||||
" with open(file_path, \"r\") as f:\n",
|
||||
" exec(f.read(), namespace)\n",
|
||||
"\n",
|
||||
" posts = namespace.get(\"BLOG_POSTS\", [])\n",
|
||||
"\n",
|
||||
" for items in posts:\n",
|
||||
" if items.get(\"id\") == id:\n",
|
||||
" content = items.get(\"content\")\n",
|
||||
" print(content)\n",
|
||||
" return items\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def update_entry(file_path, post_id, new_content):\n",
|
||||
" # 1. Load the existing data into memory\n",
|
||||
" namespace = {}\n",
|
||||
" with open(file_path, \"r\") as f:\n",
|
||||
" exec(f.read(), namespace)\n",
|
||||
"\n",
|
||||
" posts = namespace.get(\"BLOG_POSTS\", [])\n",
|
||||
"\n",
|
||||
" # 2. Find and update the specific post\n",
|
||||
" found = False\n",
|
||||
" for post in posts:\n",
|
||||
" if post.get(\"id\") == post_id:\n",
|
||||
" post[\"content\"] = new_content\n",
|
||||
" # Optional: Update the date or add an \"updated\" field\n",
|
||||
" # post['subtitle'] += \" (Updated)\"\n",
|
||||
" found = True\n",
|
||||
" break\n",
|
||||
"\n",
|
||||
" if not found:\n",
|
||||
" print(f\"Error: Post {post_id} not found.\")\n",
|
||||
" return\n",
|
||||
"\n",
|
||||
" # 3. Write the entire list back to the file\n",
|
||||
" # Using repr() or a loop to format it cleanly\n",
|
||||
" with open(file_path, \"w\") as f:\n",
|
||||
" f.write(\"BLOG_POSTS = [\\n\")\n",
|
||||
" for p in posts:\n",
|
||||
" # Use .get() to provide a default value if the key is missing\n",
|
||||
" display_val = p.get(\"displayall\", False)\n",
|
||||
" data_val = p.get(\"date\", \"?\")\n",
|
||||
" subtitle_val = p.get(\"subtitle\", \"\")\n",
|
||||
"\n",
|
||||
" entry = f\"\"\" {{\n",
|
||||
" 'id': {p[\"id\"]},\n",
|
||||
" 'title': \"{p[\"title\"]}\",\n",
|
||||
" 'subtitle': \"{subtitle_val}\",\n",
|
||||
" 'date': \"{data_val}\",\n",
|
||||
" 'content': \\\"\\\"\\\"{p[\"content\"]}\\\"\\\"\\\",\n",
|
||||
" \"displayall\": {display_val}\n",
|
||||
" }},\\n\"\"\"\n",
|
||||
" f.write(entry)\n",
|
||||
" f.write(\"]\\n\")\n",
|
||||
"\n",
|
||||
" print(f\"Post {post_id} updated successfully.\")\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "e94255ff",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import datetime\n",
|
||||
"FIELDS = ['title', 'subtitle', 'content', 'displayall']\n",
|
||||
"# id is incremental\n",
|
||||
"def add_entry(file_path, title, subtitle, content, display_all=False):\n",
|
||||
" # 1. Import the current list to get the latest ID\n",
|
||||
" # We use a namespace to avoid path issues\n",
|
||||
" namespace = {}\n",
|
||||
" with open(file_path, 'r') as f:\n",
|
||||
" exec(f.read(), namespace)\n",
|
||||
" \n",
|
||||
" posts = namespace.get('BLOG_POSTS', [])\n",
|
||||
" new_id = max([p['id'] for p in posts], default=0) + 1\n",
|
||||
" print(\"new id\", new_id)\n",
|
||||
" # 2. Format the new entry string\n",
|
||||
" date_str = datetime.datetime.now().strftime(\"%B %d, %Y\")\n",
|
||||
" \n",
|
||||
" new_post_str = f\"\"\"\n",
|
||||
" {{\n",
|
||||
" 'id': {new_id},\n",
|
||||
" 'title': '{title}',\n",
|
||||
" 'content': \\\"\\\"\\\"\n",
|
||||
" {content}\n",
|
||||
"\\\"\\\"\\\",\n",
|
||||
" 'subtitle': '{subtitle}',\n",
|
||||
" 'date': '{date_str}',\n",
|
||||
" \"displayall\": {display_all}\n",
|
||||
" }},\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" # 3. Append to the file\n",
|
||||
" # Note: This appends to the END of the file. \n",
|
||||
" # If your file ends with ']', we need to strip that first.\n",
|
||||
" with open(file_path, 'r+') as f:\n",
|
||||
" content_full = f.read().strip()\n",
|
||||
" # Find the last closing bracket of the list\n",
|
||||
" if content_full.endswith(']'):\n",
|
||||
" content_full = content_full.rsplit(']', 1)[0]\n",
|
||||
" \n",
|
||||
" f.seek(0)\n",
|
||||
" f.write(content_full + new_post_str + \"\\n]\")\n",
|
||||
" f.truncate()\n",
|
||||
"\n",
|
||||
" print(f\"Successfully added Post #{new_id}: {title}\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "7c80d17a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"have been fighting with tailwind & boostrap for hours...\n",
|
||||
"\n",
|
||||
"Post 10 updated successfully.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"FIEL_PATH = \"../content/posts.py\"\n",
|
||||
"get_entry(FIEL_PATH, 10)\n",
|
||||
"# update_entry(FIEL_PATH, target_id, new_text)\n",
|
||||
"# add_entry(FIEL_PATH, \"title\", \"subtitle\", new_text)\n",
|
||||
"text=\"\"\"I have been fighting with tailwind \n",
|
||||
"& bootstrap for past two days... It was easy to write a standalone \n",
|
||||
"web page with a few lines under tailwind or bootstrap, but not with the \n",
|
||||
"combination of both. I had the nice timeline in first 2 minutes, and \n",
|
||||
"then made 60+ hopeless commits for the font and spacing behavior under \n",
|
||||
"bootstrap...\n",
|
||||
"\"\"\"\n",
|
||||
"#add_entry(FIEL_PATH, \"test timeline\", \"subtitle\", text)\n",
|
||||
"update_entry(FIEL_PATH, 10, text)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "graphx",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.11"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
import datetime
|
||||
|
||||
|
||||
# git entry and print
|
||||
def get_entry(file_path, id):
|
||||
# 1. Import the current list to get the latest ID
|
||||
# use a namespace to avoid path issues
|
||||
namespace = {}
|
||||
|
||||
with open(file_path, "r") as f:
|
||||
exec(f.read(), namespace)
|
||||
|
||||
posts = namespace.get("BLOG_POSTS", [])
|
||||
|
||||
for items in posts:
|
||||
if items.get("id") == id:
|
||||
content = items.get("content")
|
||||
print(content)
|
||||
return items
|
||||
|
||||
|
||||
def update_entry(file_path, post_id, new_content):
|
||||
# 1. Load the existing data into memory
|
||||
namespace = {}
|
||||
with open(file_path, "r") as f:
|
||||
exec(f.read(), namespace)
|
||||
|
||||
posts = namespace.get("BLOG_POSTS", [])
|
||||
|
||||
# 2. Find and update the specific post
|
||||
found = False
|
||||
for post in posts:
|
||||
if post.get("id") == post_id:
|
||||
post["content"] = new_content
|
||||
# Optional: Update the date or add an "updated" field
|
||||
# post['subtitle'] += " (Updated)"
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
print(f"Error: Post {post_id} not found.")
|
||||
return
|
||||
|
||||
# 3. Write the entire list back to the file
|
||||
# Using repr() or a loop to format it cleanly
|
||||
with open(file_path, "w") as f:
|
||||
f.write("BLOG_POSTS = [\n")
|
||||
for p in posts:
|
||||
# Use .get() to provide a default value if the key is missing
|
||||
display_val = p.get("displayall", False)
|
||||
data_val = p.get("date", "?")
|
||||
subtitle_val = p.get("subtitle", "")
|
||||
|
||||
entry = f""" {{
|
||||
'id': {p["id"]},
|
||||
'title': "{p["title"]}",
|
||||
'subtitle': "{subtitle_val}",
|
||||
'date': "{data_val}",
|
||||
'content': \"\"\"{p["content"]}\"\"\",
|
||||
"displayall": {display_val}
|
||||
}},\n"""
|
||||
f.write(entry)
|
||||
f.write("]\n")
|
||||
|
||||
print(f"Post {post_id} updated successfully.")
|
||||
|
||||
FIELDS = ['title', 'subtitle', 'content', 'displayall']
|
||||
# id is incremental
|
||||
def add_entry(file_path, title, subtitle, content, display_all=False):
|
||||
# 1. Import the current list to get the latest ID
|
||||
# We use a namespace to avoid path issues
|
||||
namespace = {}
|
||||
with open(file_path, 'r') as f:
|
||||
exec(f.read(), namespace)
|
||||
|
||||
posts = namespace.get('BLOG_POSTS', [])
|
||||
new_id = max([p['id'] for p in posts], default=0) + 1
|
||||
print("new id", new_id)
|
||||
# 2. Format the new entry string
|
||||
date_str = datetime.datetime.now().strftime("%B %d, %Y")
|
||||
|
||||
new_post_str = f"""
|
||||
{{
|
||||
'id': {new_id},
|
||||
'title': '{title}',
|
||||
'content': \"\"\"
|
||||
{content}
|
||||
\"\"\",
|
||||
'subtitle': '{subtitle}',
|
||||
'date': '{date_str}',
|
||||
"displayall": {display_all}
|
||||
}},
|
||||
"""
|
||||
|
||||
# 3. Append to the file
|
||||
# Note: This appends to the END of the file.
|
||||
# If your file ends with ']', we need to strip that first.
|
||||
with open(file_path, 'r+') as f:
|
||||
content_full = f.read().strip()
|
||||
# Find the last closing bracket of the list
|
||||
if content_full.endswith(']'):
|
||||
content_full = content_full.rsplit(']', 1)[0]
|
||||
|
||||
f.seek(0)
|
||||
f.write(content_full + new_post_str + "\n]")
|
||||
f.truncate()
|
||||
|
||||
print(f"Successfully added Post #{new_id}: {title}")
|
||||
|
||||
# ------------ exmaple usage --------------------
|
||||
|
||||
FIEL_PATH = "../content/posts.py"
|
||||
#get_entry(FIEL_PATH, 0)
|
||||
# update_entry(FIEL_PATH, target_id, new_text)
|
||||
# add_entry(FIEL_PATH, "title", "subtitle", new_text)
|
||||
text="""<h1 class="text-3xl font-bold mb-8">Project Timeline</h1>
|
||||
|
||||
{% include "components/timeline.html" %}
|
||||
"""
|
||||
add_entry(FIEL_PATH, "test timeline", "subtitle", text)
|
||||
@@ -65,7 +65,7 @@
|
||||
type="text"
|
||||
name="author"
|
||||
class="form-control"
|
||||
placeholder="Your Name"
|
||||
placeholder="Name ^ ^"
|
||||
required
|
||||
style="margin-bottom: 15px"
|
||||
/>
|
||||
@@ -82,7 +82,7 @@
|
||||
name="content"
|
||||
class="form-control"
|
||||
rows="4"
|
||||
placeholder="Write your thoughts..."
|
||||
placeholder="Comments may need one day to appear... /\_/\ ( o.o ) > ^ <"
|
||||
required
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,14 @@ Template{% endblock %} {% block content %} {% from
|
||||
<p>
|
||||
<span class="glyphicon glyphicon-time"></span> Posted on {{ post.date }}
|
||||
</p>
|
||||
{{ render_post(post) }}
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
|
||||
Lorem Ipsum has been the industry's standard dummy text ever since the
|
||||
1500s, when an unknown printer took a galley of type and scrambled it to
|
||||
make a type specimen book. It has survived not only five centuries, but also
|
||||
the leap into electronic typesetting, remaining essentially unchanged. It
|
||||
was popularised in the 1960s with the release of Letraset sheets containing
|
||||
Lorem Ipsum passages, and more recently with desktop publishing software
|
||||
like Aldus PageMaker including versions of Lorem Ipsum.
|
||||
<div class="post-actions">
|
||||
<a href="{{ url_for('home') }}" class="btn btn-default btn-custom"
|
||||
>← Back to Posts</a
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="" />
|
||||
<meta name="author" content="" />
|
||||
|
||||
<title>Home</title>
|
||||
|
||||
<!-- Bootstrap Core CSS -->
|
||||
<link href="../static/css/bootstrap.min.css" rel="stylesheet" />
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link href="../static/css/simple-blog-template.css" rel="stylesheet" />
|
||||
|
||||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
|
||||
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Navigation -->
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
<div class="container">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button
|
||||
type="button"
|
||||
class="navbar-toggle"
|
||||
data-toggle="collapse"
|
||||
data-target="#bs-example-navbar-collapse-1"
|
||||
>
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.html"
|
||||
>Index Page - Under Construction</a
|
||||
>
|
||||
</div>
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li>
|
||||
<a href="about.html">About</a>
|
||||
</li>
|
||||
<!--li>
|
||||
<a href="login.html">Login</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="signup.html">Sign up</a>
|
||||
</li-->
|
||||
</ul>
|
||||
</div>
|
||||
<!-- /.navbar-collapse -->
|
||||
</div>
|
||||
<!-- /.container -->
|
||||
</nav>
|
||||
|
||||
<!-- Page Content -->
|
||||
<div class="container">{% block content %} {% endblock %}</div>
|
||||
|
||||
<!-- /.container -->
|
||||
|
||||
<!-- Footer -->
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<p>Last Update: October 2024</p>
|
||||
</div>
|
||||
<!-- /.col-lg-12 -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="../static/js/jquery.js"></script>
|
||||
|
||||
<!-- Bootstrap Core JavaScript -->
|
||||
<script src="../static/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user