Generate Craft CMS Plugin and Module Code

How to use Craft Generator to scaffold Craft CMS plugins, modules, and other components.


What is Craft Gen­er­a­tor? #

Craft Gen­er­a­tor is a util­i­ty for Craft CMS that scaf­folds Craft CMS plu­g­ins, mod­ules, and oth­er com­po­nents. In addi­tion to cre­at­ing new plu­g­ins or mod­ules, you can also use Craft Gen­er­a­tor to add new func­tion­al­i­ty (via new con­trollers, mod­els, wid­get-types, Twig exten­sions) to an exist­ing plu­g­in or module.

Like to learn while watch­ing? Watch the video ver­sion of the article!

Instal­la­tion #

Craft Gen­er­a­tor is a Com­pos­er pack­age we need to require as part of our Craft CMS project. 

Here are some impor­tant notes on installing Generator:

  1. It requires a work­ing instal­la­tion of Craft CMS 4.3.5+ (the lat­est ver­sion as of this writ­ing)— if you’re run­ning an old­er ver­sion of Craft, even Craft 4, you will need to update the project before installing it. 
  2. If you’re using the craft starter project via composer create-project craftcms/craft, then you do not need to require Craft Gen­er­a­tor in the project. For all projects already cre­at­ed, you will need to install it. 
  3. If you’re using a han­drolled starter project, you’ll like­ly want to go back and require the Gen­er­a­tor pack­age as part of your project.

Here’s how to install Craft Generator:

composer require craftcms/generator --dev

If we’re using the offi­cial DDEV sup­port for Craft CMS, then you’d do:

ddev composer require craftcms/generator --dev

We pass in the --dev option, so Com­pos­er sets the pack­age as the dev depen­den­cy. This means that the Gen­er­a­tor pack­age won’t be installed when you install your depen­den­cies in pro­duc­tion via com­pos­er install —no-dev.

To test that Gen­er­a­tor is work­ing and to see all of the com­mands avail­able with Gen­er­a­tor, run (for DDEV):

php craft make 

Again, if you’re using DDEV for Craft (high­ly rec­om­mend­ed, see our learn­ing mate­ri­als on the top­ic), then you should run the craft com­mand right on the container:

ddev craft make

Run­ning craft make is how we access all of the sub­com­mands in Craft Generator.

Using Craft Gen­er­a­tor to Cre­ate a Craft Plu­g­in #

The most com­mon entry point for using Craft Gen­er­a­tor is scaf­fold­ing a Craft plu­g­in. Here’s how we cre­ate one.

The first com­mand is to start the gen­er­a­tor wiz­ard to help Gen­er­a­tor know the details about your plugin.

php craft make plugin

If you’re new to Craft plu­g­in devel­op­ment, append the --with-docblocks option to get DocBlock com­ments to the gen­er­at­ed code that help explain the dif­fer­ent class­es, meth­ods, etc., in the plugin.

php craft make plugin --with-docblocks

