fix(seo): انتشار مشخصات فنی پروژه‌ها — باگ جاافتاده که زیربنا/طبقات/واحدها را حذف می‌کرد

پاسخ به این‌که دستیارهای AI «متراژ پروژه را پیدا نمی‌کنند» در حالی که در پنل ثبت شده است:
- _project_content_html فقط ۴ فیلد (موقعیت/سال/زیربنا/کارفرما) را منتشر می‌کرد و
  زیربنا را روی نسخهٔ انگلیسی به‌خاطر نبود *_en حذف می‌کرد. حالا همهٔ فیلدهای فنی
  (زمین، زیربنا، طبقات، پیلوت، واحدهای مسکونی/تجاری/اداری، کاربری، نوع، کارفرما، وضعیت)
  منتشر می‌شوند؛ اعداد زبان‌مستقل‌اند و در نبود ترجمه هم مقدار فارسی می‌آید.
- _project_schema: همان مشخصات به‌صورت additionalProperty (PropertyValue) اضافه شد
  تا به‌عنوان دادهٔ ساخت‌یافته قابل استناد باشد.

نمونهٔ زنده (آرامش الیسیان): زمین ۱۵۵۰، زیربنا ۸۷۰۰، طبقات ۷، ۳۱ واحد مسکونی، ۶ تجاری.
۶۵/۶۵ پروژه زیربنا و طبقات دارند — پیش از این هیچ‌کدام منتشر نمی‌شد.
This commit is contained in:
aramesh-site deploy
2026-10-09 23:36:55 +00:00
parent 1d0c1ae53d
commit b26207769f
+40 -4
View File
@@ -1012,6 +1012,25 @@ def _project_schema(project: models.Project, lang: str, db: Session) -> dict:
schema["description"] = description
if location:
schema["locationCreated"] = {"@type": "Place", "name": location.strip()}
# مشخصات فنی پروژه — دادهٔ ساخت‌یافته تا موتورها/دستیارها بتوانند به آن استناد کنند
def spec(fa_v: object, en_v: object, label: str) -> dict | None:
val = (str(en_v).strip() if (lang == "en" and str(en_v or "").strip()) else str(fa_v or "").strip())
return {"@type": "PropertyValue", "name": label, "value": val} if val else None
specs = [
spec(project.year, getattr(project, "year_en", ""), "Year" if lang == "en" else "سال"),
spec(project.location, getattr(project, "location_en", ""), "Location" if lang == "en" else "موقعیت"),
spec(project.land_area, getattr(project, "land_area_en", ""), "Land area" if lang == "en" else "مساحت زمین"),
spec(project.area, getattr(project, "area_en", ""), "Built area" if lang == "en" else "زیربنا"),
spec(project.floors, getattr(project, "floors_en", ""), "Floors" if lang == "en" else "طبقات"),
spec(project.units_residential, getattr(project, "units_residential_en", ""), "Residential units" if lang == "en" else "واحد مسکونی"),
spec(project.units_commercial, getattr(project, "units_commercial_en", ""), "Commercial units" if lang == "en" else "واحد تجاری"),
spec(project.units_office, getattr(project, "units_office_en", ""), "Office units" if lang == "en" else "واحد اداری"),
spec(project.client, getattr(project, "client_en", ""), "Client" if lang == "en" else "کارفرما"),
]
specs = [s for s in specs if s]
if specs:
schema["additionalProperty"] = specs
# همهٔ تصاویر (شاخص + گالری) به‌صورت ImageObject با نام — تا هر تصویر هویت داشته باشد
paths = [project.image] if (project.image or "").strip() else []
for g in (project.gallery or []):
@@ -1048,13 +1067,30 @@ def _project_content_html(project: models.Project, lang: str, brand: str) -> str
parts.append(f"<p>{esc(text)}</p>")
facts = []
# مشخصات فنی — همهٔ فیلدهای عدسی که تیم در پنل پر می‌کند.
# اعداد زبان‌مستقل‌اند؛ پس حتی وقتی ترجمهٔ انگلیسی نیست، مقدار فارسی
# (ارقام فارسی) هم منتشر می‌شود تا داده گم نشود.
def num(fa_v: object, en_v: object) -> str:
if lang == "en" and str(en_v or "").strip():
return str(en_v).strip()
return str(fa_v or "").strip()
for fa_v, en_v, label_fa, label_en in [
(project.location, project.location_en, "موقعیت", "Location"),
(project.year, project.year_en, "سال", "Year"),
(project.area, getattr(project, "area_en", ""), "زیربنا", "Area"),
(project.location, getattr(project, "location_en", ""), "موقعیت", "Location"),
(project.year, getattr(project, "year_en", ""), "سال", "Year"),
(project.project_type, getattr(project, "project_type_en", ""), "نوع پروژه", "Project type"),
(project.usage, getattr(project, "usage_en", ""), "کاربری", "Usage"),
(project.land_area, getattr(project, "land_area_en", ""), "مساحت زمین (مترمربع)", "Land area (m²)"),
(project.area, getattr(project, "area_en", ""), "زیربنا (مترمربع)", "Built area (m²)"),
(project.floors, getattr(project, "floors_en", ""), "تعداد طبقات", "Floors"),
(project.pilot_floors, getattr(project, "pilot_floors_en", ""), "طبقات پیلوت", "Pilot floors"),
(project.units_residential, getattr(project, "units_residential_en", ""), "واحد مسکونی", "Residential units"),
(project.units_commercial, getattr(project, "units_commercial_en", ""), "واحد تجاری", "Commercial units"),
(project.units_office, getattr(project, "units_office_en", ""), "واحد اداری", "Office units"),
(project.client, getattr(project, "client_en", ""), "کارفرما", "Client"),
(project.status, "", "وضعیت", "Status"),
]:
val = en(fa_v or "", en_v)
val = num(fa_v, en_v)
if val:
facts.append(f"<li>{label_en if lang == 'en' else label_fa}: {esc(val)}</li>")
if facts: