{"id":37956,"date":"2026-03-18T20:16:27","date_gmt":"2026-03-18T13:16:27","guid":{"rendered":"https:\/\/dps.media\/?p=37956"},"modified":"2026-03-18T20:25:33","modified_gmt":"2026-03-18T13:25:33","slug":"wordpress-plugin-dev-guide-2","status":"publish","type":"post","link":"https:\/\/dps.media\/en\/wordpress-plugin-dev-guide-2\/","title":{"rendered":"WordPress Plugin Development Guide"},"content":{"rendered":"<?xml encoding=\"utf-8\" ?><style>\n@import url('https:\/\/fonts.googleapis.com\/css2?family=Syne:wght@600;700;800&family=JetBrains+Mono:wght@300;400;500&family=DM+Sans:wght@300;400;500&display=swap');\n\n#dps-guide {\n  --bg:      #09090e;\n  --bg2:     #0e0e18;\n  --faint:   #1a1a2c;\n  --border:  rgba(255,255,255,0.07);\n  --border2: rgba(255,255,255,0.13);\n  --text:    #ddddf0;\n  --muted:   #6060a0;\n  --blue:    #5b9cf6;\n  --green:   #34d399;\n  --purple:  #a78bfa;\n  --amber:   #fbbf24;\n  --slate:   #94a3b8;\n  --coral:   #fb7185;\n  --blue-bg:   rgba(91,156,246,0.08);\n  --green-bg:  rgba(52,211,153,0.08);\n  --purple-bg: rgba(167,139,250,0.08);\n  --amber-bg:  rgba(251,191,36,0.08);\n  --slate-bg:  rgba(148,163,184,0.08);\n  --coral-bg:  rgba(251,113,133,0.08);\n  background: var(--bg);\n  color: var(--text);\n  font-family: 'DM Sans', sans-serif;\n  line-height: 1.6;\n  border-radius: 16px;\n  overflow: hidden;\n  position: relative;\n}\n\n#dps-guide *,#dps-guide *::before,#dps-guide *::after{box-sizing:border-box;margin:0;padding:0;}\n\n\/* TOP BAR *\/\n#dps-guide .dps-topbar{background:rgba(9,9,14,0.92);backdrop-filter:blur(20px);border-bottom:1px solid var(--border);padding:0 40px;height:52px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:50;}\n#dps-guide .dps-brand{display:flex;align-items:center;gap:10px;text-decoration:none;}\n#dps-guide .dps-logo{width:28px;height:28px;border-radius:7px;background:linear-gradient(135deg,rgba(91,156,246,.35),rgba(167,139,250,.35));border:1px solid rgba(167,139,250,.25);display:flex;align-items:center;justify-content:center;font-family:'Syne',sans-serif;font-size:13px;font-weight:800;color:#c4b5f4;flex-shrink:0;}\n#dps-guide .dps-brand-name{font-family:'Syne',sans-serif;font-size:14px;font-weight:700;color:#fff;letter-spacing:-.01em;}\n#dps-guide .dps-topbar-right{display:flex;align-items:center;gap:14px;}\n#dps-guide .dps-nav-tag{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--muted);letter-spacing:.04em;}\n#dps-guide #dps-copy-btn{display:flex;align-items:center;gap:7px;background:var(--faint);border:1px solid var(--border2);border-radius:8px;padding:6px 14px;cursor:pointer;font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--text);transition:all .18s;white-space:nowrap;}\n#dps-guide #dps-copy-btn:hover{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.2);}\n#dps-guide #dps-copy-btn.copied{background:rgba(52,211,153,0.08);border-color:rgba(52,211,153,.35);color:var(--green);}\n\n\/* PAGE *\/\n#dps-guide .dps-page{padding:48px 40px 64px;max-width:1080px;margin:0 auto;}\n\n\/* HEADER *\/\n#dps-guide .author-pill{display:inline-flex;align-items:center;gap:10px;background:var(--faint);border:1px solid var(--border2);border-radius:99px;padding:6px 14px 6px 8px;margin-bottom:28px;}\n#dps-guide .author-av{width:28px;height:28px;border-radius:50%;background:linear-gradient(135deg,rgba(91,156,246,.4),rgba(167,139,250,.4));display:flex;align-items:center;justify-content:center;font-family:'Syne',sans-serif;font-size:12px;font-weight:800;color:#fff;}\n#dps-guide .author-pill span{font-size:13px;color:var(--text);font-weight:500;}\n#dps-guide .author-pill em{font-style:normal;color:var(--muted);font-size:12px;}\n#dps-guide h1{font-family:'Syne',sans-serif;font-size:clamp(34px,5vw,58px);font-weight:800;line-height:.95;letter-spacing:-.03em;color:#fff;margin-bottom:16px;}\n#dps-guide h1 span{background:linear-gradient(120deg,var(--blue) 0%,var(--purple) 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;}\n#dps-guide .header-sub{font-size:15px;font-weight:300;color:var(--muted);max-width:500px;margin-bottom:56px;}\n\n\/* SECTION LABEL *\/\n#dps-guide .slabel{font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted);display:flex;align-items:center;gap:10px;margin-bottom:20px;}\n#dps-guide .slabel::after{content:'';flex:1;height:1px;background:var(--border);}\n\n\/* TAGS *\/\n#dps-guide .tag{font-family:'JetBrains Mono',monospace;font-size:10px;font-weight:500;padding:3px 10px;border-radius:4px;border:1px solid;display:inline-flex;align-items:center;gap:6px;white-space:nowrap;}\n#dps-guide .tag .dot{width:5px;height:5px;border-radius:50%;background:currentColor;}\n#dps-guide .t-blue  {color:var(--blue);  background:var(--blue-bg);  border-color:rgba(91,156,246,.25);}\n#dps-guide .t-green {color:var(--green); background:var(--green-bg); border-color:rgba(52,211,153,.25);}\n#dps-guide .t-purple{color:var(--purple);background:var(--purple-bg);border-color:rgba(167,139,250,.25);}\n#dps-guide .t-amber {color:var(--amber); background:var(--amber-bg); border-color:rgba(251,191,36,.25);}\n#dps-guide .t-slate {color:var(--slate); background:var(--slate-bg); border-color:rgba(148,163,184,.25);}\n#dps-guide .t-coral {color:var(--coral); background:var(--coral-bg); border-color:rgba(251,113,133,.25);}\n\n\/* CARD *\/\n#dps-guide .card{background:var(--bg2);border:1px solid var(--border);border-radius:16px;overflow:hidden;}\n#dps-guide .card-pad{padding:28px;}\n\n\/* FILE TREE *\/\n#dps-guide .tree-section{margin-bottom:56px;}\n#dps-guide .tree-wrap{background:var(--bg2);border:1px solid var(--border);border-radius:16px;overflow:hidden;}\n#dps-guide .tree-topbar-inner{background:var(--faint);border-bottom:1px solid var(--border);padding:10px 20px;display:flex;align-items:center;gap:8px;}\n#dps-guide .tree-topbar-inner span{width:10px;height:10px;border-radius:50%;}\n#dps-guide .tree-topbar-inner small{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--muted);margin-left:8px;}\n#dps-guide .tree-body{display:grid;grid-template-columns:1fr 1fr;gap:0;}\n#dps-guide .tree-col{padding:24px 28px;}\n#dps-guide .tree-col+.tree-col{border-left:1px solid var(--border);}\n#dps-guide .tree-label{font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-bottom:14px;}\n#dps-guide .tree{font-family:'JetBrains Mono',monospace;font-size:12px;line-height:2.1;}\n#dps-guide .tree .d{color:var(--blue);font-weight:500;}\n#dps-guide .tree .f{color:var(--text);}\n#dps-guide .tree .x{color:var(--green);font-weight:500;}\n#dps-guide .tree .c{color:var(--muted);font-size:11px;}\n#dps-guide .tree .i{color:var(--coral);}\n#dps-guide .tree .indent{padding-left:20px;}\n#dps-guide .tree .indent2{padding-left:40px;}\n#dps-guide .tree .indent3{padding-left:60px;}\n\n\/* FLOW *\/\n#dps-guide .flow-section{margin-bottom:56px;}\n#dps-guide .flow-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;}\n#dps-guide .fcard{background:var(--bg2);border:1px solid var(--border);border-radius:16px;overflow:hidden;}\n#dps-guide .fcard-head{padding:20px 24px 0;}\n#dps-guide .fcard h3{font-family:'Syne',sans-serif;font-size:18px;font-weight:700;color:#fff;letter-spacing:-.01em;margin-bottom:4px;margin-top:10px;}\n#dps-guide .fcard-sub{font-size:12.5px;color:var(--muted);font-weight:300;margin-bottom:20px;}\n#dps-guide .fcard-body{padding:0 24px 24px;}\n#dps-guide .steps{display:flex;flex-direction:column;}\n#dps-guide .step{display:flex;gap:14px;align-items:flex-start;}\n#dps-guide .step-l{display:flex;flex-direction:column;align-items:center;flex-shrink:0;}\n#dps-guide .step-dot{width:28px;height:28px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:500;border:1px solid;flex-shrink:0;}\n#dps-guide .step-line{width:1px;flex:1;min-height:14px;background:var(--border);margin:3px 0;}\n#dps-guide .step-r{padding-top:4px;padding-bottom:18px;}\n#dps-guide .step-title{font-size:13px;font-weight:500;color:var(--text);margin-bottom:2px;}\n#dps-guide .step-desc{font-size:12px;color:var(--muted);font-weight:300;line-height:1.55;}\n#dps-guide .code{margin-top:6px;background:var(--faint);border-radius:6px;padding:7px 12px;font-family:'JetBrains Mono',monospace;font-size:11px;line-height:1.9;}\n#dps-guide .code .cmd{color:var(--green);}\n#dps-guide .code .cmt{color:var(--muted);}\n#dps-guide .code .val{color:var(--amber);}\n#dps-guide .code .key{color:var(--blue);}\n\n\/* SCRIPTS *\/\n#dps-guide .scripts-section{margin-bottom:56px;}\n#dps-guide .scripts-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;}\n#dps-guide .scmd{background:var(--bg2);border:1px solid var(--border);border-radius:12px;padding:18px 20px;transition:border-color .2s;}\n#dps-guide .scmd:hover{border-color:var(--border2);}\n#dps-guide .scmd-cmd{font-family:'JetBrains Mono',monospace;font-size:13px;font-weight:500;color:var(--green);margin-bottom:6px;}\n#dps-guide .scmd-what{font-size:12.5px;color:var(--muted);font-weight:300;line-height:1.5;margin-bottom:8px;}\n#dps-guide .scmd-detail{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--muted);border-top:1px solid var(--border);padding-top:8px;line-height:1.7;}\n\n\/* DO\/DONT *\/\n#dps-guide .dodonts{display:grid;grid-template-columns:1fr 1fr;gap:2px;border-radius:12px;overflow:hidden;border:1px solid var(--border);}\n#dps-guide .do-col{background:rgba(52,211,153,.04);padding:20px 22px;}\n#dps-guide .dont-col{background:rgba(251,113,133,.04);padding:20px 22px;}\n#dps-guide .do-head{font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--green);margin-bottom:12px;display:flex;align-items:center;gap:8px;}\n#dps-guide .dont-head{font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--coral);margin-bottom:12px;display:flex;align-items:center;gap:8px;}\n#dps-guide .do-head::before{content:'\u2713';font-size:12px;}\n#dps-guide .dont-head::before{content:'\u2717';font-size:12px;}\n#dps-guide .do-item,#dps-guide .dont-item{font-family:'JetBrains Mono',monospace;font-size:11.5px;padding:6px 10px;border-radius:6px;margin-bottom:4px;line-height:1.5;}\n#dps-guide .do-item{color:var(--green);background:rgba(52,211,153,.06);}\n#dps-guide .dont-item{color:var(--coral);background:rgba(251,113,133,.06);text-decoration:line-through;text-decoration-color:rgba(251,113,133,.4);}\n\n\/* ZIP *\/\n#dps-guide .zip-section{margin-bottom:56px;}\n#dps-guide .zip-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;}\n#dps-guide .zip-card{background:var(--bg2);border:1px solid var(--border);border-radius:14px;overflow:hidden;}\n#dps-guide .zip-head{padding:14px 18px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:10px;}\n#dps-guide .zip-body{padding:14px 18px;}\n#dps-guide .zip-row{display:flex;align-items:center;justify-content:space-between;padding:7px 0;border-bottom:1px solid var(--border);}\n#dps-guide .zip-row:last-child{border-bottom:none;}\n#dps-guide .zip-path{font-family:'JetBrains Mono',monospace;font-size:11.5px;}\n#dps-guide .zip-note{font-size:11px;color:var(--muted);font-weight:300;}\n\n\/* ACCEPTANCE *\/\n#dps-guide .ac-section{margin-bottom:56px;}\n#dps-guide .ac-list{display:flex;flex-direction:column;gap:6px;}\n#dps-guide .ac-item{display:flex;align-items:center;gap:14px;background:var(--bg2);border:1px solid var(--border);border-radius:10px;padding:12px 18px;transition:border-color .2s;}\n#dps-guide .ac-item:hover{border-color:var(--border2);}\n#dps-guide .ac-check{width:20px;height:20px;border-radius:6px;border:1px solid rgba(52,211,153,.3);background:rgba(52,211,153,.06);display:flex;align-items:center;justify-content:center;font-size:11px;color:var(--green);flex-shrink:0;}\n#dps-guide .ac-text{font-size:13px;color:var(--text);font-weight:400;}\n\n\/* BOTTOM BAR *\/\n#dps-guide .dps-footer{border-top:1px solid var(--border);padding:22px 40px;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:12px;}\n#dps-guide .dps-footer-l{display:flex;align-items:center;gap:10px;}\n#dps-guide .dps-footer p{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--muted);}\n#dps-guide .dps-footer-links{display:flex;gap:20px;}\n#dps-guide .dps-footer-links a{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--muted);text-decoration:none;}\n#dps-guide .dps-footer-links a:hover{color:var(--text);}\n\n\/* FADE *\/\n#dps-guide .fi{opacity:0;transform:translateY(18px);transition:opacity .5s ease,transform .5s ease;}\n#dps-guide .fi.in{opacity:1;transform:none;}\n\n@media(max-width:720px){\n  #dps-guide .dps-topbar{padding:0 20px;}\n  #dps-guide .dps-nav-tag{display:none;}\n  #dps-guide .dps-page{padding:32px 20px 48px;}\n  #dps-guide .tree-body,#dps-guide .flow-grid,#dps-guide .scripts-grid,#dps-guide .zip-grid,#dps-guide .dodonts{grid-template-columns:1fr;}\n  #dps-guide .tree-col+.tree-col{border-left:none;border-top:1px solid var(--border);}\n  #dps-guide .dps-footer{padding:20px;}\n}\n<\/style><div id=\"dps-guide\">\n\n  <!-- TOP BAR -->\n  <div class=\"dps-topbar\">\n    <div class=\"dps-brand\">\n      <div class=\"dps-logo\">D<\/div>\n      <span class=\"dps-brand-name\">DPS.MEDIA<\/span>\n    <\/div>\n    <div class=\"dps-topbar-right\">\n      <span class=\"dps-nav-tag\">WP Plugin Dev Guide \u2014 Internal<\/span>\n      <button id=\"dps-copy-btn\">\n        <svg width=\"13\" height=\"13\" viewbox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"5\" y=\"5\" width=\"9\" height=\"9\" rx=\"2\"><\/rect><path d=\"M11 5V3a2 2 0 0 0-2-2H3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2\"><\/path><\/svg>\n        <span id=\"dps-copy-label\">Copy agent prompt<\/span>\n      <\/button>\n    <\/div>\n  <\/div>\n\n  <div class=\"dps-page\">\n\n    <!-- HEADER -->\n    <div class=\"fi\">\n      <div class=\"author-pill\">\n        <div class=\"author-av\">H<\/div>\n        <span>Hi\u1ec3n<\/span>\n        <em>CEO \u00b7 DPS.MEDIA<\/em>\n      <\/div>\n      <h1>WordPress<br><span>Plugin Dev<\/span><br>Guide<\/h1>\n      <p class=\"header-sub\">Source \u2192 build \u2192 release flow for teams. Sufficient for local dev, ZIP packaging, and WordPress production installation.<\/p>\n    <\/div>\n\n    <!-- STACK PILLS -->\n    <div class=\"fi\" style=\"display:flex;gap:8px;flex-wrap:wrap;margin-bottom:56px;\">\n      <span class=\"tag t-blue\"><span class=\"dot\"><\/span>PHP 8.x<\/span>\n      <span class=\"tag t-blue\"><span class=\"dot\"><\/span>WordPress hooks API<\/span>\n      <span class=\"tag t-green\"><span class=\"dot\"><\/span>@wordpress\/scripts<\/span>\n      <span class=\"tag t-green\"><span class=\"dot\"><\/span>React (Admin UI)<\/span>\n      <span class=\"tag t-green\"><span class=\"dot\"><\/span>Webpack 5<\/span>\n      <span class=\"tag t-amber\"><span class=\"dot\"><\/span>npm scripts<\/span>\n      <span class=\"tag t-slate\"><span class=\"dot\"><\/span>Node.js \u2265 18<\/span>\n      <span class=\"tag t-slate\"><span class=\"dot\"><\/span>ZIP release<\/span>\n    <\/div>\n\n    <!-- FILE TREE -->\n    <div class=\"tree-section fi\">\n      <div class=\"slabel\">Directory structure<\/div>\n      <div class=\"tree-wrap\">\n        <div class=\"tree-topbar-inner\">\n          <span style=\"background:#ff5f57;\"><\/span>\n          <span style=\"background:#febc2e;\"><\/span>\n          <span style=\"background:#28c840;\"><\/span>\n          <small>my-plugin\/ \u2014 project root<\/small>\n        <\/div>\n        <div class=\"tree-body\">\n          <div class=\"tree-col\">\n            <div class=\"tree-label\">Source (dev)<\/div>\n            <div class=\"tree\">\n              <div><span class=\"d\">my-plugin.php<\/span> <span class=\"c\">\u2190 main plugin file<\/span><\/div>\n              <div class=\"indent\"><span class=\"d\">includes\/<\/span> <span class=\"c\">\u2190 PHP runtime<\/span><\/div>\n              <div class=\"indent2\"><span class=\"f\">class-core.php<\/span><\/div>\n              <div class=\"indent2\"><span class=\"f\">class-admin.php<\/span><\/div>\n              <div class=\"indent\"><span class=\"d\">admin\/<\/span><\/div>\n              <div class=\"indent2\"><span class=\"d\" style=\"color:var(--amber);\">src\/<\/span> <span class=\"c\">\u2190 write code here<\/span><\/div>\n              <div class=\"indent3\"><span class=\"x\">index.js<\/span> <span class=\"c\">\u2190 entry point<\/span><\/div>\n              <div class=\"indent3\"><span class=\"f\">components\/<\/span><\/div>\n              <div class=\"indent2\"><span class=\"d\" style=\"color:var(--green);\">dist\/<\/span> <span class=\"c\">\u2190 build output<\/span><\/div>\n              <div class=\"indent3\"><span class=\"x\">index.js<\/span><\/div>\n              <div class=\"indent3\"><span class=\"x\">index.asset.php<\/span><\/div>\n              <div class=\"indent3\"><span class=\"f\">index.css<\/span><\/div>\n              <div class=\"indent\"><span class=\"f\">languages\/<\/span> <span class=\"c\">\u2190 i18n<\/span><\/div>\n              <div class=\"indent\"><span class=\"i\">node_modules\/<\/span> <span class=\"c\">\u2190 .gitignore<\/span><\/div>\n              <div class=\"indent\"><span class=\"i\">releases\/<\/span> <span class=\"c\">\u2190 .gitignore<\/span><\/div>\n            <\/div>\n          <\/div>\n          <div class=\"tree-col\">\n            <div class=\"tree-label\">Config files<\/div>\n            <div class=\"tree\">\n              <div><span class=\"x\">package.json<\/span><\/div>\n              <div><span class=\"f\">webpack.config.js<\/span> <span class=\"c\">\u2190 if custom is needed<\/span><\/div>\n              <div><span class=\"x\">.gitignore<\/span><\/div>\n              <div><span class=\"x\">BUILD.md<\/span><\/div>\n              <div><span class=\"f\">readme.txt<\/span><\/div>\n              <div><span class=\"f\">uninstall.php<\/span><\/div>\n              <div style=\"margin-top:16px;background:var(--faint);border-radius:8px;padding:12px 14px;border:1px solid var(--border);\">\n                <div style=\"color:var(--muted);\">\/\/ \u2713 Correct \u2014 enqueue from dist<\/div>\n                <div style=\"color:var(--green);\">plugins_url(<span style=\"color:var(--amber);\">\u2018admin\/dist\/index.js\u2019<\/span>)<\/div>\n                <div style=\"color:var(--muted);margin-top:8px;\">\/\/ \u2717 Incorrect \u2014 do not enqueue src<\/div>\n                <div style=\"color:var(--coral);text-decoration:line-through;text-decoration-color:rgba(251,113,133,.5);\">plugins_url(<span style=\"color:var(--amber);\">\u2018admin\/src\/index.js\u2019<\/span>)<\/div>\n              <\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- WORKFLOWS -->\n    <div class=\"flow-section fi\">\n      <div class=\"slabel\">Workflows<\/div>\n      <div class=\"flow-grid\">\n        <div class=\"fcard\">\n          <div class=\"fcard-head\">\n            <div class=\"tag t-green\"><span class=\"dot\"><\/span>Local Development<\/div>\n            <h3>Local dev<\/h3>\n            <p class=\"fcard-sub\">Run watch mode, edit JS\/React \u2192 automatic build, refresh WP to see immediately.<\/p>\n          <\/div>\n          <div class=\"fcard-body\">\n            <div class=\"steps\">\n              <div class=\"step\"><div class=\"step-l\"><div class=\"step-dot t-green\">01<\/div><div class=\"step-line\"><\/div><\/div><div class=\"step-r\"><div class=\"step-title\">Install dependencies<\/div><div class=\"step-desc\">Only needed the first time. Requires Node.js \u2265 18.<\/div><div class=\"code\"><span class=\"cmd\">npm install<\/span><\/div><\/div><\/div>\n              <div class=\"step\"><div class=\"step-l\"><div class=\"step-dot t-green\">02<\/div><div class=\"step-line\"><\/div><\/div><div class=\"step-r\"><div class=\"step-title\">Enable watch mode<\/div><div class=\"step-desc\">Webpack watch: save file in <code style=\"font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--amber);\" data-no-translation=\"\">admin\/src\/<\/code> \u2192 automatically build to <code style=\"font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--green);\" data-no-translation=\"\">admin\/dist\/<\/code>. Need manual F5 in WP.<\/div><div class=\"code\"><span class=\"cmd\">npm run start<\/span><\/div><\/div><\/div>\n              <div class=\"step\"><div class=\"step-l\"><div class=\"step-dot t-green\">03<\/div><\/div><div class=\"step-r\"><div class=\"step-title\">Test on local WP<\/div><div class=\"step-desc\">Symlink into <code style=\"font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--slate);\" data-no-translation=\"\">wp-content\/plugins\/<\/code> or use Local by Flywheel.<\/div><\/div><\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n        <div class=\"fcard\">\n          <div class=\"fcard-head\">\n            <div class=\"tag t-amber\"><span class=\"dot\"><\/span>Build &amp; Release<\/div>\n            <h3>Zip, install WP<\/h3>\n            <p class=\"fcard-sub\">Production build, package clean ZIP \u2014 no npm needed on server.<\/p>\n          <\/div>\n          <div class=\"fcard-body\">\n            <div class=\"steps\">\n              <div class=\"step\"><div class=\"step-l\"><div class=\"step-dot t-amber\">01<\/div><div class=\"step-line\"><\/div><\/div><div class=\"step-r\"><div class=\"step-title\">Build production<\/div><div class=\"step-desc\">Webpack build with minify + tree-shaking.<\/div><div class=\"code\"><span class=\"cmd\">npm run build<\/span><\/div><\/div><\/div>\n              <div class=\"step\"><div class=\"step-l\"><div class=\"step-dot t-amber\">02<\/div><div class=\"step-line\"><\/div><\/div><div class=\"step-r\"><div class=\"step-title\">Package ZIP<\/div><div class=\"step-desc\">Script copies correct files, excludes <code style=\"font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--coral);\" data-no-translation=\"\">node_modules<\/code> v\u00e0 <code style=\"font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--coral);\" data-no-translation=\"\">admin\/src<\/code>.<\/div><div class=\"code\"><span class=\"cmd\">npm run package<\/span><br><span class=\"cmt\"># \u2192 releases\/plugin-v1.0.0.zip<\/span><\/div><\/div><\/div>\n              <div class=\"step\"><div class=\"step-l\"><div class=\"step-dot t-amber\">03<\/div><div class=\"step-line\"><\/div><\/div><div class=\"step-r\"><div class=\"step-title\">Verify SHA256<\/div><div class=\"code\"><span class=\"cmd\">sha256sum<\/span> <span class=\"val\">releases\/plugin-v1.0.0.zip<\/span><\/div><\/div><\/div>\n              <div class=\"step\"><div class=\"step-l\"><div class=\"step-dot\" style=\"color:var(--green);background:var(--green-bg);border-color:rgba(52,211,153,.25);\">\u2713<\/div><\/div><div class=\"step-r\"><div class=\"step-title\" style=\"color:var(--green);\">Upload to WordPress<\/div><div class=\"step-desc\">Admin \u2192 Plugins \u2192 Add New \u2192 Upload. Activate. No npm needed on server.<\/div><\/div><\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- NPM SCRIPTS -->\n    <div class=\"scripts-section fi\">\n      <div class=\"slabel\">npm scripts \u2014 cheat sheet<\/div>\n      <div class=\"scripts-grid\">\n        <div class=\"scmd\"><div class=\"scmd-cmd\">npm run start<\/div><div class=\"scmd-what\">Watch mode \u2014 daily dev<\/div><div class=\"scmd-detail\">webpack \u2013watch \u2013mode development<\/div><\/div>\n        <div class=\"scmd\"><div class=\"scmd-cmd\">npm run build<\/div><div class=\"scmd-what\">Production build \u2014 before release<\/div><div class=\"scmd-detail\">webpack \u2013mode production + minify<\/div><\/div>\n        <div class=\"scmd\"><div class=\"scmd-cmd\">npm run package<\/div><div class=\"scmd-what\">Zip clean into releases\/<\/div><div class=\"scmd-detail\">exclude src\/ node_modules\/ .git\/<\/div><\/div>\n        <div class=\"scmd\"><div class=\"scmd-cmd\">npm run lint:js<\/div><div class=\"scmd-what\">Lint JS according to WP standards<\/div><div class=\"scmd-detail\">wp-scripts lint-js<\/div><\/div>\n        <div class=\"scmd\"><div class=\"scmd-cmd\">npm run format<\/div><div class=\"scmd-what\">Auto code formatting<\/div><div class=\"scmd-detail\">wp-scripts format (prettier)<\/div><\/div>\n        <div class=\"scmd\"><div class=\"scmd-cmd\">npm run release<\/div><div class=\"scmd-what\">Lint \u2192 build \u2192 package<\/div><div class=\"scmd-detail\">check + build + package in 1 cmd<\/div><\/div>\n      <\/div>\n    <\/div>\n\n    <!-- ZIP CONTENTS -->\n    <div class=\"zip-section fi\">\n      <div class=\"slabel\">ZIP release \u2014 inside and out<\/div>\n      <div class=\"zip-grid\">\n        <div class=\"zip-card\">\n          <div class=\"zip-head\"><span class=\"tag t-green\"><span class=\"dot\"><\/span>\u2713 Included in ZIP<\/span><\/div>\n          <div class=\"zip-body\">\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--green);\">my-plugin.php<\/span><span class=\"zip-note\">main plugin file<\/span><\/div>\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--green);\">includes\/<\/span><span class=\"zip-note\">Full PHP runtime<\/span><\/div>\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--green);\">admin\/dist\/<\/span><span class=\"zip-note\">Pre-built JS\/CSS<\/span><\/div>\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--green);\">languages\/<\/span><span class=\"zip-note\">i18n if applicable<\/span><\/div>\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--green);\">readme.txt<\/span><span class=\"zip-note\">WP.org format<\/span><\/div>\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--green);\">uninstall.php<\/span><span class=\"zip-note\">cleanup on plugin deletion<\/span><\/div>\n          <\/div>\n        <\/div>\n        <div class=\"zip-card\">\n          <div class=\"zip-head\"><span class=\"tag t-coral\"><span class=\"dot\"><\/span>\u2717 Not included in ZIP<\/span><\/div>\n          <div class=\"zip-body\">\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--coral);text-decoration:line-through;text-decoration-color:rgba(251,113,133,.4);\">node_modules\/<\/span><span class=\"zip-note\">dev dependencies only<\/span><\/div>\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--coral);text-decoration:line-through;text-decoration-color:rgba(251,113,133,.4);\">admin\/src\/<\/span><span class=\"zip-note\">source, not executed<\/span><\/div>\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--coral);text-decoration:line-through;text-decoration-color:rgba(251,113,133,.4);\">.git\/<\/span><span class=\"zip-note\">repo metadata<\/span><\/div>\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--coral);text-decoration:line-through;text-decoration-color:rgba(251,113,133,.4);\">package.json \/ webpack.config.js<\/span><span class=\"zip-note\">build config<\/span><\/div>\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--coral);text-decoration:line-through;text-decoration-color:rgba(251,113,133,.4);\">.test.js \/ debug-.php<\/span><span class=\"zip-note\">internal test files<\/span><\/div>\n            <div class=\"zip-row\"><span class=\"zip-path\" style=\"color:var(--coral);text-decoration:line-through;text-decoration-color:rgba(251,113,133,.4);\">.env \/ .DS_Store<\/span><span class=\"zip-note\">local machine files<\/span><\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- DO \/ DON'T -->\n    <div class=\"fi\" style=\"margin-bottom:56px;\">\n      <div class=\"slabel\">Important rules<\/div>\n      <div class=\"dodonts\">\n        <div class=\"do-col\">\n          <div class=\"do-head\">Do it right<\/div>\n          <div class=\"do-item\">Enqueue from <code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">admin\/dist\/<\/code><\/div>\n          <div class=\"do-item\">Read <code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">index.asset.php<\/code> get deps + version<\/div>\n          <div class=\"do-item\">Use <code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">wp_localize_script()<\/code> pass data PHP \u2192 JS<\/div>\n          <div class=\"do-item\">Run <code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">npm run build<\/code> before <code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">npm run package<\/code><\/div>\n          <div class=\"do-item\">Conditional load \u2014 only enqueue needed page<\/div>\n          <div class=\"do-item\">Prefix everything: <code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">dps_<\/code>, <code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">DPS_<\/code><\/div>\n        <\/div>\n        <div class=\"dont-col\">\n          <div class=\"dont-head\">Don't do<\/div>\n          <div class=\"dont-item\">Enqueue from <code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">admin\/src\/<\/code><\/div>\n          <div class=\"dont-item\">Hardcode version hash in PHP<\/div>\n          <div class=\"dont-item\">To <code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">node_modules\/<\/code> inside ZIP<\/div>\n          <div class=\"dont-item\">npm install on production server<\/div>\n          <div class=\"dont-item\">Run heavy DB queries at <code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">init<\/code> hook<\/div>\n          <div class=\"dont-item\"><code style=\"font-family:'JetBrains Mono',monospace;\" data-no-translation=\"\">echo $_POST['x']<\/code> not sanitized\/escaped<\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- CHECKLIST -->\n    <div class=\"ac-section fi\">\n      <div class=\"slabel\">Production-ready checklist<\/div>\n      <div style=\"display:grid;grid-template-columns:1fr 1fr;gap:6px;\">\n        <div style=\"display:flex;flex-direction:column;gap:6px;\">\n          <div style=\"font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--blue);padding:4px 0 8px;\">Build &amp; Release<\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\"><code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--green);\" data-no-translation=\"\">npm run build<\/code> no errors \u2192 <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--green);\" data-no-translation=\"\">admin\/dist\/<\/code><\/div><\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">ZIP installs, Activate without errors \u2014 no npm server needed<\/div><\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">ZIP does not contain <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--coral);\" data-no-translation=\"\">node_modules\/<\/code> or <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--coral);\" data-no-translation=\"\">src\/<\/code><\/div><\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">Report back: file list + ZIP path + SHA256<\/div><\/div>\n          <div style=\"font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--purple);padding:12px 0 8px;\">Security<\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">All PHP files have <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--purple);\" data-no-translation=\"\">if (!defined('ABSPATH')) exit;<\/code><\/div><\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">All AJAX\/forms: nonce verify + <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--purple);\" data-no-translation=\"\">current_user_can()<\/code><\/div><\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">Input sanitized, output escaped<\/div><\/div>\n        <\/div>\n        <div style=\"display:flex;flex-direction:column;gap:6px;\">\n          <div style=\"font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--amber);padding:4px 0 8px;\">Performance<\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">Asset load conditional \u2014 not loaded site-wide<\/div><\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">Script: <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--amber);\" data-no-translation=\"\">in_footer: true<\/code> + <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--amber);\" data-no-translation=\"\">strategy: defer<\/code><\/div><\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">Do not run heavy DB queries at <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--amber);\" data-no-translation=\"\">init<\/code> hook<\/div><\/div>\n          <div style=\"font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--green);padding:12px 0 8px;\">Standards<\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">All functions\/classes\/options have prefix <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--green);\" data-no-translation=\"\">dps_<\/code><\/div><\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">Plugin header: <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--green);\" data-no-translation=\"\">Requires at least<\/code>, <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--green);\" data-no-translation=\"\">Requires PHP<\/code><\/div><\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\">All strings use i18n, <code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--green);\" data-no-translation=\"\">uninstall.php<\/code> clean cleanup<\/div><\/div>\n          <div class=\"ac-item\"><div class=\"ac-check\">\u2713<\/div><div class=\"ac-text\"><code style=\"font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--green);\" data-no-translation=\"\">BUILD.md<\/code> complete: install, build, package, test<\/div><\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n  <\/div><!-- \/dps-page -->\n\n  <!-- BOTTOM BAR -->\n  <div class=\"dps-footer\">\n    <div class=\"dps-footer-l\">\n      <div class=\"dps-logo\">D<\/div>\n      <p>DPS.MEDIA JOINT STOCK COMPANY \u00b7 TIN 0318700500<\/p>\n    <\/div>\n    <div class=\"dps-footer-links\">\n      <a href=\"mailto:marketing@dps.media\">marketing@dps.media<\/a>\n      <a href=\"tel:0961545445\">0961 545 445<\/a>\n      <a href=\"https:\/\/dps.media\/en\/\">dps.media<\/a>\n    <\/div>\n  <\/div>\n\n<\/div><!-- \/#dps-guide --><script>\n(function(){\n  var guide = document.getElementById('dps-guide');\n  if(!guide) return;\n\n  \/\/ Fade-in on scroll\n  var io = new IntersectionObserver(function(es){\n    es.forEach(function(e){ if(e.isIntersecting){ e.target.classList.add('in'); io.unobserve(e.target); } });\n  },{threshold:0.05});\n  guide.querySelectorAll('.fi').forEach(function(el,i){\n    el.style.transitionDelay=(i*0.06)+'s';\n    io.observe(el);\n  });\n\n  \/\/ Copy button\n  var btn = document.getElementById('dps-copy-btn');\n  var lbl = document.getElementById('dps-copy-label');\n  if(!btn) return;\n\n  btn.addEventListener('click', function(){\n    var md = \"# WP Plugin Dev \\u2014 Agent Prompt (DPS.MEDIA)\\n\\n## M\\u1ee5c ti\\u00eau\\nRefactor plugin sang flow **source \\u2192 build \\u2192 release**. Plugin ph\\u1ea3i: load nhanh, kh\\u00f4ng conflict, \\u0111\\u00fang WP coding standards, b\\u1ea3o m\\u1eadt, d\\u1ec5 b\\u1ea3o tr\\u00ec.\\n\\n---\\n\\n## 0. \\u0110\\u00e1nh gi\\u00e1 tr\\u01b0\\u1edbc khi b\\u1eaft \\u0111\\u1ea7u (YAGNI check)\\n\\nTr\\u01b0\\u1edbc khi refactor b\\u1ea5t k\\u1ef3 th\\u1ee9 g\\u00ec, ki\\u1ec3m tra t\\u1eebng th\\u01b0 m\\u1ee5c asset v\\u00e0 t\\u1ef1 \\u0111\\u00e1nh gi\\u00e1:\\n\\n- `admin\/` \\u2014 c\\u00f3 React\/JSX\/TS, import ES module, Sass? \\u2192 \\u0111\\u01b0a v\\u00e0o pipeline\\n- `public\/` \\u2014 ch\\u1ec9 vanilla JS\/jQuery\/CSS thu\\u1ea7n? \\u2192 gi\\u1eef static, kh\\u00f4ng build\\n\\n\\u00c1p d\\u1ee5ng **YAGNI** \\u2014 ch\\u1ec9 build nh\\u1eefng g\\u00ec th\\u1ef1c s\\u1ef1 c\\u1ea7n transpile. B\\u00e1o l\\u1ea1i quy\\u1ebft \\u0111\\u1ecbnh tr\\u01b0\\u1edbc khi vi\\u1ebft code.\\n\\n---\\n\\n## 1. C\\u1ea5u tr\\u00fac th\\u01b0 m\\u1ee5c\\n```\\nmy-plugin\/\\n\\u251c\\u2500\\u2500 my-plugin.php\\n\\u251c\\u2500\\u2500 includes\/\\n\\u251c\\u2500\\u2500 admin\/\\n\\u2502   \\u251c\\u2500\\u2500 src\/     \\u2190 vi\\u1ebft code \\u1edf \\u0111\\u00e2y\\n\\u2502   \\u2514\\u2500\\u2500 dist\/    \\u2190 PHP enqueue t\\u1eeb \\u0111\\u00e2y\\n\\u251c\\u2500\\u2500 languages\/\\n\\u251c\\u2500\\u2500 releases\/  (.gitignore)\\n\\u251c\\u2500\\u2500 package.json\\n\\u251c\\u2500\\u2500 .gitignore\\n\\u2514\\u2500\\u2500 BUILD.md\\n```\\n\\n## 2. Plugin file header\\n```php\\n\/**\\n * Plugin Name: My Plugin\\n * Requires at least: 6.0\\n * Requires PHP: 8.0\\n * Tested up to: 6.7\\n * Text Domain: my-plugin\\n *\/\\nif (!defined('ABSPATH')) exit;\\n```\\n\\n## 3. npm scripts\\n```json\\n{\\n  \\\"start\\\":   \\\"wp-scripts start\\\",\\n  \\\"build\\\":   \\\"wp-scripts build\\\",\\n  \\\"package\\\": \\\"node scripts\/package.js\\\",\\n  \\\"lint:js\\\": \\\"wp-scripts lint-js admin\/src\\\",\\n  \\\"check\\\":   \\\"npm run lint:js && npm run lint:css\\\",\\n  \\\"release\\\": \\\"npm run check && npm run build && npm run package\\\"\\n}\\n```\\n\\n## 4. PHP enqueue \\u2014 chu\\u1ea9n\\n```php\\nadd_action('admin_enqueue_scripts', function($hook) {\\n  if ($hook !== 'toplevel_page_my-plugin') return; \/\/ conditional\\n  $asset = include plugin_dir_path(__FILE__) . 'admin\/dist\/index.asset.php';\\n  wp_enqueue_script('my-plugin', plugins_url('admin\/dist\/index.js', __FILE__),\\n    $asset['dependencies'], $asset['version'],\\n    ['in_footer' => true, 'strategy' => 'defer']);\\n  wp_localize_script('my-plugin', 'dpsData', [\\n    'nonce' => wp_create_nonce('dps_nonce')\\n  ]);\\n});\\n```\\n\\n## 5. Security\\n```php\\n\/\/ \\u0110\\u1ea7u m\\u1ecdi file PHP\\nif (!defined('ABSPATH')) exit;\\n\\n\/\/ Prefix t\\u1ea5t c\\u1ea3\\nfunction dps_get_settings() {}\\nclass DPS_Plugin_Core {}\\n\\n\/\/ AJAX handler\\nfunction dps_handle_ajax() {\\n  check_ajax_referer('dps_nonce', 'nonce');\\n  if (!current_user_can('manage_options')) wp_die('Unauthorized', 403);\\n  $name = sanitize_text_field($_POST['name']);\\n  echo esc_html($name);\\n  wp_die();\\n}\\n```\\n\\n## 6. ZIP release\\nCo trong ZIP: my-plugin.php, includes\/, admin\/dist\/, languages\/, readme.txt, uninstall.php\\nKHONG co: node_modules\/, admin\/src\/, .git\/, package.json, *.test.js\\n\\n## 7. Acceptance criteria\\n- [ ] npm run build khong loi, output ra admin\/dist\/\\n- [ ] ZIP cai duoc, Activate khong loi, khong can npm tren server\\n- [ ] ZIP khong chua node_modules\/ hay admin\/src\/\\n- [ ] Bao lai: danh sach file + ZIP path + SHA256\\n- [ ] Moi file PHP co: if (!defined('ABSPATH')) exit;\\n- [ ] Moi AJAX\/form: nonce verify + current_user_can()\\n- [ ] Input sanitized, output escaped\\n- [ ] Asset load conditional, script defer\\n- [ ] Prefix dps_ cho moi function\/class\/option\\n- [ ] Plugin header day du fields\\n- [ ] uninstall.php cleanup sach\\n- [ ] BUILD.md day du\\n\";\n\n    try {\n      var ta = document.createElement('textarea');\n      ta.value = md;\n      ta.style.cssText = 'position:fixed;top:-9999px;left:-9999px;opacity:0;';\n      document.body.appendChild(ta);\n      ta.focus(); ta.select();\n      document.execCommand('copy');\n      document.body.removeChild(ta);\n      btn.classList.add('copied');\n      lbl.textContent = 'Copied!';\n      setTimeout(function(){ btn.classList.remove('copied'); lbl.textContent = 'Copy agent prompt'; }, 2200);\n    } catch(e) {\n      lbl.textContent = 'Failed';\n      setTimeout(function(){ lbl.textContent = 'Copy agent prompt'; }, 2000);\n    }\n  });\n})();\n<\/script>","protected":false},"excerpt":{"rendered":"<p>D DPS.MEDIA WP Plugin Dev Guide \u2014 Internal Copy agent prompt H Hien CEO \u00b7 DPS.MEDIA WordPressPlugin DevGuide Flow source \u2192 build \u2192 release for the team. Enough for local dev, ZIP packaging, and installation on WordPress production. PHP 8.x WordPress hooks API @wordpress\/scripts React (Admin UI) Webpack 5 npm scripts Node.js \u2265 18 ZIP release Structure [\u2026]<\/p>","protected":false},"author":1,"featured_media":37957,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,1204],"tags":[],"class_list":["post-37956","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","category-wordpress-marketing"],"acf":[],"rankmath_keywords":{"primary":"","secondary":[""]},"yoast_keywords":{"primary":"","secondary":[]},"yoast_focuskw":"","rankmath_focuskw":"","seo_keywords":{"primary":"","secondary":[""]},"_links":{"self":[{"href":"https:\/\/dps.media\/en\/wp-json\/wp\/v2\/posts\/37956","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dps.media\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dps.media\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dps.media\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dps.media\/en\/wp-json\/wp\/v2\/comments?post=37956"}],"version-history":[{"count":0,"href":"https:\/\/dps.media\/en\/wp-json\/wp\/v2\/posts\/37956\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dps.media\/en\/wp-json\/wp\/v2\/media\/37957"}],"wp:attachment":[{"href":"https:\/\/dps.media\/en\/wp-json\/wp\/v2\/media?parent=37956"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dps.media\/en\/wp-json\/wp\/v2\/categories?post=37956"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dps.media\/en\/wp-json\/wp\/v2\/tags?post=37956"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}