Gen­er­a­tor will step you through an inter­ac­tive set­up process, where you input your desired nam­ing and set­tings for the plugin. 

  • Plu­g­in name — the name of your plu­g­in. You can always change this but think about it first and then enter. Try to use some­thing descrip­tive of what the plu­g­in will do.
  • Devel­op­er name — that is you (or your company)
  • Plu­g­in han­dle — Gen­er­a­tor will sug­gest a han­dle based on your plu­g­in name using kebab case. You can hit enter/​return to accept the default.
  • Plu­g­in loca­tion — This is where your plu­g­in will be stored inside the project (or out­side of the project if you’re sym­link­ing your plu­g­ins for devel­op­ment pur­pos­es). If you’re unsure, using the default plu­g­in­s/­plu­g­in-han­dle is safe. This will cre­ate a plugins direc­to­ry at the root of your project. 
  • Com­pos­er pack­age name — Gen­er­a­tor will rec­om­mend a Com­pos­er pack­age name using the author name and plu­g­in han­dle. You can accept the default unless you have strong opin­ions (like pre-pend­ing craft to the handle).
  • Plu­g­in descrip­tion — Tell the world what your plu­g­in does!
  • How should the plu­g­in be licensed? — Choose any license you want, but the two choic­es offered (MIT and Craft) will like­ly be your best choic­es. Choose Craft license if you plan to sell the plu­g­in on the Plu­g­in store (it’s required or MIT if you make it freely avail­able and open to all.
  • Sup­port email — How users can con­tact you to get help!
  • Github repo URL — This is required if you plan to list the plu­g­in the Craft Plu­g­in Store. If you don’t, or don’t have a Github URL yet, you can leave this blank.
  • Min­i­mum PHP ver­sion — The default is (as of this writ­ing) 8.0.2, and you can­not allow any­thing low­er because 8.0.2 is what Craft 4 requires. Accept the default here and con­tin­ue one!
  • Min­i­mum Craft CMS ver­sion — You also need to accept the default as of this writ­ing because you have to be on 4.3.5 to use this tool.
  • Plu­g­in class name — This will be the name of your main plu­g­in class file and class. It defaults to the gener­ic Plugin name, but you should cus­tomize it to some­thing spe­cif­ic to your plu­g­in using Pas­cal­Case. E.g. MagicButton
  • Root name­space — Name­space can be tricky for new devel­op­ers, but Gen­er­a­tor is try­ing to make this easy. You can accept the default here unless you have strong opin­ions from pre­vi­ous experience.
  • Should the plu­g­in have set­tings? — Will your plu­g­in have a Set­tings page in the con­trol pan­el where users can input or select set­tings? If so, input yes; oth­er­wise, accept the default of no. If unsure, it won’t hurt to indi­cate yes and then leave the set­tings page blank.
  • Include ECS? (For auto­mat­ed code styling) — The default is yes, and you should keep that. It’ll make it eas­i­er to have auto­mat­ic code styling in your plu­g­in project via ECS.
  • Include PHP­Stan? (For auto­mat­ed code qual­i­ty checks) — The default is yes, and you should keep that so you have built-in sup­port for auto­mat­ed code qual­i­ty checks.

Gen­er­a­tor will now cre­ate your plu­g­in scaf­fold using the set­tings you inputted. If Gen­er­a­tor throws an error for some rea­son, you will want to clean up your plugins direc­to­ry before retry­ing. Gen­er­a­tor doesn’t clean up after itself after a failed session.

Your plu­g­in is cre­at­ed and ready to be required and installed. Craft Gen­er­a­tor made this eas­i­er for you by adding the plu­g­in path as a new repos­i­to­ry in the project’s composer.json file.

"repositories": [{  
    "type": "path",  
    "url": "plugins/magic-button"  

To install the plu­g­in, we need to require it using the dev-main ver­sion, and then install it.

ddev composer require ryan-irelan/magic-button:dev-main
ddev craft plugin/install magic-button

And now you’re ready to work on your plu­g­in! The files are sym­linked from the plugins/magic-button, so any changes you make to the files in that loca­tion will be run as if they are in the vendor directory.

Using Craft Gen­er­a­tor to Cre­ate a Craft CMS mod­ule #

If you need to cre­ate cus­tom func­tion­al­i­ty for your Craft CMS project and don’t need the extra func­tion­al­i­ty offered via Craft plu­g­ins, then a mod­ule is the way to go. 

The first com­mand is to start the gen­er­a­tor wiz­ard to help Gen­er­a­tor know the details about your module.

ddev craft make module

Gen­er­a­tor will step you through an inter­ac­tive set­up process, where you input your desired nam­ing and set­tings for the plugin. 

  • Mod­ule ID — In kebab case, enter a mod­ule id. For exam­ple, a plu­g­in that han­dles basic project log­ic and cus­tomiza­tions could be called site-logic.
  • Mod­ule loca­tion — Input the loca­tion where you want the mod­ule saved inside your Craft project. Mod­ules are stored in the project, not required via Com­pos­er like a plu­g­in. The stan­dard loca­tion is modules/ in the project root. You might get an error if you already have a mod­ule (like the default Module.php file) in the mod­ules direc­to­ry. Remove the default Module.php file (if you’re not using it!), and then continue.
  • Should the mod­ule be loaded dur­ing app ini­tial­iza­tion? — This is almost always yes. 

Now Gen­er­a­tor will cre­ate the mod­ule file and update the config/app.php file to load the mod­ule class and boot­strap it.

Impor­tant note: The Craft starter project no longer includes the default modules/Module.php mod­ule since Gen­er­a­tor will bet­ter set up a new mod­ule for you.

Adding New Sys­tem Com­po­nents #

After you’ve already cre­at­ed a new plu­g­in or mod­ule, you might need an addi­tion­al com­po­nent, like a wid­get type in your module. 

Use one of Generator’s com­mands, and pass in the --module or --plugin option, pass­ing in the mod­ule ID or plu­g­in handle. 

ddev craft make widget-type --module=site-logic
  • Wid­get type name (Pas­cal­Case) — Give the wid­get a name that describes what it will do, like LatestInfo.
  • Wid­get type name­space — The default modules/widgets is good enough for me.

In modules/widgets, there is now a LatestInfo.php class file with some boil­er­plate code to get a mod­ule up and run­ning. Gen­er­a­tor also added the event to reg­is­ter the new wid­get type to the modules/Module.php file.

If you log into the project’s con­trol pan­el, you should be able to add the wid­get to the con­trol pan­el dashboard.

How can I learn more about extend­ing Craft CMS? #

Now that you have your scaf­fold­ed plu­g­in or mod­ule, you are ready to start the work of writ­ing the code that will make do what you wish! This is the fun part where you start to see your idea come to life. 

Your imple­men­ta­tion details will be spe­cif­ic to your needs, so we can’t write a tuto­r­i­al cov­er­ing every sin­gle sce­nario out there. How­ev­er, here are some help­ful learn­ing mate­ri­als here on CraftQuest for learn­ing how to extend Craft CMS.

  • Extend­ing Craft Quest — A col­lec­tion of cours­es and lessons on extend­ing Craft CMS.
  • Get­ting Start­ed with Craft Plu­g­in Devel­op­ment — In this mini-course plu­g­in devel­op­er Ben Cro­ker walks through some Craft plu­g­in devel­op­ment fun­da­men­tals. Learn the steps involved in set­ting up a basic plu­g­in, how to add a Set­tings page, and more.
  • Craft Plu­g­in Devel­op­ment In-Depth — Join plu­g­in devel­op­er Ben Cro­ker on a jour­ney of explor­ing Craft plu­g­ins in-depth. Go beyond and the basics and learn how and why plu­g­ins work the way they do. Along the way improve your own plu­g­in devel­op­ment chops and learn how to write bet­ter plugins.
  • Extend­ing Twig in Craft CMS — We learn how to build a Twig fil­ter that manip­u­lates text pass into it.
  • Build­ing a Craft CMS Dash­board Wid­get — We build a dep­re­ca­tion noti­fi­er wid­get named Deprec­No­ti­fi­er. The wid­get will give quick insight into the num­ber of dep­re­ca­tion errors logged for your site. It will pro­vide you with a glance at how many depre­ci­a­tion notices there are for your site.
  • Cre­at­ing a Craft CMS Field Type — In this course we learn how to cre­ate a cus­tom field type for Craft CMS. It’s per­fect if you find your­self in need of a cus­tom field type for Craft and want to know how to build it.

Plu­g­in Devel­op­ment DX and Set­up #

Once you get rolling with plu­g­in and mod­ule devl­op­ment, you might want to improve your local devel­op­ment envi­ron­ment. Here are some resources that will aid you in just that!

  • A Craft CMS Plug­in­Lo­cal Devel­op­ment Envri­on­ment by Andrew Welch — This arti­cle details a con­tainer­ized local devel­op­ment envi­ron­ment that you can use to devel­op, debug, and test Craft CMS plu­g­ins with ease”
  • A Vite Build­chain for Craft CMS Plu­g­ins by Andrew Welch — A drop-in build­chain you can use in your Craft CMS plu­g­ins and mod­ules, giv­ing you Hot Mod­ule Replace­ment for JavaScript, Tail­wind CSS, and opti­mized pro­duc­tion builds.”

Do you have a resource that you think should be on this page? Email and let us know.