]> danix's work - publisher.git/commitdiff
feat: new article stub creation with Typora open
authorDanilo M. <redacted>
Sun, 3 May 2026 08:40:54 +0000 (10:40 +0200)
committerDanilo M. <redacted>
Sun, 3 May 2026 08:40:54 +0000 (10:40 +0200)
ui/main_window.py
ui/new_article_dialog.py [new file with mode: 0644]

index 01e4cf2e2d6af66f7ed62f2d4f282ba89e867301..001b03a1b0b20925398fc773a205091387842b7f 100644 (file)
@@ -80,7 +80,7 @@ class MainWindow(QMainWindow):
         self._page_detail = self._stack.count() - 1
 
         # Remaining placeholders
-        for name in ["new_article", "taxonomy", "media", "translations", "git", "hugo"]:
+        for name in ["taxonomy", "media", "translations", "git", "hugo"]:
             w = QLabel(f"[{name}]")
             w.setAlignment(Qt.AlignmentFlag.AlignCenter)
             self._stack.addWidget(w)
@@ -134,7 +134,10 @@ class MainWindow(QMainWindow):
         no_trans_row.addWidget(self._badge_no_trans)
         layout.addLayout(no_trans_row)
 
-        btn("➕ Nuovo articolo", "_page_new_article")
+        b_new = SidebarButton("➕ Nuovo articolo")
+        b_new.clicked.connect(self._do_new_article)
+        layout.addWidget(b_new)
+        self._btn_group.append(b_new)
         btn("🏷 Tassonomia", "_page_taxonomy")
         btn("🖼 Media", "_page_media")
 
@@ -178,6 +181,13 @@ class MainWindow(QMainWindow):
         if dlg.exec():
             self._detail_view.set_article(article)
 
+    def _do_new_article(self):
+        from ui.new_article_dialog import NewArticleDialog
+        dlg = NewArticleDialog(Path(self.config.blog_repo), self)
+        if dlg.exec() and dlg.created_path:
+            self._refresh_articles()
+            subprocess.Popen([self.config.typora_bin, str(dlg.created_path)])
+
     def _do_translate(self, article: Article):
         pass  # implemented in Task 15
 
diff --git a/ui/new_article_dialog.py b/ui/new_article_dialog.py
new file mode 100644 (file)
index 0000000..0e0b4f5
--- /dev/null
@@ -0,0 +1,93 @@
+from __future__ import annotations
+from datetime import date
+from pathlib import Path
+from PyQt6.QtWidgets import (
+    QDialog, QVBoxLayout, QFormLayout, QHBoxLayout,
+    QLineEdit, QComboBox, QLabel, QPushButton, QMessageBox,
+)
+from core.models import ARTICLE_TYPES
+
+STUB_TEMPLATE = """\
++++
+title = "{title}"
+date = {date}
+type = "{type}"
+draft = true
+excerpt = ""
+tags = []
+categories = []
++++
+
+TODO: scrivi il contenuto qui.
+"""
+
+class NewArticleDialog(QDialog):
+    def __init__(self, blog_root: Path, parent=None):
+        super().__init__(parent)
+        self.setWindowTitle("Nuovo articolo")
+        self.setMinimumWidth(400)
+        self._blog_root = blog_root
+        self._created_path: Path | None = None
+        self._build_ui()
+
+    @property
+    def created_path(self) -> Path | None:
+        return self._created_path
+
+    def _build_ui(self):
+        layout = QVBoxLayout(self)
+        form = QFormLayout()
+
+        self._slug = QLineEdit()
+        self._slug.setPlaceholderText("mio-articolo-2026")
+        form.addRow("Slug:", self._slug)
+
+        self._title = QLineEdit()
+        self._title.setPlaceholderText("Il mio articolo")
+        form.addRow("Titolo:", self._title)
+
+        self._lang = QComboBox()
+        self._lang.addItems(["it", "en"])
+        form.addRow("Lingua:", self._lang)
+
+        self._type = QComboBox()
+        self._type.addItems(ARTICLE_TYPES)
+        form.addRow("Tipo:", self._type)
+
+        layout.addLayout(form)
+
+        btns = QHBoxLayout()
+        create_btn = QPushButton("Crea")
+        create_btn.clicked.connect(self._create)
+        cancel_btn = QPushButton("Annulla")
+        cancel_btn.clicked.connect(self.reject)
+        btns.addStretch()
+        btns.addWidget(cancel_btn)
+        btns.addWidget(create_btn)
+        layout.addLayout(btns)
+
+    def _create(self):
+        slug = self._slug.text().strip()
+        title = self._title.text().strip()
+        lang = self._lang.currentText()
+        article_type = self._type.currentText()
+
+        if not slug or not title:
+            QMessageBox.warning(self, "Errore", "Slug e titolo sono obbligatori.")
+            return
+
+        target = self._blog_root / "content" / lang / "articles" / slug
+        if target.exists():
+            QMessageBox.warning(self, "Errore", f"Esiste già: {target}")
+            return
+
+        target.mkdir(parents=True)
+        index_md = target / "index.md"
+        index_md.write_text(STUB_TEMPLATE.format(
+            title=title,
+            date=date.today().isoformat(),
+            type=article_type,
+        ), encoding="utf-8")
+
+        self._created_path = index_md
+        self.accept()