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)
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")
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
--- /dev/null
+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()