Element names
This is a quick visual overview of the various FileMaker elements such as tables, fields, layouts, scripts, functions and other objects. Each element of FileMaker has its own subsection below.
Tablename dataFieldName summaryCountField GLOBALFIELD CLIPBOARD (is a reserved temporary global field) unstored_Calculation id (is the primary key in all tables) id_Tablename (is a foreign key) idList_Tablename (is a pseudo-schema field for multi-key values related to solution schema)* keys_Tablename (is a utility field for multi-key values used for UI specific functionality) $variableName $$GLOBAL.VARIABLE FunctionalArea » Tablename @Tablename (is the name for developer table occurrences) Tablename: Layout Name (form|list) portal.layoutObjectName Script Name Script Name ( with ; parameters ) CustomFunction ~PrivateCustomFunction ~locallyScopedLetVariable $~privateVariableName $$~PRIVATE.GLOBAL.VARIABLE
* Pseudo-Schema
FileMaker Pro provides a unique feature called a multi-key - not to be confused with a compound, or more commonly, a concatenated key. Wherein a normalized data structure will typically use a singular key value for each and every record, FileMaker provides the ability to store multiple keys, hence a multi-key, list of values within a text field. Because of this feature, it is possible to create what filemakerstandards.org calls pseudo-schema. In the rest of the database world, this approach may not be considered valid, where isolated within the FileMaker world results in a feature which is heavily used by developers. While not suggested for normal use as part of your schema within a FileMaker solution, multi-key values for the purpose of maintaining relational structure amongst data would use the prefix of idList_ as opposed to the more utilitarian, or more specifically for the UI, keys_ prefix. See more info within Field naming.
Developer note
The primary goal of these naming conventions is to create highly readable code. Concerns related to brevity are superseded by clarity and maintainability. These naming standards are also specific to FileMaker Client development. They do not address Web, Mobile or SQL based deployment. For more information related to these aspects of FileMaker then read about Solution development models
32 Comments
Anonymous
(I'd like not to be anonymous, but the sign up doesn't appear to work...)
I think there may be a small issue relating to scripts. I use the Alexander Zueiv's #params_to_local_vars ( ) function for stripping out parameters from the script name e.g.
which I strongly believe makes the scripts more portable, and clearer to understand.
So firstly, I think your coding convention should allow for [] or ().
Given that you don't need to pass globals into a script I don't think that the length of the dotted globals will affect things, but it should be noted that there is a limit to the length of a script name...
dd at dyce dot com
Matt Petrowsky
Hey dd, I too used Alexander's params to local vars function. You can see it here.
However, when you look at many other programming languages, the use of brackets is never used for function declarations. I don't know exactly why he chose them, but I opted to switch to parens because it's more common and something you're used to when reading code quickly. Having to 'interpret' the [ ] even though you know it's used for parameters slows you down. Plus, FileMaker already has the use of [ ] for repetitions ( e.g FunctionalArea » Tablename::repeatingFieldName[2] )
With regards to specifying optional parameters, this is something we can debate if it should be used. Recently, I started using a simplified variation of script parameters. I only specify the absolute required inbound parameters for the script to function. However, I do allow additional parameters to be passed in. For these parameters, I am documenting their availability within the script header such as this.
Script name Handle Error ( errorNum, scriptName )
Note the additional optional parameters of $type and $data
Using a reserved local variable of $checkScriptName, the name of the script can optionally be used instead of absolutely used to enforce the existence of the required parameters. Taking this route didn't seem to limit the number of inbound parameters a script could accept.
One thing I kept in mind while documenting, was the fact that most all other programming languages take their parameters in an ordinal fashion. This too is a convention that is good to follow even though we can use name/value pairs. As well, other languages will take inbound parameters which are an array.
My switch from using dedicated custom functions for assigning parameters to using FileMaker's Quote function was prompted by trying to make code even more readable. Wherein, seeing this in a script call is easier to read - at least to me.
Seeing the dollar sign just sets the code apart and is very apparent as opposed to this. Where you have to determine if the key for the variable is a literal or not. I'm going for the quickest possible recognition of what things are.
Anonymous
Hmmm. Not sure I agree, in terms of the cut and paste simplicity of buttons using named scripts with passed parameters. I have a lot of generic predefined functions that I cut and paste between projects (for say adding portal rows, moving items up and down within portals, etc.) I achieve the simplicity because I can choose to pass in calculated parameters from the button. In which case, you're only looking at the parameters anyway ;-)
In fact I think this is a case where FileMaker wins out over 'languages' that use ordinally-identified parameters...
You may not see lots of Quote() calls as obtrusive, but (comparing apples with apples);
seems easier to read, than
espcially since the name of the script actually does include the expected parameters!
Or not. :-)
dd at dyce dot com
Matt Petrowsky
True, according to how the text is shown here on the wiki, it looks cleaner. However, when scanning script calls within other scripts, you're typically scrolling to the right depending on the width of the edit script dialog box (because the script is shown as one line when editing). For buttons you do have to go into the calc dialog box but seems pretty minor to me.
It's when you're scanning that one line while editing a script that your scan for the '$' becomes more useful.
I do agree that the use of the Quote() function is redundant. But it is clear what you are passing because you always know the Quote function is starting it. Thinking about this, it would be cool to have it read even cleaner. It would require an another custom function, but I'm cool with custom functions! I'm going to apply this one to my subconscious and see if there is an even cleaner way. Maybe we'll get some other suggestions too.
Jeremy Bante
Scanning for "$" vs. scanning for "#" in a one-line calculation doesn't make much difference to me. In one-liners, concise is usually easier to read (not a principle I generally agree with outside of one-line calcs), and the # function syntax is definitely more concise. What's especially important for readable one-liners is cutting down on the number of parentheses and anything else that nests, which Quote() doesn't help.
Matt Petrowsky
No argument about the Quote function being a bit too much - it just handled any necessary escaping without the hassle. We could make this method more concise with a wrapper function, but then you still do have the extra parens.
I'm ok with using a parameter setter custom function, it's just that I've found that seeing the $whatever is so much more natural than interpreting the
# ( "literal" ; "value" )
- even though it's not that hard to interpret.I'm also personally a BIG fan of List() because it's so much like an array.
Hybrid?
# ( "$key" ; "value" )
Simplified?
We'd have to write a parser (which someone is probably already using this format), but it certainly is simple and familiar.
Anonymous
Matt, you're waffling a little on the use of "." for the custom functions. I actually prefer the object oriented convention of object.id or params.get, params.set, params.assign. It was your suggestion after all!
Cheers!
rob p
Anonymous
I'm on the fence about dot notation for custom functions. FileMaker is NOT object oriented, and I don't want to confuse developers used to using object-oriented tools. However, it is helpful to group related custom functions by prefix. So I normally use and underscore delimiter instead of a dot: UUID_New, UUID_GetTimestamp( uuid ), and UUID_GetNICAddress( uuid ).
Matt Petrowsky
The reason I've flipped my waffle over is due to a few issues.
see note below
One variation I could see is keeping, or suggesting as an alternative, a change in case. Such that, object.id() becomes Object.Id(). The issue of going with title case does somewhat remove the confusion within code between tab.name and Tab.current, where the later is now identified as a custom function because of case. However, going this route would then mean that it would be advised to not use the reserved object names for any custom function prefix.
I think I would rather give in to using the FileMaker familiar format of TabCurrent() and get more "buy in" by those adopting the standards.
* Yes, I could have renamed my custom function var.eval() to something else, but it showed me that using a dot within object names, custom functions, let variables and global variables was a bit too broad and didn't fit the current FileMaker function method. When I came to realize that distinguishing my custom functions from internal functions wasn't that big of a deal I decided this was the better way to go. Plus, it's quite easy to rename your custom functions
Anonymous
I think the Script Name convention could stand to be revised in light of the fmp7script URL protocol with FileMaker Go. A script name doesn't just have to be readable in FileMaker, but in URLs. That means no spaces; "Script%20Name" is harder to recognize as "Script Name" in Manage Scripts than just "ScriptName" and "ScriptName". It also might mean not including parameters in a script name for scripts meant to be called via the fmp7script protocol — you can see exactly what variables are getting passed later in the URL.
Anonymous
Which means you just need a wrapper function for calling via URL and a internal function for other users, surely?
Matt Petrowsky
I've adjusted the note at the top of these naming conventions to address this issue. I also have this noted somewhere else that mentions these are naming conventions for FileMaker Client development.
as seen in the note at the top of this page
The suggested development approach, at least the one I'll cover in these docs is to use a dedicated file for each of the possible platforms for deployment. This means for a mobile aspect of your solution, you would create a Mobile.fp7 file and would use External data source to reference the main or data file. Then as the comment above suggests, you could create a wrapper script which would call the primary script and would adhere to the conventions required by Web or Mobile.
Good suggestion! I'll make a note in the Script naming section.
Anonymous
Actually, the more I think about it, the more I wonder that there isn't a way to produce a single wrapper function, provided that the url-side is just a parameter-less Camel cased version of the Client-side version... I will look into it.
dd @ dyce dot com
Anonymous
I disagree on the convention for TO names. I rely on the Graph less and less lately. These days, 95.6% of my use of the Graph is to support fields that I want to show on a layout or in a Portal, so the main function of naming TOs is to facilitate this. Given that, If my base table is C__Company, and I have a distant table that's C_Person_Address (or maybe c_person_ADDRESS as I've seen some people do), the related fields are grouped nicely, and that's lost by your proposed method. While I see the problem that you're solving by reversing the structure, I think that's a much smaller problem. -MattN
Matt Petrowsky
Hey Matt, I believe you are doing the same in essence, it looks like your prefix of C__ is designed to force the sort order when choosing a TO while developing.
The proposed standard above does the same thing. The FunctionalName is supposed to be well-structured and used to collect all TOs within that functional aspect of the solution. Yes, it requires more work (because you have to think about it before you name it), but it essentially forces a degree of automatic documentation. Plus, for many tables "away" you can follow the naming prefix. In my example I showed in the video on the magazine site I used the following.
Where the prefix of SideBar (of which I only had one in my solution) identifies the function use of those TOs. I can see that the first is tied to the Library table and the other two are tied to the Sources table. Extending the FunctionalName by using Type and Missing give me a clue about what they do or can be used for (e.g. Type of Sources and Missing Sources).
While you do lack any identification of the absolute field used for the relationship, I've noticed that once I've stopped working on a particular aspect of a solution I end up having to make that obligitory trip back into the graph months later just to see what the keys and chain of relationships are anyway. For this reason I opted for clarity. The other two goals were to not introduce spaces or the underscore and use the » character to identify the table portion of a field reference.
One suggestion first, if this is not something you have tried and you're commenting based on first impressions, can you hack up a small little solution and try out the suggestion? Maybe make a fake Teacher/Student/Classes database using this approach?
Matt Navarre
Each of these elements (Tables, Fields, etc) should be broken out to an individual discussion.
Matt Petrowsky
This is certainly possible. Let's wait and get a few more people actively involved to see if this is warranted.
For right now, it's easiest to read on one page.
As a participant, make sure and read up on the wiki notation guide
Matt Petrowsky
Also note that you have access to your own Blog on this wiki where you can make notations about things. The blog is public because personal profiles are public too, so keep that in mind.
Anonymous
I second the motion.
Please break these elements down into different sections. This will make it easier to browse comments to the related elements.
Arnold Kegebein
arnold (at) kegebein (dot) net
Matt Petrowsky
Each major section has now been made into a subsection under this section. Comments should be made on each section. I don't know that I can move comments - I'll have to look into it.
Anonymous
Tables
Invoice
good
Invoices
bad
Arnold Kegebein
arnold (at) kegebein (dot) net
Jeremy Bante
When referring to a Table::field in a calculation, we aren't always referring to data in one record. For "Sum ( Related » Invoices::amount )", the plural form is more semantically consistent. Plural form may also be one more signal distinguishing between tables and other objects. That said, the singular reference to one field in one record is definitely the more common in my experience. A stronger argument for singular table names might be that the names for foreign key fields can be more semantically accurate. "id_invoices" doesn't make much sense if it only refers to one invoice. (It may make sense for a multi-line foreign key; but that's much less common, and therefore less of a priority.)
Anonymous
Fields
Global Fields
I kind of like the idea to use UPPERCASE for all global fields. I did that with global fields acting as quasi constant values (for relations). I do not know, why I never did that for all global fields.
Key Fields
For my primary keys I use the field name __id. Foreign keys use two underscores and the table name, similar to your idea. My way might contradict readability, but there are some arguments for it:
package::__id < > package::id
The first field is the internal record id (unique, required), the second field an identification for the package. Perhaps not every package will have a receive an id, or an id might be reused over time.
Arnold Kegebein
arnold (at) kegebein (dot) net
Jeremy Bante
I've used the underscore prefix for key fields too, with two underscores for the primary key and one underscore for foreign keys so the primary key always sorts above the foreign keys. The only problem I've encountered with that is that some other technologies that we might like to pull data from FileMaker don't like underscores at the beginning of field names. In SQL, you'd have to put __id in quotes to use it. I think it's a small and worthwhile price to pay, but I'm only one guy. SQL developers may have a different opinion.
Jeremy Bante
Using a universally unique identifier is a worthwhile standard to have, but this page is labeled "Naming Conventions." Shouldn't we have another place for that?
Also, when talking about UUIDs, I think it's worth clarifying between RFC 4122 UUIDs and just any scheme for creating IDs that are universally unique. (I'd rather not standardize on RFC 4122 for Filemaker. As an essentially binary format, it's a square peg in FileMaker's round hole.)
Anonymous
I agree, UUID is field content and should be placed in a different section of this wiki.
But regarding the type of UUID, I do not think, this should be mandatory part of a coding standard. Recommendation perhaps, or included as additional information for interested developers, but do not make it a required standard.
Arnold Kegebein
arnold (at) kegebein (dot) net
Jeremy Bante
I don't suggest that any particular UUID scheme be "the standard." There are several alternatives, each with their own pros and cons. But I'm trying to think of a compelling reason not to at least use one of them, and I'm coming up short. My favorites all require custom functions, which means I can't add them to a solution without FileMaker Pro Advanced; but I have FileMaker Pro Advanced, and so should other serious developers.
Matt Petrowsky
Note, I've moved UUIDs to the Key values subsection under the Naming Conventions > Field naming section.
Jeremy Bante
With foreign keys, I imagine two competing arguments for case. One the one hand, using a lowercase version of the foreign table name (id_table) might be consistent with other lowerCamelCase field names. On the other hand, using the unedited titlecase table name (id_Table) more obviously identifies that there's a table involved. And isn't the lowercase "id_" prefix enough to be consistent with other field names? There's also one less step when calculating the field name:
vs
Matt Petrowsky
Good point. I agree, let's revise it.
Perren Smith
Do we need to address file naming? It seems as if it's the most basic element to any solution.
I personally don't have any preferences or recommendations off the top, but file names are exposed via both EDS references and Open Remote... dialogs. The former being more important to the developer and the latter potentially for any user of a solution.
The only pet peeve I have is to have spaces in files names. When working via the command line it's just annoying to have to work around spaces via either escaping or quoting.
Anonymous
File naming? Yes, I agree. There should definitely be standard for that.
My own ref. is here:
http://www.fimano.dk/filemaker/udviklerkonventioner.html#01
In case any of you have trouble reading Danish, I will translate below :-)
- Not mentioned in original FDC, but still relevant.
- Versioning is sometimes needed. This should be on [enclosing] folder level, not to the solution file(s).
- Never change a file's name, see below.
- 1 and only 1 period in the name: FileName.fp7
- No spaces, no special chars.
- Prefix with shortname of customer / solution, like FMstd_CMS.fp7, FMstd_CMS_data.fp7
- A bug in FMP (that may or may not be fixed by now) would keep names that the file has had previously in its lifetime.