{"id":15490754,"url":"https://github.com/sammarks/ablecore","last_synced_at":"2025-08-28T05:32:44.956Z","repository":{"id":15875291,"uuid":"18616165","full_name":"sammarks/ablecore","owner":"sammarks","description":"A library for Drupal developers.","archived":false,"fork":false,"pushed_at":"2016-07-08T16:44:37.000Z","size":308,"stargazers_count":5,"open_issues_count":20,"forks_count":4,"subscribers_count":3,"default_branch":"7.x-1.x","last_synced_at":"2025-06-10T06:49:59.541Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sammarks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-04-09T22:48:39.000Z","updated_at":"2016-07-08T16:44:38.000Z","dependencies_parsed_at":"2022-08-27T03:51:40.665Z","dependency_job_id":null,"html_url":"https://github.com/sammarks/ablecore","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sammarks/ablecore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sammarks%2Fablecore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sammarks%2Fablecore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sammarks%2Fablecore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sammarks%2Fablecore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sammarks","download_url":"https://codeload.github.com/sammarks/ablecore/tar.gz/refs/heads/7.x-1.x","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sammarks%2Fablecore/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272446405,"owners_count":24936517,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-28T02:00:10.768Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-02T07:23:38.024Z","updated_at":"2025-08-28T05:32:44.939Z","avatar_url":"https://github.com/sammarks.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Able Core\n\nAble Core is a set of modifications for Drupal to enhance the development process. Able Core\nimplements a \"no-boilerplate\" philosophy. That is, all the defaults are abstracted away and only\nmodifications of the defaults are required to be represented in the code. Able Core provides\nseveral OO-based implementations of standard Drupal configuration arrays (for example, things like\n`hook_menu` and `hook_theme`) so that developers don't have to constantly refer to the Drupal API\ndocumentation when creating a website.\n\nAble Core introduces syntactic sugar wherever it can and has the following ultimate goals:\n\n- Make Drupal easier to integrate with IDEs and code introspection (IDEs should be able to inform\n\tthe developer of the correct keys to use when configuring things like `hook_menu` so that\n\tdevelopers don't constantly have to refer to the API documentation)\n- Do more with less characters. Arrays in PHP (depending on how they're formatted) take up a lot of\n\tspace. It's a lot easier to interpret a `hook_menu` definition if every menu item is on one\n\tline (with the line not introducing horizontal scrolling, because that's just as difficult to\n\tread) than if every definition (out of a possible 50 or so) had 5 lines.\n- Introduce sensible defaults, on top of the defaults already in place.\n- Make it possible to abstract as much of the configuration to code as possible. Features is great,\n\tbut it adds a _lot_ of boilerplate code that isn't really necessary. Content types should be\n\table to be defined in 30 lines, not 400.\n- Add some convenience utilities so that modules can be OO-based more easily. Classes like `Batch`\n\tand `FormBase` are introduced so that instead of having a collection of functions representing\n\ta form or a batch operation, those functions can all be contained in one class.\n\nBasically, you shouldn't have to write thousands of lines of code to get a decent site setup with\nDrupal.\n\nAble Core is sponsored by [Able Engine,](http://ableengine.com/) a web services company located in\nLexington, Kentucky.\n\n## Getting Started\n\nTo take advantage of all the benefits of Able Core, you'll have to declare your module as an Able Core module.\nTo do this, simply add the following to your module's `.module` file:\n\n\t// Declare this module as an Able Core module.\n\tfunction MODULE_ablecore() { }\n\nSimply having the hook present will help Able Core to determine which modules it should expose its advanced\nfeatures to (like auto-inclusion of files inside `helpers/` and `hooks`).\n\n## File Structure\n\nAble Core employs specific naming conventions. Therefore, in order to use Able Core to its fullest,\nyou'll probably want to follow these conventions:\n\nAll PHP logic goes in the module and all HTML, CSS and Javascript goes in the theme. The CSS,\nJavascript and HTML all live in their own parts of the theme.\n\n### Modules\n\n\tmodule_name/\n\t\tpreprocessors/\n\t\t\ttheme-hook-name.php\n\t\t\tother-theme-hook.php\n\t\tcallbacks/\n\t\t\tpage-callback-a.php\n\t\t\tpage-callback-b.php\n\t\thelpers/\n\t\t\tmisc-file-1.inc\n\t\t\tmisc-file-2.inc\n\t\thooks/\n\t\t\tblock.inc\n\t\t\ttoken.inc\n\t\tmodule_name.info\n\t\tmodule_name.module\n\n#### Footnotes\n\n- `module_name` - This should always be in the following format: `sitename_subname`. It should\n\t**never** be the same name as the profile (or theme) because this causes large problems with\n\tDrupal (various hooks conflict with each other) and is against the convention recommended by\n\tDrupal documentation.\n\t- The primary module for the project should be called `sitename_core`.\n\t- All modules for a project should start with the profile (or site) name and be in the same\n\t\tpackage in the module configuration (the `.info` file).\n\t- Only use underscores and lowercase letters for modules. This is a Drupal convention.\n- `preprocessors` - This folder is where all theme preprocessors go. This is the convention used by\n\tAble Core. Each preprocessor file should have the same name as the theme and have one function\n\t`preprocessor_THEMEHOOK(\u0026$variables)`.\n- `callbacks` - This folder is for all callbacks registered with Drupal through `hook_menu`. These\n\tfiles should have a name that identifies them with their respective page.\n- `helpers` - Files that contain helper functions go in this folder. Any file ending in `.inc` will\n\tautomatically be included by Able Core. *Not Implemented Yet.*\n- `hooks` - Files in this folder are similar to the `helpers` folder. These files must end in\n\t`.inc` and by convention must have the same name as the module they contain hooks for. In the\n\tfuture, Able Core will have \"smart\" functionality so that when a specific module is looking for\n\thooks, it loads the respective file.\n- `module_name.module` - This file contains generic Drupal hooks. Really, it should only contain\n\tDrupal core hooks.\n\t- Block hooks go in `hooks/block.inc`\n\n### Themes\n\nWhile the standards set below are *highly* recommended, they are completely optional.\n\n\ttheme_name/\n\t\tthemes/ (not templates)\n\t\t\tnode/ (the module name)\n\t\t\t\tnode.tpl.php\n\t\t\t\tnode--type.tpl.php\n\t\t\t\tnode--type--display.tpl.php (node--type--teaser.tpl.php)\n\t\t\tcore/\n\t\t\t\thtml.tpl.php\n\t\t\t\tpage.tpl.php\n\t\t\tmodule_name/\n\t\t\t\ttheme-name.tpl.php\n\t\t\t\tother-theme-name.tpl.php\n\t\tstyles/\n\t\t\tdefault.[scss|less|sass]\n\t\t\tcore/\n\t\t\t\tlayout.[scss|less|sass] (layout under SMACSS)\n\t\t\t\tbase.[scss|less|sass] (base under SMACSS)\n\t\t\tthemes/ (modules under SMACSS)\n\t\t\t\ttheme-name.[scss|less|sass]\n\t\t\t\tother-theme-name.[scss|less|sass]\n\t\t\t\tsubfolder/ (... these can be organized into subfolders.)\n\t\t\tvendor/\n\t\t\t\tthird-party.[scss|css|less|sass]\n\t\t\t\tother-third-party.[scss|css|less|sass]\n\t\tscripts/\n\t\t\tdefault.js\n\t\t\tthemes/\n\t\t\t\ttheme-name.js\n\t\t\t\tother-theme-name.js\n\t\t\tvendor/\n\t\t\t\tequalize.js\n\t\ttheme_name.info\n\n#### Footnotes\n\n- `theme_name` - This is never to be the same name as the module or profile. This name always\n\tstarts with the profile (or site name).\n- `themes` - Traditionally, this folder is named `templates`. However, that name does \n\tnot agree with the Drupal component it deals with (themes). Therefore, the folder has been \n\trenamed so that it better defines which Drupal component it's talking about.\n\t- This folder is split up into subfolders for each module it has a theme override for.\n\t\tFor example, node templates would go inside the `node` folder because they deal\n\t\twith the node module. Core templates (really only `html.tpl.php` and `page.tpl.php`)\n\t\tgo inside the `core` folder.\n- `styles` - Any styles for a website go in this folder. The structure of the CSS loosely\n\treflects a combination of SMACSS and the structure under the `themes` folder. Any files\n\tin the root of this directory are to be included in the theme's `.info` file to be parsed\n\tby the LESS (or SASS) compiler.\n\t- `default.less` - This is the only file inside the `styles` root, and therefore the\n\t\tonly file included by Drupal. This file is meant to contain only include statements\n\t\tpointing to other LESS files.\n\t- `core` - These styles represent the base styles for the theme. Really, the only two\n\t\tfiles that belong in this folder are `layout.less` and `base.less`\n\t\t- `layout.less` - This file creates the layout for the website. This is typically\n\t\t\twhere a grid system is included and put to use.\n\t\t- `base.less` - This file contains all the base styles. Typically, this file only\n\t\t\tcontains styles for tags. Classes and IDs are not intended to be included in\n\t\t\tthis file.\n\t- `themes` - This folder is to be organized in the same way the `themes` folder underneath\n\t\tthe theme root is organized. Each `.less` file in this folder corresponds with a file\n\t\tin the `themes` directory underneath the theme root.\n\t- `vendor` - Any third party CSS or LESS goes in this folder.\n- `scripts` - Any scripts for the website go in this folder. The naming and structuring schemes\n\there are exactly the same as in the `styles` folder.\n\t- `default.js` - This file is meant to contain any global JS. There shouldn't be a lot of\n\t\tJavascript in this file as most of our Javascript code is tied with a specific theme\n\t\thook.\n- `template.php` - **This file is not meant to be used.** This file should not be used to prepare\n\tcontents for a specific page. If something changes across several pages of a website,\n\tput it in a block and not in `template.php`. Using `template.php` breaks the convention\n\tof \"all logic goes in the module and all UI goes in the theme.\"\n\n## Usage in Modules\n\nOne of the major ideas introduced by Able Core is to create modules that drive the custom aspects\nof any Drupal site. This idea was initally discovered in the [White House Petitions Repository.](https://github.com/whitehouse/petitions)\n\nLooking through the source code for the repositories, I noticed something really nasty about\nDrupal's configuration syntax for things like `hook_menu` and `hook_theme`. It consisted of\nnasty PHP arrays. The code was not readable (especially if many declarations were made in the\nsame file), and the module file went on for miles.\n\nBecause of that, several helpers classes were introduced to collapse the basic configuration for\nthese files into one-liners. Creating a custom menu entry for `hook_menu` is as simple as\nthe following:\n\n\t\u003c?php\n\t\n\t\tfunction mymodule_menu()\n\t\t{\n\t\t\treturn AbleCore\\Modules\\PathManager::init()\n\t\t\t\t-\u003edefine('this/is/a/custom/path', 'controllerFile@index', 'Page Title')\n\t\t\t\t-\u003efin();\n\t\t}\n\t\t\n\t?\u003e\n\nThat way, multiple configuration options can be passed into a single block of code. This idea\nis very similar to the way routing works in the top MVC frameworks (yes, Drupal is not an MVC).\nThe same style of code is used for some of the other manager classes in Able Core.\n\nLet's say you want the URL `test/url` to go to the `action_test_url` function in the `callbacks/test_callback.php` file. Here's what your code would look like:\n\n\t\u003c?php\n\t\n\t\tfunction mymodule_menu()\n\t\t{\n\t\t\treturn AbleCore\\Modules\\PathManager::init()\n\t\t\t\t-\u003edefine('test/url', 'test_callback@test_url', 'Test URL Page')\n\t\t\t\t-\u003efin();\n\t\t}\n\t\t\n\t?\u003e\n\nHere's the breakdown of arguments:\n\n- **path** - The path the action should respond to. This path can have multiple arguments, as\n\tdemonstrated below.\n- **callback** - The file and function to call when the path is reached.\n- **title** - The title of the page.\n- ... and more ... - Consult the documentation in the code for the complete list of arguments.\n\n### Using Arguments\n\nDrupal's menu function allows for arguments. Drupal uses percent (%) signs to designate wildcards.\nHere are some examples of wildcarded paths:\n\n- `path/%/with/%/arguments` will match the following:\n\t- `path/1/with/2/arguments`\n\t- `path/test/with/moretest/arguments`\n- `path%` will match the following:\n\t- `pathtest`\n\t- `pathsecondtest/thirdtest`\n- `%` *should* match any path. It's not recommended to do this, for obvious reasons.\n\nArguments are automatically stored in variables and passed as arguments to the callback function.\nFor example, `path/%/with/%/arguments` will yield the following callback function:\n\n\t\u003c?php\n\t\n\t\tfunction action_page($argument_a, $argument_b)\n\t\t{\n\t\t\t// $argument_a is the first %\n\t\t\t// $argument_b is the second %\n\t\t}\n\t\t\n\t?\u003e\n\nTherefore, going to `path/1/with/2/arguments` will call the callback like so:\n\n\t\u003c?php\n\t\n\t\taction_page(1, 2);\n\t\t\n\t?\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsammarks%2Fablecore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsammarks%2Fablecore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsammarks%2Fablecore/lists"}